我有一个数据框
df<-data.frame(var1=c(1:10),var2=c(rep(c(0,0.1),each=5)),BYGROUP_OBSNUM=c(0:4))
我想使用rowwise伪公式计算列
df$VAR1_NEW <-(ifelse (var2!=0 & BYGROUP_OBSNUM !=0),
var1[i]+lag(var1,1)*var2^1+lag(var1,2)*var2^2 +....lag(var1,BYGROUP_OBSNUM)*var2^BYGROUP_OBSNUM)
目前的做法 -
my.func <- function(x){mapply(function(v1,v2,v3,n) {
if(v2==0 | v3==0){
as.numeric(v1)
} else {
sum(v1, x[rev(seq(1:(n-1))),1][1:v3] * v2 ^ seq(1:(n-1))[1:v3])
}
}, x[,"var1"], x[,"var2"], x[,"BYGROUP_OBSNUM"],seq(1:nrow(x)))
}
df1 <- df %>%
do(data.frame(., my.func(.))) %>%
mutate(VAR1_NEW = my.func...)%>%
select(-my.func...)
#Result -
DF1
var1 var2 BYGROUP_OBSNUM VAR1_NEW
1 0.0 0 1.0000
2 0.0 1 2.0000
3 0.0 2 3.0000
4 0.0 3 4.0000
5 0.0 4 5.0000
6 0.1 0 6.0000
7 0.1 1 7.6000
8 0.1 2 8.7600
9 0.1 3 9.8760
10 0.1 4 10.9876
对于140万行的数据帧,此方法需要6分钟。因此,我想改变data.table的方法,因为不会创建副本所需的时间更短。
到目前为止,这是我所取得的成就 -
DT<-as.data.table(df)
DT<-DT[, c("New_Var1") := my.func(DT)]
但这引发了很多警告,比如 -
>warnings()
10: In if (v2 == 0 | v3 == 0) { ... :
the condition has length > 1 and only the first element will be used
11: In `[.data.table`(DT, , `:=`(c("New.Var1"), my.func(DT))) :
10 column matrix RHS of := will be treated as one vector
12: In `[.data.table`(DT, , `:=`(c("New.Var1"), my.func(DT))) :
Supplied 100 items to be assigned to 10 items of column 'New.Var1' (90 unused)
只是将var1列复制到new_var1中,因为只使用了第一个元素。
我是data.table使用的新手,无法找到解决方法。
答案 0 :(得分:2)
以下是使用data.table
library(data.table)
setDT(df)[, grp := cumsum(BYGROUP_OBSNUM==0)
][, VAR1_NEW := Reduce(`+`, Map(`*`, shift(var1, 1:.N, fill = 0),
var2^(seq_len(.N)))) + var1, grp][, grp := NULL][]
# var1 var2 BYGROUP_OBSNUM VAR1_NEW
# 1: 1 0.0 0 1.0000
# 2: 2 0.0 1 2.0000
# 3: 3 0.0 2 3.0000
# 4: 4 0.0 3 4.0000
# 5: 5 0.0 4 5.0000
# 6: 6 0.1 0 6.0000
# 7: 7 0.1 1 7.6000
# 8: 8 0.1 2 8.7600
# 9: 9 0.1 3 9.8760
#10: 10 0.1 4 10.9876