尝试在 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 创建