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

使用gtsummary生成配对Wilcoxon检验表格遇错误求助

问题解决:tbl_summary+add_p配对检验报错处理

问题背景

我想分析before和after两个观测点的变化,同时按condition的两组做比较,用了下面的代码:

Data %>% select(condition, before, after) %>%
  tbl_summary(by=condition) %>%
  add_p(test=everything()~"paired.wilcox.test")

但没得到预期的p值,反而抛出错误:

There was an error in 'add_p()/add_difference()' for variable 'before', p-value omitted:
Error: 'before': There may only be one observation per `group=` per `by=` level.
There was an error in 'add_p()/add_difference()' for variable 'after', p-value omitted:
Error: 'after': There may only be one observation per `group=` per `by=` level.

数据结构如下:

structure(list(condition = c(2, 2, 1, 2, 2, 1, 1, 2, 2, 2, 1, 
2, 2, 1, 2, 1, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 
2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 2, 
1, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 
2, 1), before= c(13, 7, 18, 18, 15, 5, 14, 5, 3, 6, 
18, 7, 5, 11, 6, 3, NA, 3, 11, 8, 10, 3, 7, 7, 12, 3, 5, 8, 4, 
9, 15, 9, 3, 16, 3, 3, 11, 3, 11, 8, 14, 21, 21, 17, 9, 3, 18, 
15, 6, 6, 12, 9, 15, 5, 13, 7, 6, 7, 9, 11, 21, 12, 7, 12, 6, 
21, 15, 21, 16, 12, 7, 18, 12, 20, 3, 10), after= c(15, 
3, 6, 18, 14, 15, 6, NA, 6, 3, 18, NA, 3, 15, NA, 15, 11, NA, 
10, 9, NA, 6, 6, 12, 3, NA, NA, 11, 9, 15, 21, 21, 6, 15, 9, 
16, 9, 11, 14, 13, 5, NA, 3, 10, NA, 3, 18, 12, NA, NA, 8, 11, 
14, NA, 13, NA, NA, 10, 6, 5, 15, 11, 12, NA, 5, NA, 15, 21, 
11, NA, 3, NA, 12, NA, 17, 15)), class = c("rowwise_df", "tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -76L), groups = structure(list(
    .rows = structure(list(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 
        10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 
        21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 
        32L, 33L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 
        43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 52L, 53L, 
        54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 
        65L, 66L, 67L, 68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 
        76L), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, -76L), class = c("tbl_df", 
"tbl", "data.frame"))

错误原因

paired.wilcox.test是配对检验,要求每个by组(即condition的1和2)内,每个配对组仅有一个观测。但你的数据是宽格式,before和after是同一行的两个变量,tbl_summary(by=condition)会把before和after当成独立变量分别按condition分组,此时用配对检验完全不符合逻辑——配对检验需要的是同一受试对象的前后测数据配对,而非把before和after分开做组间比较。

解决方法

要实现需求,需先把数据转成长格式,让每个观测点(before/after)作为单独行,同时保留受试对象ID(配对数据必须有ID对应前后测),再结合tbl_summary做配对检验。

方法一:长格式配对检验

# 取消行分组,添加受试对象ID
Data <- Data %>% ungroup() %>% mutate(ID = row_number())

# 宽格式转长格式
Data_long <- Data %>% 
  pivot_longer(cols = c(before, after), names_to = "time", values_to = "value")

# 生成统计表格并添加配对检验
Data_long %>%
  tbl_summary(
    by = condition,
    include = c(time, value),
    group = ID,  # 指定配对的受试对象ID
    statistic = value ~ "{median} ({p25}, {p75})"  # 非正态数据用中位数四分位数描述
  ) %>%
  add_p(
    test = value ~ "paired.wilcox.test",  # 对value变量用配对Wilcoxon检验
    group = ID  # 明确配对分组依据
  )

方法二:计算差值后做组间比较

如果只想比较两组的前后变化差异,可以先计算每组内before和after的差值,再用秩和检验比较两组差值的差异:

Data %>% ungroup() %>%
  mutate(diff = after - before) %>%  # 计算前后测差值
  select(condition, before, after, diff) %>%
  tbl_summary(by = condition) %>%
  add_p(
    test = list(before ~ "wilcox.test", after ~ "wilcox.test", diff ~ "wilcox.test")
  )

这种方法中,diff列代表每个受试对象的前后变化,通过比较两组diff的差异,就能实现“按condition两组比较before和after变化”的目的。

补充提示

  • 你的数据是rowwise_df,第一步必须用ungroup()取消行分组,否则后续操作会报错
  • 配对检验的核心是同一受试对象的重复测量,必须有ID来对应前后测关系,否则函数无法识别配对结构
  • 若数据中没有明确的受试对象ID,用行号作为ID是可行的,因为每行就是一个受试对象的前后测数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:32:10