【问题标题】:using dplyr's do() with summary()使用 dplyr 的 do() 和 summary()
【发布时间】:2016-07-15 16:37:24
【问题描述】:

我希望能够使用 dplyr 的 split-apply-combine 策略来应用 summary() 命令。

取一个简单的数据框:

df <- data.frame(class = c('A', 'A', 'B', 'B'),
                 value = c(100, 120, 800, 880))

理想情况下,我们会这样做:

df %>%
  group_by(class) %>%
  do(summary(.$value))

不幸的是,这不起作用。有任何想法吗?

【问题讨论】:

    标签: r dplyr summary


    【解决方案1】:

    do 的行为将根据您是否给它一个命名或未命名参数而改变。对于未命名的参数,它期望每个组都有一个 data.frame,它们将绑定在一起。对于命名参数,它将为每个组创建一行,并将输出的任何内容放入具有该名称的新变量中。

    所以在这种情况下,我们会抱怨未命名的使用(summary 不会生成 data.frame),但命名的使用会起作用:

    df %>%
      group_by(class) %>%
      do(summaries = summary(.$value)) ->
      df2
    

    这给出了:

    Source: local data frame [2 x 2]
    Groups: <by row>
    
       class                  summaries
      (fctr)                      (chr)
    1      A <S3:summaryDefault, table>
    2      B <S3:summaryDefault, table>
    

    我们可以像这样访问摘要:

    df2$summaries[[1]]
    

    给予:

    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    100     105     110     110     115     120 
    

    将所有这些作为 df 的新列只能通过首先将输出转换为 data.frame 来完成,如其他答案所示。

    所以问题的根源在于summary 输出的是table 而不是data.frame。

    【讨论】:

    • 谢谢,太好了。我刚刚遇到的另一种方法是使用 broom 包中的 tidy() 函数。但是命名它是避免这种情况的一种非常简单的方法。
    【解决方案2】:

    可以使用data_frame的SE版,即data_frame_,执行:

    df %>%
      group_by(class) %>%
      do(data_frame_(summary(.$value)))
    

    或者,您可以使用由data.frame() 包裹的as.list() 和参数check.names = FALSE

    df %>%
      group_by(class) %>%
      do(data.frame(as.list(summary(.$value)), check.names = FALSE))
    

    两个版本都产生:

    # Source: local data frame [2 x 7]
    # Groups: class [2]
    # 
    #    class  Min. 1st Qu. Median  Mean 3rd Qu.  Max.
    #   (fctr) (dbl)   (dbl)  (dbl) (dbl)   (dbl) (dbl)
    # 1      A   100     105    110   110     115   120
    # 2      B   800     820    840   840     860   880
    

    【讨论】:

    • 谢谢,这个输出看起来很完美。我读过一些关于 SE 的文章,但从未完全理解它。这些功能属于哪个包?从_ 的使用来看,它看起来像@hadley 之一。我还从 broom 包中找到了一种使用 tidy() 的方法。见下文。
    • data_framedata_frame_ 来自 dplyr。顺便说一句,就我而言,这个答案值得勾选。
    • 谢谢,有道理。感谢您自愿这样做,我改变了它。
    【解决方案3】:

    问题在于dplyrdo() 仅适用于data.frame 形式的输入。

    broom packagetidy() 函数可用于将summary() 的输出转换为data.frame

    df %>%
      group_by(class) %>%
      do( tidy(summary(.$value)) )
    

    这给出了:

    Source: local data frame [2 x 7]
    Groups: class [2]
    
       class minimum    q1 median  mean    q3 maximum
      (fctr)   (dbl) (dbl)  (dbl) (dbl) (dbl)   (dbl)
    1      A     100   105    110   110   115     120
    2      B     800   820    840   840   860     880
    

    【讨论】:

      猜你喜欢
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-05
      • 2018-06-19
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      相关资源
      最近更新 更多