在R的table1包中实现带抽样权重的分组统计自定义渲染
解决table1包自定义加权统计量的分组展示问题
核心问题分析
你的代码直接引用完整数据集计算统计量,忽略了table1分组时传递给渲染函数的x是当前分组的变量子集,导致所有组的结果完全一致,分组功能失效。
修正后的实现代码
首先加载所需依赖包:
library(table1) library(DescTools) library(e1071)
生成可复现的示例数据:
set.seed(123) dat1 <- data.frame( disease = factor(rbinom(100, 1, 0.2), labels = c("No", "Yes")), age = rnorm(100, 45, 15), sample.weight = rexp(100, 1), group = factor(rbinom(100, 1, 0.4), labels = c("Group 1", "Group 2")) )
自定义加权渲染函数:
my.render.with.weights <- function(x, name, weightsvar, ...) { # 获取当前分组在原数据中的行索引,提取对应权重 row_idx <- as.integer(attr(x, "row.names")) selected_weights <- dat1[[weightsvar]][row_idx] values <- x # x即为当前分组的变量值,无需从完整数据集提取 # 连续变量处理 if (is.numeric(values)) { # 计算当前分组的偏度 skwnss <- skewness(values, na.rm = TRUE) # 加权统计量计算 weightedmean <- round(weightedMean(values, weights = selected_weights, na.rm = TRUE), 2) weightedsd <- round(sqrt(wtd.var(values, weights = selected_weights, na.rm = TRUE)), 2) weightedmedian <- round(weightedMedian(values, weights = selected_weights, na.rm = TRUE), 2) weightedquantile <- round(weightedQuantile(values, weights = selected_weights, probs = c(0.25, 0.75), na.rm = TRUE), 2) # 根据偏度选择输出格式 out.skewed <- c("", `Median [Q1, Q3], weighted` = sprintf("%s [%s, %s]", weightedmedian, weightedquantile[1], weightedquantile[2])) out.not.skewed <- c("", `Mean (SD), weighted` = sprintf("%s (± %s)", weightedmean, weightedsd)) return(if (skwnss > 0.4) out.skewed else out.not.skewed) } else { # 分类变量处理 # 计算加权频数和百分比 weighted_freq <- tapply(selected_weights, values, function(w) round(sum(w, na.rm = TRUE), 1)) weighted_pct <- round(weighted_freq / sum(weighted_freq, na.rm = TRUE) * 100, 2) # 构建输出文本 out_categorical <- c("", paste0(names(weighted_freq), ": ", weighted_freq, " (", weighted_pct, "%)")) names(out_categorical) <- c("", names(weighted_freq)) # 二分类变量仅展示第二组结果(匹配table1默认逻辑) if (length(levels(values)) == 2) { return(out_categorical[3]) } else { return(out_categorical) } } }
调用table1生成分组加权统计表:
table1(~ age + disease | group, data = dat1, weightsvar = "sample.weight", render = my.render.with.weights)
关键修改点说明
- 基于分组子集计算:直接使用
x作为当前分组的变量值,替代原代码中从完整数据集提取的变量,确保统计量仅针对当前分组。 - 匹配分组权重:通过
attr(x, "row.names")获取当前分组在原数据中的行索引,提取对应行的抽样权重,保证权重与变量值一一对应。 - 修正偏度判断:偏度基于当前分组的变量值计算,而非整个数据集,确保偏度判断的准确性。
- 简化分类变量统计:用
tapply替代aggregate,更简洁地计算分组内的加权频数,避免层级混乱。
内容的提问来源于stack exchange,提问作者elebuzz
相关产品推荐
相关产品推荐

