Удалите все строки из фрейма данных, которые следуют порогу фильтра, используя dplyr - PullRequest
2 голосов
/ 03 марта 2020

Это похоже на достаточно распространенную задачу, и я предполагаю, что для ее выполнения существует установленная функция / метод. Я представляю себе функцию, подобную dplyr::filter_after(), но, похоже, ее нет.

Вот метод, который я использую в качестве отправной точки:

#Setup:
library(dplyr)
threshold <- 3
test.df <- data.frame("num"=c(1:5,1:5),"let"=letters[1:10])

#Drop every row that follows the first 3, including that row:
out.df <- test.df %>%
  mutate(pastThreshold = cumsum(num>=threshold)) %>%
  filter(pastThreshold==0) %>%
  dplyr::select(-pastThreshold)

Это дает желаемый результат:

> out.df
  num let
1   1   a
2   2   b

Есть ли другое решение, которое менее многословно?

Ответы [ 3 ]

1 голос
/ 03 марта 2020

Мы можем использовать то же самое в filter без необходимости создания дополнительного столбца и последующего его удаления

library(dplyr)
test.df %>% 
     filter(cumsum(num>=threshold) == 0)
#   num let
#1   1   a
#2   2   b

Или другой вариант match с slice

test.df  %>%
    slice(seq_len(match(threshold-1, num)))

Или другой вариант rleid

library(data.table)
test.df %>%
     filter(rleid(num >= threshold) == 1)
1 голос
/ 03 марта 2020

dplyr предоставляет оконные функции cumany и cumall, которые фильтруют все строки после / до того, как условие впервые становится ложным. Документация .

test.df %>% 
  filter(cumall(num<threshold)) #all rows until condition violated for first time
#   num let
# 1   1   a
# 2   2   b
1 голос
/ 03 марта 2020

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

test.df %>%
 slice(1:which.max(num == threshold)-1)

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