用两个因素重新排列 dplyr groupby 输出?
Rearrange dplyr groupby output with exactly two factors?
我发现这个问题很难搜索,因为术语总结、groupby、重新排列 table 太通用了。
我想做的是在按两个因素分组后汇总一个值,并将结果放入 table 中,rows/columns 为 factor1/factor2。这是 groupby-exactly-two 的一个特例,每个单元格一个值,但我发现自己非常想要这种模式。
这是一个玩具数据集,其中因子“isx”有两个水平,因子“grp”有三个水平:
library(dplyr)
df <- tibble(
isx = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
grp = c('a', 'b', 'c', 'a', 'b', 'c',
'a', 'b', 'c', 'a', 'b', 'c'),
val = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
)
df$isx <- factor(df$isx)
df$grp <- factor(df$grp)
df %>%
group_by(isx, grp) %>%
summarize(mean(val))
dplyr 很棒,我可以轻松找到每个独特组合的价值摘要。但是输出是 6 行 table,每 2x3=6 种因素组合一行。
## # A tibble: 6 x 3
## # Groups: isx [2]
## isx grp `mean(val)`
## <fct> <fct> <dbl>
## 1 FALSE a 8.5
## 2 FALSE b 9.5
## 3 FALSE c 10.5
## 4 TRUE a 2.5
## 5 TRUE b 3.5
## 6 TRUE c 4.5
在恰好有两个因素的特殊情况下,我刚刚将它们组合在一起,我很乐意将该结果转换为更易读的小 table。像这样:
# grp
# a b c
# isX F 8.5 9.5 10.5
# T 2.5 3.5 4.5
最后的想法是,我确定我可以通过查找代码位来将输出 tibble 重建到我想要的矩阵中。但这感觉就像是 R 可以通过一次调用完成的情况,如果我能弄清楚如何具体表达我正在寻找的内容。
我们可以使用 pivot_wider
和 values_fn
作为 mean
一步完成重塑和聚合
library(dplyr)
library(tidyr)
df %>%
pivot_wider(names_from = grp, values_from = val, values_fn = mean)
-输出
# A tibble: 2 x 4
# isx a b c
# <fct> <dbl> <dbl> <dbl>
#1 TRUE 2.5 3.5 4.5
#2 FALSE 8.5 9.5 10.5
类似于 dcast
功能 (data.table/reshape2
)
library(data.table)
dcast(df, isx ~ grp, value.var = 'val', mean)
或在 base R
中使用 xtabs
和 aggregate
xtabs(val ~ isx + grp, aggregate(val ~ isx + grp, df, mean))
# grp
#isx a b c
# FALSE 8.5 9.5 10.5
# TRUE 2.5 3.5 4.5
或 tapply
来自 base R
with(df, tapply(val, list(isx, grp), mean))
# a b c
#FALSE 8.5 9.5 10.5
#TRUE 2.5 3.5 4.5
我发现这个问题很难搜索,因为术语总结、groupby、重新排列 table 太通用了。
我想做的是在按两个因素分组后汇总一个值,并将结果放入 table 中,rows/columns 为 factor1/factor2。这是 groupby-exactly-two 的一个特例,每个单元格一个值,但我发现自己非常想要这种模式。
这是一个玩具数据集,其中因子“isx”有两个水平,因子“grp”有三个水平:
library(dplyr)
df <- tibble(
isx = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE),
grp = c('a', 'b', 'c', 'a', 'b', 'c',
'a', 'b', 'c', 'a', 'b', 'c'),
val = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
)
df$isx <- factor(df$isx)
df$grp <- factor(df$grp)
df %>%
group_by(isx, grp) %>%
summarize(mean(val))
dplyr 很棒,我可以轻松找到每个独特组合的价值摘要。但是输出是 6 行 table,每 2x3=6 种因素组合一行。
## # A tibble: 6 x 3
## # Groups: isx [2]
## isx grp `mean(val)`
## <fct> <fct> <dbl>
## 1 FALSE a 8.5
## 2 FALSE b 9.5
## 3 FALSE c 10.5
## 4 TRUE a 2.5
## 5 TRUE b 3.5
## 6 TRUE c 4.5
在恰好有两个因素的特殊情况下,我刚刚将它们组合在一起,我很乐意将该结果转换为更易读的小 table。像这样:
# grp
# a b c
# isX F 8.5 9.5 10.5
# T 2.5 3.5 4.5
最后的想法是,我确定我可以通过查找代码位来将输出 tibble 重建到我想要的矩阵中。但这感觉就像是 R 可以通过一次调用完成的情况,如果我能弄清楚如何具体表达我正在寻找的内容。
我们可以使用 pivot_wider
和 values_fn
作为 mean
一步完成重塑和聚合
library(dplyr)
library(tidyr)
df %>%
pivot_wider(names_from = grp, values_from = val, values_fn = mean)
-输出
# A tibble: 2 x 4
# isx a b c
# <fct> <dbl> <dbl> <dbl>
#1 TRUE 2.5 3.5 4.5
#2 FALSE 8.5 9.5 10.5
类似于 dcast
功能 (data.table/reshape2
)
library(data.table)
dcast(df, isx ~ grp, value.var = 'val', mean)
或在 base R
中使用 xtabs
和 aggregate
xtabs(val ~ isx + grp, aggregate(val ~ isx + grp, df, mean))
# grp
#isx a b c
# FALSE 8.5 9.5 10.5
# TRUE 2.5 3.5 4.5
或 tapply
来自 base R
with(df, tapply(val, list(isx, grp), mean))
# a b c
#FALSE 8.5 9.5 10.5
#TRUE 2.5 3.5 4.5