我有一个数据表DT
,它有3列,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
的下三个值中的一个。如果为TRUE,则Eingriff == 1
否则为Eingriff == 0
。对于我的真实数据,我检查Spuer
中接下来的20个或更多值是否小于30,因此像lead(Spuer,1(、lead(Spruer,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
这里有另一个使用非等联接的选项:
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