You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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)

关键修改点说明

  1. 基于分组子集计算:直接使用x作为当前分组的变量值,替代原代码中从完整数据集提取的变量,确保统计量仅针对当前分组。
  2. 匹配分组权重:通过attr(x, "row.names")获取当前分组在原数据中的行索引,提取对应行的抽样权重,保证权重与变量值一一对应。
  3. 修正偏度判断:偏度基于当前分组的变量值计算,而非整个数据集,确保偏度判断的准确性。
  4. 简化分类变量统计:用tapply替代aggregate,更简洁地计算分组内的加权频数,避免层级混乱。

内容的提问来源于stack exchange,提问作者elebuzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:16:11