如何在 gtsummary table 中使用 McNemar 检验?

How to use McNemar's test in gtsummary table?

我有一个纵向数据框,其中记录了接种疫苗前后的一些患者症状。我正在使用 gtsummary 创建摘要 table 并进行 McNemar's 测试。 McNemar 的测试结果不正确,因为 gtsummary 没有给出疫苗接种前后的交叉表 (2X2)。这是我使用的代码

trial_paired %>%
  
  filter(complete.cases(.)) %>%

  group_by(id) %>%
  filter(n() == 2) %>%
  ungroup() %>%

  tbl_summary(type = list(c(Pain, Redness, Swelling, Tiredness, Headache, Muscle, Chills, Fever, Nausea, JointPain, `Allergic reaction`) ~ "categorical"),by = visit, include = -id) %>%
  add_p(test = list( c(Pain, Redness, Swelling, Tiredness, Headache, Muscle, Chills, Fever, Nausea, JointPain, `Allergic reaction`) ~ "mcnemar.test"), 
        group = id)

这是我得到的不正确的输出。

有人可以帮忙吗

以下是示例数据

structure(list(visit = c("1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", 
"1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", 
"2"), Pain = c("No", "No", "Yes", "Yes", "No", "No", "Yes", "Yes", 
"Yes", "No", "No", "Yes", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "Yes", "No", "No", "Yes", "No", 
"No", "No", "No", "No", "No", "Yes", "No", "No", "Yes", "No", 
"No", "No", "No", "Yes", "No", "No", "No", "No", "No", "No", 
"Yes", "No", "Yes", "No", "Yes", "Yes", "Yes", "Yes", "Yes", 
"No", "No", "No", "No", "No", "No", "Yes", "No", "No", "No", 
"No", "No", "No", "Yes", "No", "Yes", "Yes", "No", "No", "Yes", 
"No", "Yes", "Yes", "Yes", "No", "No", "No", "No", "No", "Yes", 
"No", "Yes", "Yes", "Yes", "No", "Yes", "No", "Yes", "No", "Yes", 
"Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", 
"No", "No", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "No", "No", 
"No", "No", "Yes", "Yes", "Yes", "Yes", "No", "No", "No", "No", 
"Yes", "No", "No", "No", "No", "No", "No", "No", "Yes", "Yes", 
"Yes", "Yes", "Yes", "Yes", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "Yes", "Yes", "No", "Yes", "No", "No", 
"Yes", "Yes", "No", "No", "Yes", "Yes", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "Yes", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "Yes", "Yes", "No", "Yes"), Redness = c("No", "No", 
"No", "Yes", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"Yes", "No", "No", "No", "No", "Yes", "Yes", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "Yes", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "Yes", "Yes", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No"), Swelling = c("No", 
"No", "No", "No", "No", "No", "No", "No", "Yes", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "Yes", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "Yes", "Yes", "No", "No", 
"No", "No", "No", "No", "No", "No", "Yes", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "Yes", "Yes", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No"), 
    Chills = c("No", "No", "Yes", "Yes", "No", "No", "No", "No", 
    "No", "Yes", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "Yes", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "Yes", 
    "No", "No", "No", "No", "No", "No", "No", "Yes", "No", "No", 
    "No", "No", "No", "No", "No", "Yes", "No", "No", "No", "No", 
    "No", "No", "Yes", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "Yes", "Yes", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "Yes", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", 
    "No", "No", "No", "No", "No", "No", "No", "Yes", "No", "No", 
    "Yes", "No", "No", "No", "No", "No")), row.names = c(NA, 
-204L), class = c("tbl_df", "tbl", "data.frame"))

{gtsummary} 包要求配对数据采用长格式(每个 ID 2 个观察值),您应该使用 gtsummary v1.5.0(预期的数据结构已在该版本中更新)。

library(gtsummary)
#> #Uighur
library(tidyverse)
packageVersion("gtsummary")
#> [1] '1.5.0'

# adding a patient ID to the data
df <- 
  df %>% 
  select(visit, Pain, Chills) %>%
  filter(complete.cases(.)) %>%
  group_by(visit) %>%
  mutate(id = row_number(), .before = 1) %>%
  group_by(id) %>%
  filter(n() == 2) %>%
  ungroup()

# creating summary table with McNemars test
tbl <-
  df %>% 
  tbl_summary(
    type = all_dichotomous() ~ "categorical",
    by = visit,
    include = -id
  ) %>%
  add_p(test = everything() ~ "mcnemar.test", group = id)

reprex package (v2.0.1)

创建于 2022-01-03