0

I want to apply a quantile regression (with one dependent and one independent variable) to each month of a one-year time series , so that I will receive 12 coefficients as a result. My data set is given by return_2000_xts and rq() is a function for quantile regression. My dataset is in xts format and includes daily returns of bank stocks.

I tried using apply.monthly():

apply.monthly(return_2000_xts, 
    rq(esb.eu ~ hsbc.uk, data = return_2000_xts, tau = 0.95))

Unfortunately, I get the following error message:

Error in get(as.character(FUN), mode = "function", envir = envir) : object 'FUN' of mode 'function' was not found

What could be the problem with my code?

AkselA
  • 8,153
  • 2
  • 21
  • 34
bernd
  • 3
  • 2

2 Answers2

2

I'm not entirely sure what's going wrong, maybe apply.monthly() is stripping some attributes, but going back to basics seems to work.

library(xts)
library(quantreg)

data(sample_matrix)
xt <- as.xts(sample_matrix)

f <- as.character(index(xt), format="%Y-%m")
xt.ym <- split(xt, f)
lapply(xt.ym, FUN=function(x) rq(Open ~ Close, data=x, tau=0.95))

For reference, this is what didn't work, but feels like it should

apply.monthly(xt, FUN=function(x) rq(Open ~ Close, data=x))

Error in coredata.xts(x) : currently unsupported data type


I've realised why apply.monthly() doesn't work. It wants to return an xts object, but there is no way a list of regression objects can be coerced to xts, so it throws an error. It will work, however, if we limit the regression output to something that can be coerced, f.ex.

apply.monthly(xt, FUN=function(x) rq(Open ~ Close, data=x)$coef)
#            (Intercept)     Close
# 2007-01-31   12.224046 0.7564106
# 2007-02-28   -6.326472 1.1242798
# 2007-03-31   -2.108973 1.0432247
# 2007-04-30    5.739395 0.8840677
# 2007-05-31    2.453616 0.9495129
# 2007-06-30   17.380465 0.6342055
AkselA
  • 8,153
  • 2
  • 21
  • 34
  • Thank you very much. How would your code change if I want to run a regression for each year out of the period 2000 to 2018? So basically an alternative for "apply.yearly" – bernd Jun 07 '19 at 15:34
  • @bernd: I changed the code slightly to make it more generalizable. `xt` is split into groups following unique values in `f`. You can look at `?strptime` to see what options you have with `format`. You can group by day, year-day, year-weeknumber, weekday, year-weekday, etc. etc. etc. – AkselA Jun 07 '19 at 16:31
  • Thanks! It works with your code, however the result states the same coefficient (and intercept) for every month? Which does not make sense to me since obviously the data is different for every month – bernd Jun 07 '19 at 23:19
  • @bernd: Does that happen with my example, or when you use your own data? – AkselA Jun 08 '19 at 07:29
  • When I use my own data. Is there a way to provide it to you? – bernd Jun 08 '19 at 16:00
  • @bernd: You'd have to upload it to something like a github gist or pastebin paste. But before you do that, make sure you're using the correct variables, double check that your data is ok, plot it, use `str()` and `summary()`. When performing the monthly regression, check line by line that the result looks ok. Try a simpler `lapply()` call, f.ex `do.call(rbind, lapply(xt.ym, colMeans))` and compare it with `apply.monthly(xt, colMeans)`. By gradually narrowing down the scope like this you can figure out where the bug is, and then think about fixing it. – AkselA Jun 08 '19 at 16:23
  • I think I found the problem, but don't know how to solve it. When I use split(return_2000_xts, f) command, the data is separated for every month, BUT there is not a column for every bank with the observed returns. It is just a list with all returns of all banks in the sample for that month, but it should be a dataframe where the rows are the date and one column for each bank... do you know how to solve that? – bernd Jun 13 '19 at 18:38
  • @bernd: The expected output from `split(return_2000_xts, f)` is a list of multivariate time series', most likely `zoo` or `xts`, is that not what you're getting? – AkselA Jun 13 '19 at 19:21
  • @bernd: If you run `lapply(split(return_2000_xts, as.character(index(return_2000_xts), format="%Y")), summary)`, do you get a summary for each bank, each year? – AkselA Jun 13 '19 at 19:24
  • Please forget what I said ealier, the data is in correct format after using the split command. Also, when I use lapply(split(return_2000_xts, as.character(index(return_2000_xts), format="%Y")), summary), I do get a summary for each bank , each year. – bernd Jun 13 '19 at 19:28
  • So the problem must be in the last line: lapply(return_2000_xts.y, FUN=function(x) rq(esb.eu ~ hsbc.uk, data=return_2000_xts, tau=0.95)). Could it be that the argument "data=return_2000_xts" is the problem? It refers to the "old" (not splitted) file.... but when I change data= to the split file, it returns an error "arguments imply different number of rows" – bernd Jun 13 '19 at 19:30
  • Yes, that would cause error. You'd need `data=x`, assuming you also have, `function(x)`. `lapply()` is looping over each element in the list, each element is then passed to our function as `x`, or what ever you put in `function()`, and processed by our function. – AkselA Jun 13 '19 at 19:38
  • Now it works! I get 12 different coefficient and double-checked some results by running a manuel regression. Thank you! :) – bernd Jun 13 '19 at 19:49
  • @bernd: Good to hear. Figuring out what's going on with the `*apply()` functions can be a bit tricky early on. There's a good introduction in [this answer](https://stackoverflow.com/questions/3505701/grouping-functions-tapply-by-aggregate-and-the-apply-family) – AkselA Jun 13 '19 at 20:02
1

A reproducible example would be nice, but you probably want

apply.monthly(return_2000_xts, 
              FUN=rq,
              formula = esb.eu ~ hsbc.uk, 
              data = return_2000_xts, tau = 0.95)

... that is, you pass just rq function as an argument, then add the other arguments to rq() as additional arguments (which correspond to the ... argument to apply.monthly())

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • Thank you. I tried running that code and get the following error: Error in eval(substitute(subset), data, env) : object 'x' not found – bernd Jun 07 '19 at 10:12