R 列值增量更新
各位R-Stackoverflowers 我有一个包含两列的数据表,我正在尝试根据两个现有列值和前一行的新列计算值计算新的第三列 我一直在查看论坛,我尝试了几个答案,但我没有得到正确的答案。我希望你能帮助我 以下是一个可复制的示例:R 列值增量更新,r,data.table,R,Data.table,各位R-Stackoverflowers 我有一个包含两列的数据表,我正在尝试根据两个现有列值和前一行的新列计算值计算新的第三列 我一直在查看论坛,我尝试了几个答案,但我没有得到正确的答案。我希望你能帮助我 以下是一个可复制的示例: 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
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更新新列。我发现我必须初始化新列才能运行:
DTtest <- DTtest[, impact:=0]
DTtest[, impact:=ifelse(trigger, lag(impact)+1, error)]
然后我尝试了for循环,但结果也不正确:
for(index in nrow(DTtest)){
imp <- 0
if(index==1){
imp <- DTtest[index]$error
} else {
imp <- DTtest[index-1]$impact+1
}
set(DTtest, i=index, j=as.integer(4), value=imp )
}
for(nrow索引(DTtest)){
imp创建新的“虚拟”列,当触发器==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
DTtest[DTtest$trigger==“TRUE”,“dummy”]这可能是一个代码,但我喜欢我的代码冗长:
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
以下是使用组的另一种方法:
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
这显然与“预期”列不匹配(而且没有使用data.table“编码样式”)是的,它越来越近了,但新值不是预期值。不过,我正试图用伪列解决一些问题。是的,我尝试了求和,但它没有给出预期值。我只想求和错误>0组(错误组=1个值,错误=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
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
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