Rob
Rob

Reputation: 1490

Applying function to multiple rows using values from multiple rows

I have created the following simple function in R:

fun    <- function(a,b,c,d,e){b+(c-a)*((e-b)/(d-a))}

That I want to apply this function to a data.frame that looks something like:

> data.frame("x1"=seq(55,75,5),"x2"=round(rnorm(5,50,10),0),"x3"=seq(30,10,-5))
  x1 x2 x3
1 55 51 30
2 60 45 25
3 65 43 20
4 70 57 15
5 75 58 10

I want to apply fun to each separate row to create a new variable x4, but now comes the difficult part (to me at least..): for the arguments d and e I want to use the values x2 and x3 from the next row. So for the first row of the example that would mean: fun(a=55,b=51,c=30,d=45,e=25). I know that I can use mapply() to apply a function to each row, but I have no clue on how to tell mapply that it should use some values from the next row, or whether I should be looking for a different approach than mapply()?

Many thanks in advance!

Upvotes: 0

Views: 2483

Answers (1)

Ari B. Friedman
Ari B. Friedman

Reputation: 72731

Use mapply, but shift the fourth and fifth columns by one row. You can do it manually, or use taRifx::shift.

> dat
  x1 x2 x3
1 55 25 30
2 60 58 25
3 65 59 20
4 70 68 15
5 75 43 10
library(taRifx)
> shift(dat$x2)
[1] 58 59 68 43 25
> mapply( dat$x1, dat$x2, dat$x3, shift(dat$x2), shift(dat$x3) , FUN=fun )
[1]    25.00000 -1272.00000   719.00000   -50.14815    26.10000

If you want the last row to be NA rather than wrapping, use wrap=FALSE,pad=TRUE:

> shift(dat$x2,wrap=FALSE,pad=TRUE)
[1] 58 59 68 43 NA

Upvotes: 6

Related Questions