I am given data-table, where the (i+1)-th column depends on the previous one and needs to be calculated recursively. The header of data-table consists of a sequence starting from 0.`
0 1 2 3
1: 1 NA NA NA
2: 2 NA NA NA
3: 3 NA NA NA
Accessing the columns by the index, eg dt[,..2]
makes the code IMHO the most readable. Yet, this apparently cannot be used when trying to assign:
library(data.table)
dt <- data.table("0"=c(1,2,3),"1"=c(NA,NA,NA),"2"=c(NA,NA,NA),"3"=c(NA,NA,NA))
x <- c(0.01, 0.02, 0.015)
for (u in 1:3){
v<- u+1
dt[,..v] <- dt[,..u]*(1+x[u])
}
This yields the following error:
Error in `[<-.data.table`(`*tmp*`, , ..v, value = list(`0` = c(1.01, 2.02, : object '..v' not found
Update: Thanks @IceCreamToucan for the answer. However, I have just posted a simple example to illustrate my general issue. Due to the higher complexity of my actual code, I probably will have to stick to a for-loop. So I look to a solution, to recursively access and assign the columns.
You can do this with lapply
and cumprod
. I renamed the varibles because I'm not sure how to deal with numeric column names. Also see comments for an outer
and cumprod
option.
setnames(dt, names(dt), paste0('v', names(dt)))
dt[, names(dt)[-1] := lapply(cumprod(1 + x), '*', v0)][]
# v0 v1 v2 v3
# 1: 1 1.01 1.0302 1.045653
# 2: 2 2.02 2.0604 2.091306
# 3: 3 3.03 3.0906 3.136959
You can also do it this way
for (u in 0:2){
v <- u+1
dt[, as.character(v) := get(as.character(u))*(1 + x[u + 1])]
}
dt[]
# 0 1 2 3
# 1: 1 1.01 1.0302 1.045653
# 2: 2 2.02 2.0604 2.091306
# 3: 3 3.03 3.0906 3.136959
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.