例如,考虑以下数据集:
id Var1
A 0
A 0
A 1
A 0
B 0
B 1
B 0
B 1
我想删除Var1中第一次出现1之后(包括之后)的所有A和B观测值;结果将是:
id Var1
A 0
A 0
B 0
任何建议都非常欢迎! 非常感谢!
答案 0 :(得分:0)
您可以检查每个组的累计总和是否等于零。
dat[with(dat, ave(Var1, id, FUN = cumsum) == 0), ]
# id Var1
#1 A 0
#2 A 0
#5 B 0
数据
dat <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L
), .Label = c("A", "B"), class = "factor"), Var1 = c(0L, 0L,
1L, 0L, 0L, 1L, 0L, 1L)), .Names = c("id", "Var1"), class = "data.frame", row.names = c(NA,
-8L))
答案 1 :(得分:0)
您可以这样做:
library(data.table)
setDT(df)[, .SD[rleid(Var1) == 1], by = id]
输出:
id Var1
1: A 0
2: A 0
3: B 0
现在假设您从1开始没有观察到。否则,您可以将它们过滤掉:
setDT(df)[, .SD[rleid(Var1) == 1 & Var1 != 1], by = id]
否则,@ markus的cumsum
方法似乎最为简洁,data.table
也是如此:
setDT(df)[, .SD[cumsum(Var1) == 0], by = id]
答案 2 :(得分:0)
如果您更喜欢tidyverse
,则可以执行以下操作:
df %>%
group_by(id) %>%
filter(row_number() < min(which(Var1 == 1)))
id Var1
<fct> <int>
1 A 0
2 A 0
3 B 0
它正在评估每个组的“ Var1” == 1的最小行数,然后保持低于最小行数的行。
或者:
df %>%
group_by(id) %>%
filter(row_number() <= min(which(Var1 == 0 & lead(Var1) == 1)))
它正在评估最小行号,其中“ Var1” == 0,下一个“ Var1”值是1,然后保持小于或等于最小行号的行。
或者@markus和@ arg0naut已经为cumsum()
发布了一种data.table
方法:
df %>%
group_by(id) %>%
filter(cumsum(Var1) < 1)