R: Как идентифицировать первое вхождение указанного значения c переменной, сгруппированной по идентификатору - PullRequest
3 голосов
/ 28 апреля 2020

У меня есть набор данных в форме дневника - т.е. у меня есть несколько записей для одного и того же идентификатора. Кроме того, у меня есть категориальная переменная (да / нет), которая указывает, произошло событие или нет.

ID <-  c(1,1,1,2,2,2,2,3,3,3,3,3,3)
event <- c("No", "No", "No", "Yes", "No", "No", "Yes", "Yes", "Yes", "No", "No", "Yes", "Yes") 
df <- data.frame(ID, event)

ID   event   
 1    No
 1    No
 1    No
 2    Yes
 2    No
 2    No
 2    Yes
 3    Yes
 3    Yes
 3    No
 3    No
 3    Yes
 3    Yes

Теперь я хочу удалить эти записи до первого «Нет», поэтому каждый идентификатор должен начать с «нет». Однако после первого «Нет» все еще может быть «Да». Итак, желаемый результат, который я хочу:

ID   event   
 1    No
 1    No
 1    No
 2    No
 2    No
 2    Yes
 3    No
 3    No
 3    Yes
 3    Yes

Кто-нибудь знает, как этого добиться? Заранее спасибо за ваше время!

Ответы [ 4 ]

2 голосов
/ 28 апреля 2020

В base вы можете использовать match, чтобы найти позицию первого "No". Чтобы сделать это за ID, вы можете использовать split и lapply. Чтобы вернуть результат в data.frame, вы можете использовать rbind с do.call.

do.call(rbind, lapply(split(df, df$ID), function(x) {
  x[match("No", x$event):nrow(x),]}))
#     ID event
#1.1   1    No
#1.2   1    No
#1.3   1    No
#2.5   2    No
#2.6   2    No
#2.7   2   Yes
#3.10  3    No
#3.11  3    No
#3.12  3   Yes
#3.13  3   Yes
2 голосов
/ 28 апреля 2020

Попробуйте:

library(dplyr)

df %>%
  group_by(ID) %>%
  filter(cumsum(event == 'No') >= 1)

Вывод:

# A tibble: 10 x 2
# Groups:   ID [3]
      ID event
   <int> <fct>
 1     1 No   
 2     1 No   
 3     1 No   
 4     2 No   
 5     2 No   
 6     2 Yes  
 7     3 No   
 8     3 No   
 9     3 Yes  
10     3 Yes 
2 голосов
/ 28 апреля 2020

Опция, использующая data.table:

library(data.table)
setDT(df)[, .(event=event[match("No", event):.N]), ID]
2 голосов
/ 28 апреля 2020

Мы можем получить первое "No" с помощью which.max и выбрать все строки оттуда до последней строки.

library(dplyr)
df %>% group_by(ID) %>% slice(which.max(event == 'No') : n())
#Also
#df %>% group_by(ID) %>% slice(which(event == 'No')[1] : n())

#      ID event
#   <dbl> <chr>
# 1     1 No   
# 2     1 No   
# 3     1 No   
# 4     2 No   
# 5     2 No   
# 6     2 Yes  
# 7     3 No   
# 8     3 No   
# 9     3 Yes  
#10     3 Yes  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...