如何从特定点开始删除观测值?

时间:2019-01-11 18:17:55

标签: r subset data-manipulation

我有一个按组有多个观察值的数据。我要做的就是从单个变量的特定值中删除所有观察(在每个组中)。

例如,考虑以下数据集:

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

任何建议都非常欢迎! 非常感谢!

3 个答案:

答案 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)