简体   繁体   中英

Subsetting within user-defined function using dplyr

I have financial data with multiple tickers and monthly returns data. I would like to create a function to calculate the Sharpe Ratio just by providing the ticker as a string.

library(dplyr)
library(reshape2)
library(lubridate)

# Define function to calculate sharpe ratio
sharpe_ratio <- function(ticker)
{
  # Create data frame containing annualized returns for each year for ticker 
  # of interest
  df1 %>% subset(ticker == ticker) %>%
     group_by(year(date)) %>% 
      summarize(annual.return = prod(1 + mret.excess) - 1) %>% 
      as.data.frame -> annualized_returns

  # Calculate Sharpe Ratio with annualized metrics
  mu <- mean(annualized_returns$annual.return)
  sigma <- sd(annualized_returns$annual.return)
  return (mu/sigma)
}

However, when I try:

sharpe_ratio("YACKX")

it does not subset the data frame (df1) at all, and I am left with the mean annualized return for all returns irrespective of ticker input. However, if in the function I replace

... %>% subset(ticker == ticker) %>% ...

with

... %>% subset(ticker == "YACKX") %>% ...

the function now properly subsets my dataframe. I am curious as to why when I try subsetting the dataframe with a formal argument it does not work, but when I "fix" what ticker to subset by typing the ticker name in quotes it behaves properly.

Here is an example dataset:

date <- as.Date(c("2000-01-31", "2000-02-29", "2000-03-31", "2000-04-30", "2000-05-31", 
                     "2000-06-30", "2000-07-31", "2000-08-31", "2000-09-30", "2000-10-31", 
                     "2000-11-30", "2000-12-31", "2001-01-31", "2001-02-28", "2001-03-31", 
                     "2001-04-30", "2001-05-31", "2001-06-30", "2001-07-31", "2001-08-31", 
                     "2001-09-30", "2001-10-31", "2001-11-30","2001-12-31", "2000-01-31", 
                     "2000-02-29", "2000-03-31", "2000-04-30", "2000-05-31", "2000-06-30", 
                     "2000-07-31", "2000-08-31", "2000-09-30", "2000-10-31", "2000-11-30", 
                     "2000-12-31", "2001-01-31", "2001-02-28", "2001-03-31", "2001-04-30",
                     "2001-05-31", "2001-06-30", "2001-07-31", "2001-08-31", "2001-09-30", 
                     "2001-10-31", "2001-11-30","2001-12-31"))
tickers <- c(rep("YACKX",24), rep("APIMX",24))
mret.excess <- c(-0.0743128, -0.0798149,  0.0571812, -0.0408150,  0.0277273,  0.0535117, 
                 -0.0181185,  0.0591170, -0.0019288, 0.0786993,  0.0017027,  0.0220814,  
                 0.0170490,  0.0061800, -0.0368087,  0.0216363,  0.0356446, -0.0066351,
                 0.0335736,  0.0006140, -0.0795808,  0.0238521, 0.1076750,  0.0290756, 
                 -0.0566304,  0.0328873,  0.0552739, -0.0458054, -0.0402790,  0.0265851, 
                 -0.0344774,  0.0860904, -0.0575071, -0.0814842, -0.0872155, 0.0028902,
                 0.0470691, -0.1203689, -0.0896772,  0.0995483, -0.0048447, -0.0242168, 
                 -0.0257273, -0.0711448, -0.1155542, 0.0540500,  0.0880436,  0.0202195)
df1 <- data.frame(date_ex,tickers_ex,returns_ex ,stringsAsFactors = FALSE)

For YACKX my Sharpe ratio output should be [1] 1.997946 but I get [1] -1.186262. Similarly, for APIMX my Sharpe ratio output should be [1] -7.231879 but I get -1.186262. Thus, I know the data is not being subset correctly.

You have a few mistakes in your function. Instead of subset, just use filter instead of subset and you have the column name tickers in df1, not ticker. See below.

library(dplyr)
library(lubridate)
sharpe_ratio <- function(ticker)
{
  # Create data frame containing annualized returns for each year for ticker 
  # of interest
  df1 %>% filter(tickers == ticker) %>%
    group_by(year(date)) %>% 
    summarize(annual.return = prod(1 + mret.excess) - 1) %>% 
    as.data.frame -> annualized_returns

  # Calculate Sharpe Ratio with annualized metrics
  mu <- mean(annualized_returns$annual.return)
  sigma <- sd(annualized_returns$annual.return)
  return (mu/sigma)
}

sharpe_ratio("YACKX")
[1] 1.997946
sharpe_ratio("APIMX")
[1] -7.231879

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM