使用tbl_summary生成2×2表后,如何通过卡方检验获取正确P值?
解决方案
你的需求是对分组求和后的2×2表做卡方检验并得到单个P值,当前add_p()会为每行生成P值,原因是tbl_summary()将correct_answers和incorrect_answers视为两个独立变量,而非组成列联表的两个类别。以下是两种可行的解决方法:
方法一:保留原汇总表样式,添加卡方P值
先手动计算分组求和后的列联表卡方检验结果,再将P值添加到原汇总表底部:
library(gtsummary) library(tidyverse) test <- data.frame("With_assistant" = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE), "correct_answers" = c(2,4,5,6,1,2,7,2,1,2,3), "incorrect_answers" = c(1,2,1,5,3,1,2,5,3,2,4)) # 1. 计算分组求和的2×2列联表,并做卡方检验 cross_tab <- test %>% group_by(With_assistant) %>% summarize(correct = sum(correct_answers), incorrect = sum(incorrect_answers)) chisq_result <- chisq.test(as.matrix(cross_tab[, -1])) # 2. 生成原汇总表并添加卡方P值 test %>% tbl_summary( by = With_assistant, type = list(c(correct_answers, incorrect_answers) ~ "continuous"), statistic = list(c(correct_answers, incorrect_answers) ~ "{sum}") ) %>% # 在表底添加卡方检验P值 add_stat( fns = ~ ifelse(.variable %in% c("correct_answers", "incorrect_answers"), paste("卡方检验P值:", round(chisq_result$p.value, 3)), NA), location = "bottom" ) %>% # 清理多余行 modify_table_body(~ .x %>% filter(!(row_type == "statistic" & is.na(label))) %>% distinct())
方法二:用tbl_cross()直接生成带卡方检验的列联表
将数据转换为适合列联表的长格式,使用tbl_cross()直接生成符合卡方检验要求的表格:
library(gtsummary) library(tidyverse) test <- data.frame("With_assistant" = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE), "correct_answers" = c(2,4,5,6,1,2,7,2,1,2,3), "incorrect_answers" = c(1,2,1,5,3,1,2,5,3,2,4)) # 将数据展开为每个答案条目单独一行的格式 test_long <- test %>% mutate(id = row_number()) %>% pivot_longer(cols = c(correct_answers, incorrect_answers), names_to = "answer_type", values_to = "count") %>% uncount(count) %>% mutate(answer_type = ifelse(answer_type == "correct_answers", "正确答案", "错误答案")) # 生成列联表并添加卡方检验P值 test_long %>% tbl_cross(row = answer_type, col = With_assistant) %>% add_p(test = ~ chisq.test(.))
两种方法的卡方检验结果一致,你可以根据需要选择表格样式。
内容的提问来源于stack exchange,提问作者MegStats
相关产品推荐
相关产品推荐

