как удалить наблюдения с определенной точки? - PullRequest
0 голосов
/ 11 января 2019

У меня есть данные с несколькими наблюдениями по группам. Что я пытаюсь сделать, это удалить все наблюдения (в каждой группе) из определенного значения одной переменной.

Например, учитывая набор данных ниже:

id  Var1
A  0 
A  0
A  1
A  0
B  0
B  1
B  0 
B  1

Я хочу удалить все наблюдения для A и B после (и в том числе) первого появления 1 в Var1; результат будет:

id  Var1
A   0 
A   0
B   0

любое предложение приветствуется! Большое спасибо!

Ответы [ 3 ]

0 голосов
/ 11 января 2019

Вы можете сделать:

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 '1010 * подход представляется наиболее лаконичным, также с data.table:

setDT(df)[, .SD[cumsum(Var1) == 0], by = id]
0 голосов
/ 11 января 2019

Если вы предпочитаете 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, а затем сохраняет строки, которые меньше или равны минимальному номеру строки.

Или подход cumsum(), уже опубликованный @markus и @ arg0naut для data.table:

df %>%
 group_by(id) %>%
 filter(cumsum(Var1) < 1)
0 голосов
/ 11 января 2019

Вы можете проверить, равна ли накопленная сумма нулю на группу.

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))
...