【问题标题】:How to estimate the mean of the 10% upper and lower values over multiple categories with dplyr?如何使用 dplyr 估计多个类别的 10% 上限值和下限值的平均值?
【发布时间】:2021-08-19 23:17:41
【问题描述】:

假设你在 R 中有这个 data.frame

set.seed(15)
df <-  data.frame(cat = rep(c("a", "b"), each = 50), 
                  x = c(runif(50, 0, 1), runif(50, 1, 2)))

我想估计每个类别中 10% 上限值和下限值的平均值。

我可以使用 base 这样的函数来做到这一点

dfa <- df[df$cat=="a",]
dfb <- df[df$cat=="b",]

mean(dfa[dfa$x >= quantile(dfa$x, 0.9),"x"])
# [1] 0.9537632
mean(dfa[dfa$x <= quantile(dfa$x, 0.1),"x"])
# [1] 0.07959845

mean(dfb[dfb$x >= quantile(dfb$x, 0.9),"x"])
# [1] 1.963775
mean(dfb[dfb$x <= quantile(dfb$x, 0.1),"x"])
# [1] 1.092218

但是,我不知道如何使用dplyrpurrr 来实现它。

感谢您的帮助。

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    我们可以通过使用cutquantile 作为breaks 的方法在一个组中执行此操作

    library(dplyr)
    df %>% 
        group_by(cat) %>%
        mutate(grp = cut(x, breaks = c(-Inf, quantile(x,
            probs = c(0.1, 0.9)), Inf))) %>% 
        group_by(grp, .add = TRUE) %>%
        summarise(x = mean(x, na.rm = TRUE), .groups = 'drop_last') %>%
        slice(-2)
    

    -输出

    # A tibble: 4 x 3
    # Groups:   cat [2]
      cat   grp                x
      <chr> <fct>          <dbl>
    1 a     (-Inf,0.0813] 0.0183
    2 a     (0.853, Inf]  0.955 
    3 b     (-Inf,1.21]   1.07  
    4 b     (1.93, Inf]   1.95  
    

    【讨论】:

      【解决方案2】:

      这是一种您可以使用cut() 帮助您将数据分成组然后取平均值的方法

      df %>% 
        group_by(cat) %>% 
        mutate(part=cut(x, c(-Inf, quantile(x, c(.1, .9)), Inf), labels=c("low","center","high"))) %>% 
        filter(part!="center") %>% 
        group_by(cat, part) %>% 
        summarize(mean(x))
      

      在一个漂亮的小标题中返回所有内容

        cat   part  `mean(x)`
        <chr> <fct>     <dbl>
      1 a     low      0.0796
      2 a     high     0.954 
      3 b     low      1.09  
      4 b     high     1.96 
      

      为了使其更简洁,您可以将拆分分解为辅助函数

      split_quantile <- function(x , p=c(.1, .9))  {
        cut(x, c(-Inf, quantile(x, c(.1, .9)), Inf), labels=c("low","center","high"))
      }
      df %>% 
        group_by(cat) %>% 
        mutate(part = split_quantile(x)) %>% 
        filter(part != "center") %>% 
        group_by(cat, part) %>% 
        summarize(mean(x))
      

      【讨论】:

        【解决方案3】:

        @MrFlick 答案的变体 - 您可以使用 cut_numberslice

        df %>% 
          group_by(cat) %>% 
          mutate(part = cut_number(x, n = 10)) %>% 
          group_by(cat, part) %>% 
          summarise(mean(x)) %>% 
          slice(1, n())
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-02-06
          • 2018-03-22
          • 2015-04-28
          • 1970-01-01
          • 2021-05-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多