尝试在 R 中创建 table ,其中我按向量的变量对列进行分组
Trying to make a table in R where I group columns by variables of a vector
我正在尝试使用 kableExtra / gt 包(或任何可用的包)生成一个整洁的 table,目的是让我的值列按不同的变量分组:
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91)) %>% arrange(Name, Variables)
# Desired output:
# a b c
# Count Percent | Count Percent | Count Percent
# Mary 45 45% 76 56% 43 89%
# Jane 23 65% 11 88% 46 91%
我似乎不知道该怎么做,最接近的是:
library(gt)
gt(data, rowname_col = "Variables", groupname_col = "Name")
output
我从 this page 中显示的图表中得到启发:
table with output columns grouped by year variable
感谢您的帮助!
更新:根据来自 Stefan 的 post 解决:
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91)) %>%
arrange(desc(Name), Variables)
# Helper to put the columns in the right order
cols_order <- unlist(lapply(c("a", "b", "c"), function(x) paste(x, c("Count", "Percent"), sep = "_")))
data_wide <- data %>%
pivot_wider(names_from = "Variables", values_from = c(Count, Percent), names_glue = "{Variables}_{.value}") %>%
# Reorder columns
select(all_of(c("Name", cols_order)))
data_wide %>%
gt(rowname_col = "Name") %>%
tab_spanner_delim(delim = "_") %>%
fmt_percent(ends_with("Percent"), decimals = 0)
为了达到您想要的结果,您可以首先使用例如将数据重塑为宽格式tidy::pivot_wider
。下一步是按正确的顺序排列列。为此,我重新排序了 df 的列,但这也可以通过 gt
来完成。剩下的就是 table 的样式。要按 Variables
分组,您可以使用 tab_spanner_delim
并通过 fmt_percent
:
获得格式良好的百分比
EDIT 感谢 @Shoesoff 指出我原来的解决方案可以通过使用 tab_spanner_delim
大大简化而不是 tab_spanner
.
改进答案
library(gt)
library(tidyr)
library(dplyr)
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91)) %>%
arrange(desc(Name), Variables)
# Helper to put the columns in the right order
cols_order <- unlist(lapply(c("a", "b", "c"), function(x) paste(x, c("Count", "Percent"), sep = "_")))
data_wide <- data %>%
pivot_wider(names_from = "Variables", values_from = c(Count, Percent), names_glue = "{Variables}_{.value}") %>%
# Reorder columns
select(all_of(c("Name", cols_order)))
data_wide %>%
gt(data, rowname_col = "Name") %>%
tab_spanner_delim(
delim = "_"
) %>%
fmt_percent(ends_with("Percent"), decimals = 0)
得到结果
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91))
v1 <- xtabs(cbind(Count, Percent) ~ Name + Variables, data)
重组数据:
Mary <- apply(v1[2,,], 1, c)
dim(Mary) <- NULL
Jane <- apply(v1[1,,], 1, c)
dim(Jane) <- NULL
使用 kable 创建 table 并使用 kableExtra 添加额外的 header。
require(knitr)
require(kableExtra)
add_header_above(kable(rbind(Mary, Jane), col.names = rep(c("Count", "Percent"), 3)),
c("", "a" = 2, "b" = 2, "c" = 2))
剩下的是一些格式化以添加更多 space 并格式化百分比...
由 reprex package (v0.3.0)
于 2021-01-09 创建
我正在尝试使用 kableExtra / gt 包(或任何可用的包)生成一个整洁的 table,目的是让我的值列按不同的变量分组:
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91)) %>% arrange(Name, Variables)
# Desired output:
# a b c
# Count Percent | Count Percent | Count Percent
# Mary 45 45% 76 56% 43 89%
# Jane 23 65% 11 88% 46 91%
我似乎不知道该怎么做,最接近的是:
library(gt)
gt(data, rowname_col = "Variables", groupname_col = "Name")
output
我从 this page 中显示的图表中得到启发: table with output columns grouped by year variable
感谢您的帮助!
更新:根据来自 Stefan 的 post 解决:
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91)) %>%
arrange(desc(Name), Variables)
# Helper to put the columns in the right order
cols_order <- unlist(lapply(c("a", "b", "c"), function(x) paste(x, c("Count", "Percent"), sep = "_")))
data_wide <- data %>%
pivot_wider(names_from = "Variables", values_from = c(Count, Percent), names_glue = "{Variables}_{.value}") %>%
# Reorder columns
select(all_of(c("Name", cols_order)))
data_wide %>%
gt(rowname_col = "Name") %>%
tab_spanner_delim(delim = "_") %>%
fmt_percent(ends_with("Percent"), decimals = 0)
为了达到您想要的结果,您可以首先使用例如将数据重塑为宽格式tidy::pivot_wider
。下一步是按正确的顺序排列列。为此,我重新排序了 df 的列,但这也可以通过 gt
来完成。剩下的就是 table 的样式。要按 Variables
分组,您可以使用 tab_spanner_delim
并通过 fmt_percent
:
EDIT 感谢 @Shoesoff 指出我原来的解决方案可以通过使用 tab_spanner_delim
大大简化而不是 tab_spanner
.
改进答案
library(gt)
library(tidyr)
library(dplyr)
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91)) %>%
arrange(desc(Name), Variables)
# Helper to put the columns in the right order
cols_order <- unlist(lapply(c("a", "b", "c"), function(x) paste(x, c("Count", "Percent"), sep = "_")))
data_wide <- data %>%
pivot_wider(names_from = "Variables", values_from = c(Count, Percent), names_glue = "{Variables}_{.value}") %>%
# Reorder columns
select(all_of(c("Name", cols_order)))
data_wide %>%
gt(data, rowname_col = "Name") %>%
tab_spanner_delim(
delim = "_"
) %>%
fmt_percent(ends_with("Percent"), decimals = 0)
得到结果
data <- data.frame(Name = c("Mary","Mary","Mary","Jane","Jane","Jane"),
Variables = c(letters[1:3],letters[1:3]),
Count = c(45, 76, 43, 23, 11, 46),
Percent = c(0.45, 0.56, 0.89, 0.65, 0.88, 0.91))
v1 <- xtabs(cbind(Count, Percent) ~ Name + Variables, data)
重组数据:
Mary <- apply(v1[2,,], 1, c)
dim(Mary) <- NULL
Jane <- apply(v1[1,,], 1, c)
dim(Jane) <- NULL
使用 kable 创建 table 并使用 kableExtra 添加额外的 header。
require(knitr)
require(kableExtra)
add_header_above(kable(rbind(Mary, Jane), col.names = rep(c("Count", "Percent"), 3)),
c("", "a" = 2, "b" = 2, "c" = 2))
剩下的是一些格式化以添加更多 space 并格式化百分比...
由 reprex package (v0.3.0)
于 2021-01-09 创建