列值增量更新

时间:2016-06-22 09:01:40

标签: r data.table

研究员R-Stackoverflowers,

我有一个包含2列的数据表,我试图根据现有的2个列值和前一行的新列计算值计算新的第三列。

我一直在查看论坛,我已经尝试了几个答案,但我没有做好。我希望你能帮助我。

这是一个可重复的例子:

xmlHttp.send

"期待"列包含我期望用"错误"计算的值。和"触发"列。我想申请的公式如下:

error <- c(1,1,0,0,0,1,1,1,1,0)
trigger <- c(FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE)
expected <- c(1,2,0,0,0,1,2,3,4,0)
DTtest <- data.table(error, trigger, expected)
DTtest
     error trigger expected 
 1:     1   FALSE        1     
 2:     1    TRUE        2     
 3:     0   FALSE        0     
 4:     0   FALSE        0     
 5:     0   FALSE        0     
 6:     1   FALSE        1     
 7:     1    TRUE        2     
 8:     1    TRUE        3     
 9:     1    TRUE        4     
10:     0   FALSE        0     

我的第一次尝试是直接使用ifelse来更新新列。我发现我必须初始化新列才能运行它:

if(trigger) {
    new_column = new_column(previous_row) + 1
} else {
    new_column = error
}

此选项会计算新列&#34;影响&#34;但是结果与我在Excel中计算列的预期值不匹配(我可以对整个数据表进行处理,因为它非常大):

DTtest <- DTtest[, impact:=0]
DTtest[, impact:=ifelse(trigger, lag(impact)+1, error)]

然后我尝试了for循环,但结果也不正确:

    error trigger expected impact
 1:     1   FALSE        1      1
 2:     1    TRUE        2      1
 3:     0   FALSE        0      0
 4:     0   FALSE        0      0
 5:     0   FALSE        0      0
 6:     1   FALSE        1      1
 7:     1    TRUE        2      1
 8:     1    TRUE        3      1
 9:     1    TRUE        4      1
10:     0   FALSE        0      0

我觉得滞后(影响)由于某种原因没有获得更新的值,但我不明白为什么。

你能帮帮我吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

这可能是代码高尔夫,但我喜欢我的代码详细:

DTtest[, impact := error]

#add a TRUE before each trigger run
DTtest[, trigger1 := trigger | shift(trigger, 1L, fill = FALSE, type = "lead")]

#IDs for by
DTtest[, rleid := rleid(trigger1)]

#cumsum by
DTtest[(trigger1), impact := cumsum(impact), by = rleid]

#    error trigger expected impact trigger1 rleid
# 1:     1   FALSE        1      1     TRUE     1
# 2:     1    TRUE        2      2     TRUE     1
# 3:     0   FALSE        0      0    FALSE     2
# 4:     0   FALSE        0      0    FALSE     2
# 5:     0   FALSE        0      0    FALSE     2
# 6:     1   FALSE        1      1     TRUE     3
# 7:     1    TRUE        2      2     TRUE     3
# 8:     1    TRUE        3      3     TRUE     3
# 9:     1    TRUE        4      4     TRUE     3
#10:     0   FALSE        0      0    FALSE     4

答案 1 :(得分:1)

以下是使用群组的替代方法:

DTtest[, grp:=cumsum(!trigger)][,new:=c(error[1], cumsum(head(error, -1))+1),grp][]

    error trigger expected grp new
 1:     1   FALSE        1   1   1
 2:     1    TRUE        2   1   2
 3:     0   FALSE        0   2   0
 4:     0   FALSE        0   3   0
 5:     0   FALSE        0   4   0
 6:     1   FALSE        1   5   1
 7:     1    TRUE        2   5   2
 8:     1    TRUE        3   5   3
 9:     1    TRUE        4   5   4
10:     0   FALSE        0   6   0

答案 2 :(得分:0)

创建新的“虚拟”列,在触发器== TRUE

时复制错误
DTtest[DTtest$trigger=="TRUE", "dummy"]<- DTtest[DTtest$trigger=="TRUE", "error"]
DTtest[is.na(DTtest$dummy), "dummy"] <- 0 # replace NA in dummy column with 0

基于虚拟列的循环:

for(i in 1:nrow(DTtest)){
  if(i == 1)DTtest[i, "new"] <- 0
  else DTtest[i, "new"] <- DTtest[i,"dummy"] + DTtest[i-1,"new"]
} 

   error trigger expected dummy new
1      1   FALSE        1     0   0
2      1    TRUE        2     1   1
3      0   FALSE        0     0   1
4      0   FALSE        0     0   1
5      0   FALSE        0     0   1
6      1   FALSE        1     0   1
7      1    TRUE        2     1   2
8      1    TRUE        3     1   3
9      1    TRUE        4     1   4
10     0   FALSE        0     0   4