Вот подход, использующий tidyverse
и базовую функцию R quantile
:
library(tidyverse)
df %>%
group_by(fruit) %>%
filter(price > quantile(price, 0.2) & price < quantile(price, 0.8))
#> # A tibble: 6 x 2
#> # Groups: fruit [2]
#> fruit price
#> <chr> <int>
#> 1 apple 13
#> 2 apple 14
#> 3 apple 15
#> 4 banana 3
#> 5 banana 4
#> 6 banana 2
Created on 2022-04-09 by the reprex package (v2.0.1)
Данные (взятые из вопроса) в воспроизводимом формате
df <- structure(list(fruit = c("apple", "apple", "apple", "apple",
"apple", "banana", "banana", "banana", "banana", "banana"), price = c(12L,
13L, 14L, 15L, 16L, 3L, 5L, 1L, 4L, 2L)), class = "data.frame", row.names = c(NA,
-10L))
немного по-другому, используя функцию процент_ранга dplyr
library(dplyr)
df_new <-df %>%
group_by(fruit) %>%
filter(percent_rank(price) %>% between(0.2,0.8)) %>%
ungroup()
Спасибо, что указали на это! Я не использовал фильтры в group_by. Это очень полезно.
Комбинация @Allan Cameron и @Joe Erinjeri отвечает:
library(dplyr)
df %>%
group_by(fruit) %>%
filter(between(price, quantile(price, .2), quantile(price, .8)))
fruit price
<chr> <int>
1 apple 13
2 apple 14
3 apple 15
4 banana 3
5 banana 4
6 banana 2
Это можно упростить до
df %>% group_by(fruit) %>% filter(between(percent_rank(price), 0.2, 0.8))
.