rollapply
works by column unless the by.column=FALSE
argument is used so try this:
rollapply(dat, 20, SharpeRatio, by.column = FALSE)
Question
I designed my own function called SharpeRatio(data)
Where data is an nx2 matrix.
The function works fine for a given matrix dat, however when I try to use rollapply(dat, 20, SharpeRatio)
I get the following error: Error in dat[, 1] : incorrect number of dimensions
The following is the function definition:
SharpeRatio <- function(dat){
Returns = dat[,1]
RiskFree = dat[,2]
ER = (Returns - RiskFree)/100
Volatility = sd(Returns/100)
return((exp(mean(log(1+ER))) - 1)/Volatility)
}
Solution 2
rollapply
works by column unless the by.column=FALSE
argument is used so try this:
rollapply(dat, 20, SharpeRatio, by.column = FALSE)
OTHER TIPS
rollapply
applies a function to rolling margins of an array. But it does this column-by-column. That is, it does not present an array to your function, but presents vectors N times over (N=2 in your case).
Here's an example:
(m <- matrix(1:10, ncol=2))
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [3,] 3 8
## [4,] 4 9
## [5,] 5 10
We'll rollapply
a mean
, and see what gets passed in at each iteration:
y <- rollapply(m, width=2, FUN=function(x) {print(x); mean(x)})
## [1] 1 2
## [1] 2 3
## [1] 3 4
## [1] 4 5
## [1] 6 7
## [1] 7 8
## [1] 8 9
## [1] 9 10
No matrices are passed to the function, just individual vectors. rollapply
then packages the result up as an array in the correct shape:
y
## [,1] [,2]
## [1,] 1.5 6.5
## [2,] 2.5 7.5
## [3,] 3.5 8.5
## [4,] 4.5 9.5
The fix is in Mr. Grothendieck's comment, to pass by.column=FALSE
to rollapply
:
z <- rollapply(m, width=2, by.column=FALSE, FUN=function(x) {print(x); colMeans(x)})
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [,1] [,2]
## [1,] 2 7
## [2,] 3 8
## [,1] [,2]
## [1,] 3 8
## [2,] 4 9
## [,1] [,2]
## [1,] 4 9
## [2,] 5 10
Here, matrices of two rows each are being passed to the function. The result is the same as above:
z
## [,1] [,2]
## [1,] 1.5 6.5
## [2,] 2.5 7.5
## [3,] 3.5 8.5
## [4,] 4.5 9.5
Since the current roll apply taking a matrix returns "incorrect number of dimension", because it is not meant to take a matrix. I wrote my own one
rollmatapply <- function(m,by=100,FUN)
{
v = vector()
for(i in 1:(nrow(m)-by))
{
v[i] = do.call(FUN,list(m[i:(by+i-1),]))
}
v
}