将 dplyr 的 do() 与 summary() 结合使用
using dplyr's do() with summary()
我希望能够使用 dplyr
的拆分-应用-组合策略来应用 summary()
命令。
取一个简单的数据框:
df <- data.frame(class = c('A', 'A', 'B', 'B'),
value = c(100, 120, 800, 880))
理想情况下我们会这样做:
df %>%
group_by(class) %>%
do(summary(.$value))
不幸的是,这不起作用。有任何想法吗?
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。
您可以使用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
问题是 dplyr
的 do()
仅适用于 data.frame
.
形式的输入
broom package 的 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
我希望能够使用 dplyr
的拆分-应用-组合策略来应用 summary()
命令。
取一个简单的数据框:
df <- data.frame(class = c('A', 'A', 'B', 'B'),
value = c(100, 120, 800, 880))
理想情况下我们会这样做:
df %>%
group_by(class) %>%
do(summary(.$value))
不幸的是,这不起作用。有任何想法吗?
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。
您可以使用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
问题是 dplyr
的 do()
仅适用于 data.frame
.
broom package 的 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