R语言中为含百分比的列联表添加正确边际的问题
2×2列联表(含观测值、百分比、边际总计)解决方案
1. 简便实现工具
- 基础R可通过
table()+prop.table()组合实现,但更高效的是用专门统计包:janitor包:tabyl()函数一键生成含频数、行/列/总百分比的表格,语法简洁易读。gmodels包:CrossTable()直接输出带观测值、百分比、边际统计的列联表,自带多种预设格式。
2. 获取正确边际总计
janitor包方案:先生成tabyl对象,再调用adorn_totals(),该函数自动区分频数与百分比,仅对频数计算边际,不会错误纳入百分比值:library(janitor) # 假设数据框为df,分类变量为var1、var2 tab <- tabyl(df, var1, var2) %>% adorn_percentages("row") %>% # 计算行百分比 adorn_pct_formatting(digits = 1) %>% # 格式化百分比 adorn_ns() # 合并观测值与百分比 # 添加行、列边际总计 tab_with_totals <- tab %>% adorn_totals(c("row", "col"))gmodels包方案:CrossTable()默认输出正确边际总计,无需额外操作:library(gmodels) # prop.r=TRUE显示行百分比,其余参数关闭不必要统计量 CrossTable(df$var1, df$var2, prop.r = TRUE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
3. 观测值取整、百分比保留小数
- 观测值本身为整数,无需额外处理;百分比保留小数可通过以下方式:
janitor包:用adorn_pct_formatting(digits = 1)设置保留1位小数,按需调整digits数值即可。- 基础R:用
round()对百分比值取整,再与观测值合并:freq_table <- table(df$var1, df$var2) row_pct <- round(prop.table(freq_table, 1)*100, 1) # 保留1位小数 combined_table <- matrix(paste(freq_table, "\n", row_pct, "%", sep = ""), nrow = nrow(freq_table))
4. 基础R修改现有代码获取正确边际
若不想依赖第三方包,需分离频数与百分比,手动构建边际总计,避免addmargins()错误计算:
- 生成独立的频数表与行百分比表:
freq <- table(df$var1, df$var2) row_pct <- round(prop.table(freq, 1)*100, 1) - 将观测值与百分比合并为单元格内容:
table_content <- matrix(paste(freq, "\n", row_pct, "%", sep = ""), nrow = 2, dimnames = dimnames(freq)) - 单独计算边际总计(仅基于原始频数):
row_totals <- paste(rowSums(freq), "\n100.0%", sep = "") # 行总计的频数+100% col_totals <- c(paste(colSums(freq), sep = ""), sum(freq)) # 列总计的频数+总频数 - 组合成带边际的完整表格:
final_table <- rbind(cbind(table_content, row_totals), col_totals) dimnames(final_table) <- list(c(rownames(freq), "总计"), c(colnames(freq), "总计"))
内容的提问来源于stack exchange,提问作者pdeli
相关产品推荐
相关产品推荐

