Roland
Roland

Reputation: 537

Applying a function to multiple rows of a time series in R

I have a time series with multiple columns, some have NAs 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 NAs when merging, but maybe I'm just doing something wrong. Do I need to remove the NAs or is there something wrong with the length of the vector returned by the function?

Upvotes: 0

Views: 1564

Answers (2)

GSee
GSee

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

crogg01
crogg01

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

Related Questions