#r #dplyr
Вопрос:
Я хочу отфильтровать идентификатор группы только после двух последовательных значений «да», которые наблюдаются.
DT<-data.frame(id=c(1,1,1,2,2,2,2,3,3,3,3,3,3,3),
type=c("yes","yes","no","no","yes","yes","no","no","yes","no","yes","yes","no","yes"))
Желаемый результат:
id type
1 yes
1 yes
1 no
2 yes
2 yes
2 no
3 yes
3 yes
3 no
3 yes
Я попробовал это как:
DT<-DT %>% group_by(id) %>%
mutate(Tlag = lag(type), ident = type == 'yes' amp; Tlag == 'yes' ) %>%
filter(any(ident)) %>% filter(type == 'yes' | (cumsum(type == 'yes') == 1)) %>% select(-ident)
Комментарии:
1. В ваших данных есть неправильное написание переменной
type
asype
.2. Я исправил опечатку.
Ответ №1:
Использование dplyr
и вид индикатора:
DT %>%
group_by(id) %>%
mutate(indic = ifelse(lead(type) == "yes" amp; type == "yes", 1, NA)) %>%
fill(indic, .direction = 'down') %>%
filter(!is.na(indic)) %>%
select(-indic)
Выход:
# A tibble: 10 x 2
# Groups: id [3]
id type
<dbl> <chr>
1 1 yes
2 1 yes
3 1 no
4 2 yes
5 2 yes
6 2 no
7 3 yes
8 3 yes
9 3 no
10 3 yes
Ответ №2:
У вас почти получилось, т. е. используйте lead
вместо lag
и немного отрегулируйте свой порог кумуляции:
library(tidyverse)
DT %>%
group_by(id) %>%
mutate(Tlead = lead(type),
cumsum_yes = cumsum(type == "yes" amp; Tlead == "yes"),
cumsum_yes = if_else(is.na(cumsum_yes), lag(cumsum_yes), cumsum_yes)) %>%
filter(cumsum_yes >=1) %>%
select(-cumsum_yes, -Tlead)
что дает:
# A tibble: 10 x 2
# Groups: id [3]
id type
<dbl> <chr>
1 1 yes
2 1 yes
3 1 no
4 2 yes
5 2 yes
6 2 no
7 3 yes
8 3 yes
9 3 no
10 3 yes
Вот результат без удаления временных столбцов, чтобы вы могли лучше видеть, что происходит:
# A tibble: 10 x 4
# Groups: id [3]
id type Tlead cumsum_yes
<dbl> <chr> <chr> <int>
1 1 yes yes 1
2 1 yes no 1
3 1 no NA 1
4 2 yes yes 1
5 2 yes no 1
6 2 no NA 1
7 3 yes yes 1
8 3 yes no 1
9 3 no yes 1
10 3 yes NA 1
Ответ №3:
Если вы используете rollapply
from zoo
, вы можете искать любое количество 'yes'
значений.
library(dplyr)
library(zoo)
n <- 2
DT %>%
group_by(id) %>%
filter(row_number() >= match(TRUE,
rollapply(type == 'yes', n, all, align = 'left', fill = NA))) %>%
ungroup()
# id type
# <dbl> <chr>
# 1 1 yes
# 2 1 yes
# 3 1 no
# 4 2 yes
# 5 2 yes
# 6 2 no
# 7 3 yes
# 8 3 yes
# 9 3 no
#10 3 yes