xappppp
xappppp

Reputation: 491

Updating the column values using previous row

I want to use the data.table functions to update a column's value by referring the value its value in previous rows. Here is an example

> DT<-data.table(id=1:2,x=1:10,y=1)

I already knew data.table can refer to previous rows in a way like below:

> DT[,z:=cumsum(y),keyby=id]
> DT[]
    id  x y z
 1:  1  1 1 1
 2:  1  3 1 2
 3:  1  5 1 3
 4:  1  7 1 4
 5:  1  9 1 5
 6:  2  2 1 1
 7:  2  4 1 2
 8:  2  6 1 3
 9:  2  8 1 4
10:  2 10 1 5

However, the next example is not working, where trying to create a Fibonacci series using previous values in column y to update itself. It seems data.table is not using a loop to perform the calculation iteratively. Can anyone tell me how to solve this kind problem using data.table elegantly?

> DT[,y:=shift(y,1,fill=0)+shift(y,2,fill=0),]
> DT[]
    id  x y z
 1:  1  1 0 1
 2:  1  3 1 2
 3:  1  5 2 3
 4:  1  7 2 4
 5:  1  9 2 5
 6:  2  2 0 1
 7:  2  4 1 2
 8:  2  6 2 3
 9:  2  8 2 4
10:  2 10 2 5

What I actually want is below (column y is updated):

    id  x y z
 1:  1  1 1 1
 2:  1  3 1 2
 3:  1  5 2 3
 4:  1  7 3 4
 5:  1  9 5 5
 6:  2  2 1 1
 7:  2  4 1 2
 8:  2  6 2 3
 9:  2  8 3 4
10:  2 10 5 5

Upvotes: 2

Views: 887

Answers (1)

mtoto
mtoto

Reputation: 24178

Generating Fibonacci numbers is by definition a sequential problem, which we could solve in data.table by defining a custom function that works with a for.loop under the hood.

# Define function
fibon <- function(x) {
  for(i in 3:length(x)) x[i] = x[i-1] + x[i-2] 
  return(x)
}

# Plug into data.table
DT[,y := fibon(y), by = id]
> DT
#   id  x y z
#1:  1  1 1 1
#2:  1  3 1 2
#3:  1  5 2 3
#4:  1  7 3 4
#5:  1  9 5 5
#6:  2  2 1 1
#7:  2  4 1 2
#8:  2  6 2 3
#9:  2  8 3 4
#10: 2 10 5 5

Upvotes: 6

Related Questions