Reputation: 537
I have a time series with multiple columns, some have NA
s in them, for example:
date.a<-seq(as.Date('2014-01-01'),as.Date('2014-02-01'),by = 2)
date.b<-seq(as.Date('2014-01-01'),as.Date('2014-02-15'),by = 3)
df.a <- data.frame(time=date.a, A=sin((1:16)*pi/8))
df.b <- data.frame(time=date.b, B=cos((1:16)*pi/8))
my.ts <- merge(xts(df.a$A,df.a$time),xts(df.b$B,df.b$time))
I'd like to apply a function to each of the rows, in particular:
prices2percreturns <- function(x){100*diff(x)/x}
I think that sapply
should do the trick, but
sapply(my.ts, prices2percreturns)
gives Error in array(r, dim = d, dimnames = if (!(is.null(n1 <- names(x[[1L]])) & :
length of 'dimnames' [1] not equal to array extent
. I suspect that this is due to the NA
s when merging, but maybe I'm just doing something wrong. Do I need to remove the NA
s or is there something wrong with the length of the vector returned by the function?
Upvotes: 0
Views: 1564
Reputation: 49830
Per the comments, you don't actually want to apply the function to each row. Instead you want to leverage the vectorized nature of R. i.e. you can simply do this
100*diff(my.ts)/my.ts
If you do want to apply a function to each row of a matrix (which is what an xts object is), you can use apply
with MARGIN=1
. i.e. apply(my.ts, 1, myFUN)
.
sapply(my.ts, myFUN)
would work like apply(my.ts, 2, myFUN)
in this case -- applying a function to each column.
Upvotes: 2
Reputation: 2526
Your diff(x)
will be 1 shorter than your x
. Also your returns will be based on the results. You want returns based on the starting price not the end price. Here I change the function to reflect that and apply the function per column.
prices2percreturns <- function(x){100*diff(x)/x[-length(x)]}
prcRets = apply(my.ts, 2, prices2percreturns)
Upvotes: 1