是一个数据框df
,其中包含1个变量ID
,数据点数为500K,我需要执行event counter
并符合以下条件。
的 1 即可。 event counter
时增加ID == A
的 2 即可。尽管ID == A
,但不应考虑前3个数据点用于计数器增量
下面显示了具有预期输出的数据框df
ID Event Counter
D 0
F 0
V 0
A 0
A 0
A 0
A 1
A 1
A 1
V 1
F 1
A 1
A 1
A 1
A 2
F 2
G 2
A 2
A 2
A 2
A 3
A 3
请注意: - 第1,2和3行不满足条件,因此Event Counter
无增量。虽然第4,5行和第6行中ID ==A
event counter
不会增加(引用:条件2)。第12,13和14行的情况相同。
找到类似的问题,其中计数器在满足条件的每个数据点的遇到时递增,但是我的实现条件不同。
答案 0 :(得分:5)
您可以将zoo::rollsum
用于此类任务并结合rle
:
library(zoo)
x <- rollsumr(df$ID == "A", k=4, fill = NA)
df$new <- with(rle(!is.na(x) & x == 4), rep(cumsum(values), lengths))
在这种情况下,k = 4
和x == 4
意味着在您想要增加之前需要3个ID == "A"
个案例。您可以根据需要更改此号码。
结果等于您想要的输出:
all.equal(df$Event_counter, df$new)
#[1] TRUE
rle
部分返回:
rle(!is.na(x) & x == 4)
#Run Length Encoding
# lengths: int [1:6] 6 3 5 1 5 2
# values : logi [1:6] FALSE TRUE FALSE TRUE FALSE TRUE
现在我们可以a)计算值的累积和,即0-1-1-2 ... b)使用rep
我们重复每个值与每个序列相同的次数很长,即lengths
。
答案 1 :(得分:1)
这似乎可以做你想要的:
df = read.table(text="ID Event_counter
D 0
F 0
V 0
A 0
A 0
A 0
A 1
A 1
A 1
V 1
F 1
A 1
A 1
A 1
A 2
F 2
G 2
A 2
A 2
A 2
A 3
A 3",header=TRUE)
indices = df$ID=="A"
reset.counter = indices!=c(NA,head(indices,-1))& indices==FALSE & c(NA,head(indices,-1))==TRUE
indices <- unname(split(indices, cumsum(seq_along(indices) %in% which(reset.counter))))
indices=unlist(lapply(indices, function(x) cumsum(x)==4 & x==TRUE))
df$Event_counter_check = cumsum(indices)
输出
ID Event_counter Event_counter_check
1 D 0 0
2 F 0 0
3 V 0 0
4 A 0 0
5 A 0 0
6 A 0 0
7 A 1 1
8 A 1 1
9 A 1 1
10 V 1 1
11 F 1 1
12 A 1 1
13 A 1 1
14 A 1 1
15 A 2 2
16 F 2 2
17 G 2 2
18 A 2 2
19 A 2 2
20 A 2 2
21 A 3 3
22 A 3 3
希望这有帮助!
答案 2 :(得分:0)
以下是使用split
和lapply
的基础R替代方案。
dat$v3 <-
cumsum(unlist(lapply(split(dat$ID,
with(rle(as.character(dat$ID)), rep(seq_along(values), lengths))),
function(x) {
v <- length(x)
if(x[1] == "A" && v > 3) rep(c(0, 1, 0), c(3, 1, v-4))
else rep(0, v)
})))
使用与docendo-discimus的答案中类似的方法拆分ID变量,拆分相同ID的运行。此列表将输入lapply
,检查该组是否由As组成,以及该组是否至少包含3个元素。如果是,则返回具有3 0s后跟1的向量,并返回0的剩余元素以匹配向量的长度。如果检查失败,则返回适当长度的0向量。
返回
dat
ID Event_Counter v3
1 D 0 0
2 F 0 0
3 V 0 0
4 A 0 0
5 A 0 0
6 A 0 0
7 A 1 1
8 A 1 1
9 A 1 1
10 V 1 1
11 F 1 1
12 A 1 1
13 A 1 1
14 A 1 1
15 A 2 2
16 F 2 2
17 G 2 2
18 A 2 2
19 A 2 2
20 A 2 2
21 A 3 3
22 A 3 3