两类合并样本响应类别统计差异检验:tidy方法实现问询
问题描述
需要检验第1年(Y1)与第2年(Y2)各响应类别(0至10及NA)的差异是否具有统计学意义。已生成包含各年度百分比及差值的表格dist3:
dist3<- tibble::tribble( ~`DV`,~`Y1`, ~`Y2`, ~ `Difference`, "0", 8.21, 11.34, 8.21 - 11.34, "1", 3.05, 4.46,3.05 - 4.46, "2", 5.82, 7.41, 5.82 - 7.41, "3", 7.64,8.91, 7.64-8.91, "4", 6.60, 7.28, 6.60-7.28, "5", 20.89, 18.30, 20.89-18.30, "6", 7.56, 7.66, 7.56-7.66, "7", 9.34, 8.58, 9.34-8.58, "8", 7.86,6.69, 7.86-6.69, "9", 3.17, 3.16, 3.17-3.16, "10", 13.40, 11.18, 13.40-11.18, "NA", 6.46, 5.03, 6.46-5.03, "Total", 100, 100, 100.00-100.00)
咨询以下问题:
- 是否可通过tidy风格的
map函数自动筛选每个DV类别并执行t.test? - 能否通过
mutate%>%case_when追加检验结果,还是必须手动编写代码?
解决方案
关于map函数自动执行t.test
完全可以用tidy风格的map实现,但前提是你得有原始个体级数据——仅靠dist3里的百分比无法做t检验,因为t.test需要原始观测值计算标准误、自由度等统计量。
假设你有原始数据框raw_data(每行对应一个样本,包含DV类别、Y1和Y2的观测值),可以按DV分组后用map批量执行检验:
library(tidyverse) library(broom) # 按DV分组嵌套数据,批量执行配对t检验(参数可根据实际调整) test_results <- raw_data %>% filter(DV != "Total") %>% group_by(DV) %>% nest() %>% mutate( test = map(data, ~t.test(.x$Y1, .x$Y2, paired = TRUE)), test_tidy = map(test, tidy) ) %>% unnest(test_tidy) %>% select(DV, estimate, statistic, p.value, conf.low, conf.high)
用broom::tidy()能把t检验结果转换成整洁的数据框,方便和dist3合并。
如果只有百分比数据,那应该用**比例检验(prop.test)**替代t检验,同样可以用map批量处理:
# 假设Y1和Y2的总样本量分别为n1、n2,替换为实际值 n1 <- 1000 n2 <- 1000 dist3_with_prop_test <- dist3 %>% filter(DV != "Total") %>% mutate( count1 = Y1 / 100 * n1, count2 = Y2 / 100 * n2, test = map2(count1, count2, ~prop.test(c(.x, .y), c(n1, n2))), test_tidy = map(test, tidy) ) %>% unnest(test_tidy) %>% select(DV, Y1, Y2, Difference, p.value, conf.low, conf.high)
关于mutate%>%case_when追加结果
case_when是基于已有列的条件判断生成新列,不适合批量追加检验结果——每个DV类别的检验结果是独立计算的,不是简单的条件映射。
正确做法是把map生成的检验结果表,和原dist3做左连接来合并信息:
dist3_with_test <- dist3 %>% filter(DV != "Total") %>% left_join(test_results, by = "DV")
总结
- 有原始数据:用
group_by+nest+map批量执行t.test,再合并到原表,无需手动编写每个类别的代码。 - 仅含百分比:用
prop.test替代t.test,同样可通过map批量处理。 case_when不适用于这个场景,合并表格是更高效的方式。
内容的提问来源于stack exchange,提问作者ibm
相关产品推荐
相关产品推荐

