Question

I'd like to use the previous row value for a calculation involving the current row. The matrix looks something like:

      A   B
[1,]  1   2
[2,]  2   3
[3,]  3   4 
[4,]  4   5
[5,]  5   6

I want to do the following operation: (cell[i]/cell[i-1])-1, essentially calculating the % change (-1 to 1) from the current row to the previous (excluding the first row).

The output should look like:

         C      D
[1,]    NA     NA
[2,]   1.0    0.5
[3,]   0.5   0.33 
[4,]  0.33   0.25
[5,]  0.25   0.20

This can be accomplished easily using for-loops, but I am working with large data sets so I would like to use apply (or other inbuilt functions) for performance and cleaner code.

So far I've come up with:

test.perc <- sapply(test, function(x,y) x-x[y])

But it's not working.

Any ideas?

Thanks.

Was it helpful?

Solution

df/rbind(c(NA,NA), df[-nrow(df),]) - 1

will work.

OTHER TIPS

1) division

ans1 <- DF[-1,] / DF[-nrow(DF),] - 1

or rbind(NA, ans1) if its important to have the NAs in the first row

2) diff

ans2 <- exp(sapply(log(DF), diff)) - 1

or rbind(NA, ans2) if its important to have the NAs in the first row

3) diff.zoo

library(zoo)
coredata(diff(as.zoo(DF), arithmetic = FALSE)) - 1

If its important to have the NA at the beginning then add the na.pad=TRUE argument like this:

coredata(diff(as.zoo(DF), arithmetic = FALSE, na.pad = TRUE)) - 1

Alternatively, sticking with your original sapply method:

sapply(dat, function(x) x/c(NA,head(x,-1)) - 1 )

Or a variation on @user3114046's answer:

dat/rbind(NA,head(dat,-1))-1

#             A         B
#[1,]        NA        NA
#[2,] 1.0000000 0.5000000
#[3,] 0.5000000 0.3333333
#[4,] 0.3333333 0.2500000
#[5,] 0.2500000 0.2000000
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top