考虑测试数据集
test = data.table("a"=c(NA,NA, 0, NA, NA), "b"=c(1,3,4,7,8), "c"=c(NA, 2,1,3,1), "group"=c(1,1,1,1,1))
a b c group
1: NA 1 NA 1
2: NA 3 2 1
3: 0 4 1 1
4: NA 7 3 1
5: 0 8 1 1
6: NA 9 1 1
我想更新列的值,以便:
t = a_{i-1}+c_i
if(is.na(a_i)) {
a_i = t
}
这应该会产生以下数据集:
a b c group
1: NA 1 NA 1
2: NA 3 2 1
3: 0 4 1 1
4: 3 7 3 1
5: 0 8 1 1
6: 1 9 1 1
我将示例缩减为一组,但可以有多个。我宁愿避免使用循环解决方案,因为我的实际数据集有数百万行。
答案 0 :(得分:0)
当我在第一个非NA
NA
之前有a
值时,我不清楚逻辑是什么。我认为它是保持a
的当前值。在这种情况下,那么这可能是你期待的:
> library(zoo)
> test = data.table("a"=c(NA,NA, 0, NA, NA, 1, 2),
+ "b"=c(1,3,4,7,8, 9, 10),
+ "c"=c(NA, 2,1,3,1, 1, 2),
+ "group"=c(1,1,1,1,1,1, 1))
> test
a b c group
1: NA 1 NA 1
2: NA 3 2 1
3: 0 4 1 1
4: NA 7 3 1
5: NA 8 1 1
6: 1 9 1 1
7: 2 10 2 1
>
> test[, `:=`(tmp_idx = shift(cumsum(!is.na(a)), fill = 0) > 0)][
+ , c_cum := cumsum(c), by = tmp_idx][
+ tmp_idx == 0, c_cum := 0][
+ tmp_idx == TRUE, a := NA][
+ , a := na.locf(a, na.rm = FALSE)]
> test
a b c group tmp_idx c_cum
1: NA 1 NA 1 FALSE 0
2: NA 3 2 1 FALSE 0
3: 0 4 1 1 FALSE 0
4: 0 7 3 1 TRUE 3
5: 0 8 1 1 TRUE 4
6: 0 9 1 1 TRUE 5
7: 0 10 2 1 TRUE 7
>
> test[, a := ifelse(is.na(shift(a)), a, shift(a)) + c_cum][
+ , `:=`(tmp_idx = NULL, c_cum = NULL)]
> test
a b c group
1: NA 1 NA 1
2: NA 3 2 1
3: 0 4 1 1
4: 3 7 3 1
5: 4 8 1 1
6: 5 9 1 1
7: 7 10 2 1
如果您有更多群组,请使用.SD
调用[.data.table
内的by
使用上述内容。