使用dplyr的do()和summary()函数

5

我希望能够使用dplyr的分割-应用-组合策略来应用summary()命令。

以一个简单的数据框为例:

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

理想情况下,我们会做出这样的操作:

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

很遗憾,这并不起作用。有什么想法吗?
3个回答

5
您可以使用 data_frame_ 这个 SE 版本的数据框,然后执行以下操作:
df %>%
  group_by(class) %>%
  do(data_frame_(summary(.$value)))

或者,您可以使用as.list()包裹data.frame(),参数为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()的方法。请参见下文。 - Bastiaan Quast
3
data_framedata_frame_来自于dplyr。顺便说一下,就我而言,这个答案值得打勾。 - Axeman
谢谢,那很有道理。还有感谢您的志愿工作,我已经改了它。 - Bastiaan Quast

4
问题在于,dplyrdo() 只能处理 data.frame 格式的输入。
可以使用 broom 包 中的 tidy() 函数将 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

3
do 函数的行为取决于你给它命名参数还是未命名参数。对于未命名参数,它期望每个组都有一个数据框,这些数据框将被合并在一起。对于命名参数,它将为每个组创建一行,并将输出放入新的变量中。
因此,在这种情况下,如果使用未命名参数会出现错误(summary 不会产生数据框),但如果使用命名参数则可以正常工作。
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。

1
谢谢,这很棒。我刚刚发现的另一种方法是使用broom包中的tidy()函数。但给它命名是一个非常简单的避免方法。 - Bastiaan Quast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接