Фильтрация по последовательности ведения сгруппированных переменных - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть фрейм данных:

df <- data.frame(
        Group=c('A','A','A','A','B','B','B','B'),
        Activity = c('EOSP','NOR','EOSP','COSP','NOR','EOSP','WL','NOR'),
        TimeLine=c(1,2,3,4,1,2,3,4)
      )

Я хочу отфильтровать только для два действия для каждой группы и в порядке, в котором я фильтрую.Например, я ищу только действия EOSP и NOR, но и в порядке.Этот код:

df %>% group_by(Group) %>% 
        filter(all(c('EOSP','NOR') %in% Activity) & Activity %in% c('EOSP','NOR'))

приводит к:

# A tibble: 6 x 3
# Groups:   Group [2]
  Group Activity TimeLine
  <fct> <fct>       <dbl>
1 A     EOSP            1
2 A     NOR             2
3 A     EOSP            3
4 B     NOR             1
5 B     EOSP            2
6 B     NOR             4

Я не хочу строку 3, так как EOSP происходит после NOR.Аналогично для группы B я не хочу строку 4, так как NOR происходит до EOSP.Как мне этого добиться?

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

здесь есть опция с пакетом : вы присоединяете df к себе, устанавливаете его подмножество, оставляя только EOSP Activity и вычисляя минимум TimeLine по группам, затемвы можете оставить только строки, у которых TimeLine больше или равно этому TimeLine, чтобы быть уверенным, что вы сохраняете NOR, только если раньше было EOSP.Затем вы отбрасываете дублированную группу и действие, если хотите сохранить только 2 действия на группу:

df[df[Activity=="EOSP", min(TimeLine), by=Group], on="Group"][Activity %in% c("NOR", "EOSP") & TimeLine >= V1][!duplicated(paste(Group, Activity))]

#   Group Activity TimeLine V1
#1:     A     EOSP        1  1
#2:     A      NOR        2  1
#3:     B     EOSP        2  2
#4:     B      NOR        4  2
0 голосов
/ 12 декабря 2018

Вот идея dplyr:

df %>%
  filter(Activity %in% c('EOSP','NOR')) %>%
  group_by(Group) %>%
  mutate(tmp = which(Activity == 'EOSP' & !duplicated(Activity))) %>%
  filter(row_number() %in%  c(tmp, tmp+1)) 

# A tibble: 4 x 4
# Groups:   Group [2]
  Group Activity TimeLine   tmp
  <fct> <fct>       <dbl> <int>
1 A     EOSP            1     1
2 A     NOR             2     1
3 B     EOSP            2     2
4 B     NOR             4     2
0 голосов
/ 12 декабря 2018

Вы можете использовать match, чтобы получить первый экземпляр Activity == EOSP, и использовать slice, чтобы удалить все до этого.Как только вы это сделаете, вы можете удалить дубликаты и отфильтровать их по EOSP и NOR, то есть

library(tidyverse)

df %>% 
 group_by(Group) %>% 
 mutate(new = match('EOSP', Activity)) %>% 
 slice(new:n()) %>% 
 distinct(Activity, .keep_all = TRUE) %>% 
 filter(Activity %in% c('EOSP', 'NOR'))

, что дает

# A tibble: 4 x 4
# Groups:   Group [2]
  Group Activity TimeLine   new
  <fct> <fct>       <dbl> <int>
1 A     EOSP            1     1
2 A     NOR             2     1
3 B     EOSP            2     2
4 B     NOR             4     2

ПРИМЕЧАНИЕ 1: Вы можете ungroup() и select(-new)

ПРИМЕЧАНИЕ 2: Здесь выдается предупреждающее сообщение

(Предупреждающее сообщение: 1: В новом: 4L: числовое выражение имеет 4 элемента: используется только первый 2: В новом: 4L: в числовом выражении 4 элемента: используется только первый)

не влияет на нас, посколькунам нужен только первый элемент, так как все равно одинаковы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...