dplyr 是否可以通过在一个管道中汇总创建的输出来过滤数据帧?

Is it possible with dplyr to filter a dataframe with output created by summarize within one pipe?

我得到了一个包含一个数值和一个 5 级因子变量的数据框。

# set seed for reproducibility
set.seed(123)
df <- tibble(group = rep(c("a", "b", "c", "d", "e"), each = 20),
             values = c(rnorm(20, 0, 1), rnorm(20, 1, 1), rnorm(20, 2, 1),
                        rnorm(20, 3, 1), rnorm(20, 4, 1)))

我想使用 summarize 来得到像

这样的分位数
df %>% 
  group_by(group) %>%
  summarize(quantiles = quantile(values, c(0.25, 0.75))) 


df %>% 
  group_by(group) %>%
  summarize(quantile0.25 = quantile(values, c(0.25)), 
            quantile0.75 = quantile(values, c(0.75)))

其中之一。我不知道哪个更实用,用两个变量或两行作为一个变量来获取每一行的分位数。

最后我想(最好在同一个管道中)使用分位数过滤原始数据帧中的异常值,而不是汇总数据帧,在每个相应的组中,比如

df %>% 
  group_by() %>%
  summarize() %>%
  filter()

其中每个组都按其各自的分位数过滤+-1,5IQR。

这可能吗,最好的方法是什么? 我认为使用一个适用于所有组的过滤器值按组进行过滤会很简单,但是如何为每个组应用不同的过滤器值?

您可以编写一个函数来通过 IQR 检测异常值

is_iqr_outlier <- function(x) {
   q <- quantile(x, c(0.25, 0.75))
   iqr <- diff(q)
   (x < q[1] - 1.5*iqr) | (x > q[2] + 1.5*iqr)
}

然后你就可以在过滤器中使用它了

df %>% 
  group_by(group) %>%
  filter(!is_iqr_outlier(values))

过滤器将按组运行。您的示例数据似乎没有任何异常值,因此它不是一个很好的测试用例。