отфильтровать все строки, меньшие х, со всеми последующими значениями, также меньшими х - PullRequest
1 голос
/ 20 апреля 2020

Я ищу краткий способ фильтрации data.frame для всех строк, меньших, чем значение x, со всеми следующими значениями, также меньшими, чем x. Я нашел способ, но он многословен. Я пытался сделать это с dplyr::cumall и cumany, но не смог понять это.

Вот небольшой пример, включающий мой реальный подход. В идеале у меня была бы только одна filter строка или mutate + filter, но при текущем подходе требуется два раунда mutate/filter.

library(dplyr)

# Original data
tbl <- tibble(value = c(100,100,100,10,10,5,10,10,5,5,5,1,1,1,1))

# desired output:
# keep only rows, where value is smaller than 5 and ...
# no value after that is larger than 5

tbl %>% 
  mutate(id = row_number()) %>% 
  filter(value <= 5) %>%
  mutate(id2 = lead(id, default = max(id) + 1) - id) %>% 
  filter(id2 == 1)

#> # A tibble: 7 x 3
#>   value    id   id2
#>   <dbl> <int> <dbl>
#> 1     5     9     1
#> 2     5    10     1
#> 3     5    11     1
#> 4     1    12     1
#> 5     1    13     1
#> 6     1    14     1
#> 7     1    15     1

Создано в 2020-04 -20 * Представить пакет (v0.3.0)

Ответы [ 2 ]

3 голосов
/ 20 апреля 2020

Вы можете объединить cummin с обратным реверсом cummax:

 tbl %>% filter(rev(cummax(rev(value))) <= 5 & cummin(value) <= 5)
# A tibble: 7 x 1
  value
  <dbl>
1     5
2     5
3     5
4     1
5     1
6     1
7     1
2 голосов
/ 20 апреля 2020

Базовым вариантом R является использование subset + rle

tblout <- subset(tbl,
                 with(rle(value<=5 & c(0,diff(value))<=0),
                      rep(lengths>1 & values,lengths)))

таким, что

> tblout
# A tibble: 7 x 1
  value
  <dbl>
1     5
2     5
3     5
4     1
5     1
6     1
7     1
...