我希望能够使用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))
不幸的是,这不起作用。有任何想法吗?
答案 0 :(得分:5)
您可以使用data_frame
的SE版本,即data_frame_
并执行:
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
答案 1 :(得分:4)
问题是dplyr
的{{1}}仅适用于do()
形式的输入。
broom package的data.frame
函数可用于将tidy()
的输出转换为summary()
。
data.frame
这给出了:
df %>%
group_by(class) %>%
do( tidy(summary(.$value)) )
答案 2 :(得分:3)
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。