Различные правила фильтрации для групп, использующих dplyr - PullRequest
0 голосов
/ 31 мая 2018

Пример данных:

df <- data.frame(loc.id = rep(1:2, each = 11), 
             x = c(35,51,68,79,86,90,92,93,95,98,100,35,51,68,79,86,90,92,92,93,94,94))

Для каждого loc.id я хочу отфильтровать x <= 95.

df %>% group_by(loc.id) %>% filter(row_number() <= which.max(x >= 95))

          loc.id   x
          <int> <dbl>
       1      1    35
       2      1    51
       3      1    68
       4      1    79
       5      1    86
       6      1    90
       7      1    92
       8      1    93
       9      1    95
      10      2    35

Однако для группы 2 все значения меньше 95. Поэтому я хочу сохранить все значения x для группы 2. Однако вышеприведенная строка этого не делает.

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

Вы можете использовать match, чтобы получить первый индекс TRUE и вернуть длину группы, если совпадение не найдено с помощью параметра nomatch:

df %>% 
    group_by(loc.id) %>% 
    filter(row_number() <= match(TRUE, x >= 95, nomatch=n()))

# A tibble: 20 x 2
# Groups:   loc.id [2]
#   loc.id     x
#    <int> <dbl>
# 1      1    35
# 2      1    51
# 3      1    68
# 4      1    79
# 5      1    86
# 6      1    90
# 7      1    92
# 8      1    93
# 9      1    95
#10      2    35
#11      2    51
#12      2    68
#13      2    79
#14      2    86
#15      2    90
#16      2    92
#17      2    92
#18      2    93
#19      2    94
#20      2    94

или наоборот cumsum каксостояние фильтра:

df %>% group_by(loc.id) %>% filter(!lag(cumsum(x >= 95), default=FALSE))
0 голосов
/ 31 мая 2018

Решение с использованием all вместе с пакетом dplyr может быть достигнуто как:

library(dplyr)
df %>% group_by(loc.id) %>%
  filter((x > 95) | all(x<=95))  # All x in group are <= 95 OR x > 95

# # Groups: loc.id [2]
# loc.id     x
# <int> <dbl>
# 1      1  98.0
# 2      1 100  
# 3      2  35.0
# 4      2  51.0
# 5      2  68.0
# 6      2  79.0
# 7      2  86.0
# 8      2  90.0
# 9      2  92.0
# 10      2  92.0
# 11      2  93.0
# 12      2  94.0
# 13      2  94.0
0 голосов
/ 31 мая 2018

Возможно, что-то вроде этого?

df %>%
    group_by(loc.id) %>%
    mutate(n = sum(x > 95)) %>%
    filter(n == 0 | (x > 0 & x > 95)) %>%
    ungroup() %>%
    select(-n)
## A tibble: 13 x 2
#   loc.id     x
#    <int> <dbl>
# 1      1   98.
# 2      1  100.
# 3      2   35.
# 4      2   51.
# 5      2   68.
# 6      2   79.
# 7      2   86.
# 8      2   90.
# 9      2   92.
#10      2   92.
#11      2   93.
#12      2   94.
#13      2   94.

Обратите внимание, что удаление записей, где x <= 95 соответствует , сохранение записей, где x > 95 (не x >= 95).

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