R中用lapply与summarytools::ctable批量生成交叉表的问题
批量生成交叉表及问题修复方案
问题1:变量名与频数表输出顺序错位
原因是lapply会缓存所有函数返回结果最后统一输出,而print(i)是即时输出,导致先打印所有变量名再输出所有表格。修复方法是显式打印表格,用无返回值的迭代函数避免汇总输出:
library(RNHANES) library(summarytools) library(purrr) smk <- nhanes_load_data("SMQ_H", "2013-2014") vars <- c("SMQ040", "SMD093") ctabs <- function(i) { # 打印当前变量名 cat("\n---\n### 频数表:", i, "\n") # 即时打印频数表 print(freq(smk[[i]])) } # walk仅执行函数副作用,不会额外输出汇总结果 walk(vars, ctabs)
问题2:ctable显示占位符smk[,i]而非实际变量名
原因是直接用smk[,i]传入的是匿名向量,ctable无法识别原始变量名,通过dnn参数显式指定行列标签即可修复,同时用[[i]]索引避免tibble索引的维度问题:
ctabs2 <- function(i) { cat("\n---\n### 交叉表:", i, " × SMQ020\n") print(ctable( x = smk[[i]], y = smk[["SMQ020"]], chisq = TRUE, useNA = "no", # 自定义行列显示名称 dnn = c(i, "SMQ020") )) } walk(vars, ctabs2)
问题3:自有数据集提示列不存在报错
原因是部分数据结构(如tibble)用[,i]索引时默认返回1列的表格而非向量,ctable无法识别表格格式的输入,统一用[[i]]取列向量即可解决,也可以用smk[,i, drop = TRUE]实现等价效果。
可选替代方案(gmodels::CrossTable)
如果需要更轻量的实现,也可以用gmodels包的CrossTable,同样支持卡方检验、自定义排除NA:
library(gmodels) ctabs3 <- function(i) { cat("\n---\n### 交叉表:", i, " × SMQ020\n") CrossTable( x = smk[[i]], y = smk[["SMQ020"]], chisq = TRUE, missing.include = FALSE ) } walk(vars, ctabs3)
内容的提问来源于stack exchange,提问作者Maggie
相关产品推荐
相关产品推荐

