【问题标题】:Add multiple columns to data.frame using a function that returns multiple outputs in dplyr使用在 dplyr 中返回多个输出的函数将多列添加到 data.frame
【发布时间】:2019-09-02 07:42:38
【问题描述】:

我正在计算连续变量的不同分位数的中位数和值。我想一步添加所有列。这有可能做到这一点。以下是一个可重现的示例。

df <- data.frame(group = rep(c('group1','group2'),50),
             x = rnorm(100), 
             y = rnorm(100))
df %>% 
gather('variable','value', -group) %>% 
group_by(group, variable) %>% 
summarise(median = round(quantile(value,0.5, na.rm = T),2),
          iqr25 = round(quantile(value,0.25, na.rm = T),2),
          iqr75 = round(quantile(value,0.75, na.rm = T),2))

输出

# A tibble: 4 x 5
# Groups:   group [2]
  group  variable median iqr25 iqr75
  <fct>  <chr>     <dbl> <dbl> <dbl>
1 group1 x          0.06 -0.74  1.04
2 group1 y         -0.36 -1.03  0.45
3 group2 x         -0.04 -0.85  0.62
4 group2 y          0.06 -0.56  0.89

这个总结步骤可以不写分位数函数3次就完成吗?

我做了一个解决方法。但是有没有一个很好的方法来做到这一点。

df %>% 
gather('variable','value', -group) %>% 
group_by(group, variable) %>% 
summarise(s = toString(round(quantile(value, c(0.25,0.5,0.75),na.rm = T),2))) %>% 
separate(s, into = c('q25','median','q75'), sep = ',')

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你可以nestgroup_by之后的数据,然后mapquantile

    df %>% 
      gather('variable','value', -group) %>% 
      group_by(group, variable) %>% 
      nest() %>% 
      mutate(quant = map(data, ~quantile(.$value, probs = c(0.25, 0.5, 0.75))),
             quant = map(quant, t),
             quant = map(quant, as.data.frame),
             quant = map(quant, setNames, c("iqr25", "median", "iqr75")),
    
             ) %>% 
      unnest(quant) %>% 
      select(-data)
    
    # A tibble: 4 x 5
      group  variable  iqr25  median iqr75
      <fct>  <chr>     <dbl>   <dbl> <dbl>
    1 group1 x        -0.876 -0.173  0.471
    2 group2 x        -0.372  0.0507 0.519
    3 group1 y        -0.785 -0.109  0.618
    4 group2 y        -0.944 -0.117  0.647
    

    【讨论】:

    • 不错!我们可以在其中添加列名吗?
    • 查看名称编辑 - 也可以在 unnest 之后使用 dplyr::rename
    • 感谢nest 后跟map 方法在很多其他方面也有帮助。将尝试将这些纳入日常工作流程
    【解决方案2】:

    使用nest的另一种方法:

    df %>%
      gather('variable', 'value', -group) %>%
      group_by(group, variable) %>%
      nest() %>%
      mutate(quants = map(data, function(x) 
        quantile(x$value, c(0.25,0.5,0.75)))) %>%
      unnest(quants) %>%
      group_by(group, variable) %>%
      mutate(case = c("iqr25", "median" , "iqr75")) %>%
      spread(case, quants) %>% 
      mutate_if(is.numeric, round, 2)
    
    # A tibble: 4 x 5
    # Groups:   group, variable [4]
      group  variable iqr25 iqr75 median
      <fct>  <chr>    <dbl> <dbl>  <dbl>
    1 group1 x        -0.5   0.7    0.09
    2 group1 y        -0.54  0.7    0.1 
    3 group2 x        -0.59  0.61  -0.06
    4 group2 y        -0.89  0.35  -0.11
    

    【讨论】:

    • 这段代码实际上看起来比在quantile函数中使用quantile函数3次summarize更冗长和混乱!
    • 好吧,我个人认为你的原始代码是最干净和最易读的,即使你调用了quantile 3 次。替代方案是对整个数据集执行不必要的转换,以在更多代码行中实现相同的目标。我同意 Richard 的解决方案比我的更干净,但我们仍然将 3 次调用 quantile 替换为 4 次调用 map?!
    • 是的。这就是我不接受他的回答的原因。
    • 你可以只使用一个调用来映射,但是内容会变得有点混乱 - map(data, ~{quantile(.$value, probs = c(0.25, 0.5, 0.75))) %&gt;% t() %&gt;% as.data.frame() %&gt;% setNames, c("iqr25", "median", "iqr75"))})
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-21
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多