我的朋友R-Stackoverflowers,
我有一个包含2列的数据表,并且我试图根据现有的2列值和前一行的新列计算值来计算新的第三列。
我一直在检查论坛,我尝试了几个答案,但我不明白。我希望你能帮助我。
下面是一个可重复的例子:
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 “预期”列包括我希望用"error“和”触发器“列计算的值。我想采用的公式如下:
if(trigger) {
new_column = new_column(previous_row) + 1
} else {
new_column = error
}我的第一次尝试是直接使用ifelse更新新列。我发现我必须实际初始化新列才能运行:
DTtest <- DTtest[, impact:=0]
DTtest[, impact:=ifelse(trigger, lag(impact)+1, error)]该选项确实计算了新列"impact“,但结果与我在Excel中计算该列时得到的期望值不匹配(对于整个数据表,由于它非常大,所以不能这样做):
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然后我尝试了一个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 )
}我觉得延迟(影响)由于某些原因没有得到更新的值,但我不知道为什么。
你能帮帮我吗?
谢谢!
发布于 2016-06-22 09:55:20
下面是使用组的另一种方法:
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发布于 2016-06-22 09:27:47
这可能是代码高举,但我喜欢我的代码冗长:
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发布于 2016-06-22 09:11:28
创建新的“虚拟”列,在触发== 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 4https://stackoverflow.com/questions/37963275
复制相似问题