尝试在 R 中制作一个表格,其中我按向量的变量对列进行分组

问题描述

我正在尝试使用 kableExtra / gt 包(或任何有效的包)生成一个整洁的表格,目的是让我的值列按不同的变量分组:

data <- data.frame(Name = c("Mary","Mary","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 的帖子解决

data <- data.frame(Name = c("Mary",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 的 cols 重新排序,但这可能也可以通过 gt 完成。剩下的就是设计表格。要按 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","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)

enter image description here

,

得到结果

data <- data.frame(Name = c("Mary",0.91))

v1 <- xtabs(cbind(Count,Percent) ~ Name + Variables,data)

重新组织数据:

Mary <- apply(v1[2,],1,c)
dim(Mary) <- NULL
Jane <- apply(v1[1,c)
dim(Jane) <- NULL

使用 kable 创建表格并使用 kableExtra 添加额外的标题。

require(knitr)
require(kableExtra)
add_header_above(kable(rbind(Mary,Jane),col.names = rep(c("Count",3)),c("","a" = 2,"b" = 2,"c" = 2))

Table with two headers

剩下的就是一些格式化以增加更多空间和格式化百分比...

reprex package (v0.3.0) 于 2021 年 1 月 9 日创建