data.table 中后续值或先前值的滚动计算
rolling computation for following or previous values in a data.table
我有一个包含 3 列的 data.table DT
,Zeit
、Spuer
和 Eingriff
。
DT <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44),
Eingriff = c(0, 0, 1, 0, 0, 0, 1, 0, 0))
我想知道 Eingriff == 1
和 Spuer < 30
的后 3 个值之一。如果为真,则 Eingriff == 1
否则 Eingriff == 0
。对于我的真实数据,我检查 Spuer
中接下来的 20 个或更多值是否小于 30,因此 lead(Spuer, 1)、lead(Spuer, 2) 等解决方案不是一个好的解决方案。
我已经尝试使用 frollapply
和 shift
实现解决方案,但无法实现。
最后的结果应该是这样的:
res <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44),
Eingriff = c(0, 0, 1, 0, 0, 0, 0, 0, 0))
这是一个使用 sapply
的选项:
我们首先找出 Eingriff == 1
所在的索引,并针对每个索引检查 window
中值的 any
是否小于 30。
library(data.table)
window <- 3
inds <- which(DT$Eingriff == 1)
DT[inds, Eingriff := as.integer(sapply(inds, function(x)
any(DT$Spuer[x:(x+window - 1)] < 30)))]
DT
# Zeit Spuer Eingriff
#1: 1 45 0
#2: 2 45 0
#3: 3 32 1
#4: 4 25 0
#5: 5 30 0
#6: 6 44 0
#7: 7 34 0
#8: 8 42 0
#9: 9 44 0
这是另一个使用 non-equi 连接的选项:
k <- 3L
DT[, c("start", "end") := .(.I, .I + k)]
DT[Eingriff==1L, Eingriff :=
DT[.SD, on=.(start>start, start<=end), by=.EACHI, +any(x.Spuer < 30)]$V1
]
输出:
Zeit Spuer Eingriff start end
1: 1 45 0 1 4
2: 2 45 0 2 5
3: 3 32 1 3 6
4: 4 25 0 4 7
5: 5 30 0 5 8
6: 6 44 0 6 9
7: 7 34 0 7 10
8: 8 42 0 8 11
9: 9 44 0 9 12
我有一个包含 3 列的 data.table DT
,Zeit
、Spuer
和 Eingriff
。
DT <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44),
Eingriff = c(0, 0, 1, 0, 0, 0, 1, 0, 0))
我想知道 Eingriff == 1
和 Spuer < 30
的后 3 个值之一。如果为真,则 Eingriff == 1
否则 Eingriff == 0
。对于我的真实数据,我检查 Spuer
中接下来的 20 个或更多值是否小于 30,因此 lead(Spuer, 1)、lead(Spuer, 2) 等解决方案不是一个好的解决方案。
我已经尝试使用 frollapply
和 shift
实现解决方案,但无法实现。
最后的结果应该是这样的:
res <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44),
Eingriff = c(0, 0, 1, 0, 0, 0, 0, 0, 0))
这是一个使用 sapply
的选项:
我们首先找出 Eingriff == 1
所在的索引,并针对每个索引检查 window
中值的 any
是否小于 30。
library(data.table)
window <- 3
inds <- which(DT$Eingriff == 1)
DT[inds, Eingriff := as.integer(sapply(inds, function(x)
any(DT$Spuer[x:(x+window - 1)] < 30)))]
DT
# Zeit Spuer Eingriff
#1: 1 45 0
#2: 2 45 0
#3: 3 32 1
#4: 4 25 0
#5: 5 30 0
#6: 6 44 0
#7: 7 34 0
#8: 8 42 0
#9: 9 44 0
这是另一个使用 non-equi 连接的选项:
k <- 3L
DT[, c("start", "end") := .(.I, .I + k)]
DT[Eingriff==1L, Eingriff :=
DT[.SD, on=.(start>start, start<=end), by=.EACHI, +any(x.Spuer < 30)]$V1
]
输出:
Zeit Spuer Eingriff start end
1: 1 45 0 1 4
2: 2 45 0 2 5
3: 3 32 1 3 6
4: 4 25 0 4 7
5: 5 30 0 5 8
6: 6 44 0 6 9
7: 7 34 0 7 10
8: 8 42 0 8 11
9: 9 44 0 9 12