代码之家  ›  专栏  ›  技术社区  ›  Martin Ueding

分组依据,然后用多个元素汇总

  •  0
  • Martin Ueding  · 技术社区  · 7 年前

    假设我在一个数据框架中有许多测试结果 scores 如下:

       name firstname score
    1 McKay    Rodney     4
    2 McKay    Rodney     2
    3 McKay    Rodney     5
    4  Weir Elizabeth     1
    5  Weir Elizabeth     8
    

    我想计算每个人的分数分布的分位数。如果我只想要一个固定的分位数(比如中位数),我可以做以下操作:

    quantile_df <- score_df %>%
        group_by(name, firstname) %>%
        summarize(q50 = median(score))
    

    生成的数据帧将具有列 name ,请 firstname q50 .如果我想计算任意数量的分位数,这是不可缩放的。假设我现在想要三个,那么结果如下(数字是胡说):

       name firstname    q quantiles
    1 McKay    Rodney 0.25         1
    2 McKay    Rodney 0.50         3
    3 McKay    Rodney 0.75         7
    4  Weir Elizabeth 0.25         2
    5  Weir Elizabeth 0.50         4
    6  Weir Elizabeth 0.75         6
    

    感觉就像 dplyr 应该是为这个找到东西的合适包装,但我没有。相反,我将实现以下功能:

    • 将原始数据帧减少到我要分组的列。
    • 仅获取该数据帧的唯一行。
    • 使用 mapply 在包含此数据帧的行的函数上 名称 名字 .然后此函数将筛选 分数 这样名字和名字就匹配并提取分数。函数返回的数据帧 名称 ,请 名字 ,请 q quantiles .
    • 可能还有其他行,然后我将使用函数和reduced的结果进行联接 分数 获取这些列的数据框(如果有)。

    公共R库中是否存在这样的函数?

    2 回复  |  直到 7 年前
        1
  •  3
  •   Sotos    7 年前

    unnest()

    library(tidyverse)
    
    df %>% 
     group_by(name, firstname) %>% 
     summarise(new = list(quantile(score))) %>% 
     unnest()
    

    # A tibble: 10 x 3
    # Groups:   name [2]
       name  firstname   new
       <fct> <fct>     <dbl>
     1 McKay Rodney     2.00
     2 McKay Rodney     3.00
     3 McKay Rodney     4.00
     4 McKay Rodney     4.50
     5 McKay Rodney     5.00
     6 Weir  Elizabeth  1.00
     7 Weir  Elizabeth  2.75
     8 Weir  Elizabeth  4.50
     9 Weir  Elizabeth  6.25
    10 Weir  Elizabeth  8.00
    
        2
  •  0
  •   IceCreamToucan    7 年前

    data.table

    score_df <- data.frame(name = sample(c('Bob', 'Sue', 'Lorna'), 100, T)
                           , score = sample(1:100))
    
    library(data.table)
    setDT(score_df)
    
    
    score_df[, quantile(score), name]
    #      name     V1
    #  1:   Bob   1.00
    #  2:   Bob  20.00
    #  3:   Bob  41.00
    #  4:   Bob  82.00
    #  5:   Bob  99.00
    #  6: Lorna   2.00
    #  7: Lorna  23.00
    #  8: Lorna  52.00
    #  9: Lorna  77.00
    # 10: Lorna 100.00
    # 11:   Sue   7.00
    # 12:   Sue  33.75
    # 13:   Sue  50.00
    # 14:   Sue  64.50
    # 15:   Sue  94.00
    

    或者,如果你想包括百分比

    score_df[, {qu <- quantile(score)
                .(q = names(qu), quantiles = qu)}
             , name]
    
    #      name    q quantiles
    #  1:   Bob   0%      1.00
    #  2:   Bob  25%     20.00
    #  3:   Bob  50%     41.00
    #  4:   Bob  75%     82.00
    #  5:   Bob 100%     99.00
    #  6: Lorna   0%      2.00
    #  7: Lorna  25%     23.00
    #  8: Lorna  50%     52.00
    #  9: Lorna  75%     77.00
    # 10: Lorna 100%    100.00
    # 11:   Sue   0%      7.00
    # 12:   Sue  25%     33.75
    # 13:   Sue  50%     50.00
    # 14:   Sue  75%     64.50
    # 15:   Sue 100%     94.00
    

    数据.表

    score_df[, quantile(score), .(name, firstname)]
    

    如果你碰巧 tibble tidyverse

    library(tidyverse)
    score_df[, enframe(quantile(score), 'q')
             , name]
    
    #      name    q value
    #  1: Lorna   0%   9.0
    #  2: Lorna  25%  35.0
    #  3: Lorna  50%  65.5
    #  4: Lorna  75%  85.0
    #  5: Lorna 100%  97.0
    #  6:   Bob   0%   7.0
    #  7:   Bob  25%  24.5
    #  8:   Bob  50%  48.0
    #  9:   Bob  75%  65.5
    # 10:   Bob 100% 100.0
    # 11:   Sue   0%   1.0
    # 12:   Sue  25%  19.0
    # 13:   Sue  50%  40.0
    # 14:   Sue  75%  67.0
    # 15:   Sue 100%  98.0