基于分组列对两列执行t.test/wilcox.test的R脚本问题
解决分组配对检验的问题
首先,你之前代码的核心问题是:在by函数的匿名函数里,你直接使用了data1[,2]和data1[,3],这是整个数据集的两列,而不是当前分组对应的子集,所以所有分组返回的都是同一个检验结果。我们需要针对每个分组的子集来做检验。
接下来,我们实现一个完整的流程:按moda分组,先检验差值的正态性(Shapiro检验),再根据结果选择配对t检验或Wilcoxon配对秩和检验,最后输出每个分组的详细结果。
步骤1:加载数据
首先把你的数据加载到R中:
data1 <- structure(list(moda = structure(c(20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 16L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 22L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 23L, 23L), .Label = c("ACN1", "ACN2", "BA", "BM", "BS1", "BS2", "CN", "EK5", "HW1", "HW2", "HW3", "L27", "L5K", "LC", "M2K", "M630", "PB1", "PB2", "PB3", "PG", "RMB", "RMC", "RMM"), class = "factor"), epicotyle = c(1.5, 1.5, 2, 1, 1.5, 1.2, 1, 2.4, 1.3, 1.4, 1.7, 2, 1.8, 2.3, 2.5, 2.5, 1.5, 1.5, 2, 1.3, 1.5, 1.8, 1.3, 1.8, 1.7, 1.5, 2.3, 1.8, 2.2, 1.5, 1.5, 1.5, 1.3, 1.5, 1.5, 1.5, 1.5, 1.8, 1.5, 2.1, 1.8, 1.3, 2, 1.5, 2, 3.5, 1.5, 1.7, 1.7, 2, 1.7, 2, 1.5, 2, 1.5, 2, 2, 1.5, 2, 1.5, 1.8, 1, 2, 3, 1.6, 1.5, 1.5, 1.3, 1.5, 1.5, 1.2, 1.5, 1.5, 1, 1.2, 1.5, 1.5, 1.5, 1.5, 2, 1.1, 1.5, 1.5, 1.7, 1.8, 1.5, 1.3, 1.5, 1.5, 2.5, 1.2, 1.4, 1, 1.5, 2, 1.5, 1.2, 1.5, 2, 2.3, 2.1, 2, 2.4, 1.5, 1.7, 1.4, 2.4, 1, 1, 2, 1.5, 1.2, 2.4, 1.2, 1, 0.8, 1.8, 1.5, 1.5, 2, 1, 1.5, 1.2, 1, 2.4, 1.3, 1.4, 1.5, 1.5, 1.5, 2.1, 1.5, 1.4, 1.5, 1.3, 1.5, 3, 2.6, 1.5, 2.2, 1.9, 1.5, 1.4, 1.4, 2.5, 2.1, 2, 1.5, 2, 2, 2, 1.5, 2.1, 2, 1.5, 2.5, 2.5, 3, 3, 3.5, 3.5, 3, 2, 2.5, 3.5, 1, 1.2, 1.5, 2.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.4, 1.5, 2, 3, 1.7, 3, 2.5, 2, 2.5, 2.5, 2.5, 1.5, 1.5, 1.5, 1, 1.5, 2, 1.4, 1.2, 1.7, 2.1, 1.5, 2, 1.5, 1.5, 2, 1.4, 2, 3, 2, 2, 1.5, 1.5, 2, 1, 1.5, 1.2, 1, 2.4, 1.3, 1.4, 2, 2.5, 3, 3, 1.7, 3, 1.8, 2, 1.8, 2.2, 2.3, 1.5, 2, 1.8, 1.8, 1.3, 2, 1.8, 1.8, 2, 1.8, 1.5, 1.7, 2, 1.4, 1.5, 1.7, 1.5), hypocotyle = c(1.5, 1.5, 2, 1, 1.5, 1.2, 1, 2.4, 1.3, 1.4, 5, 7, 2.5, 6.5, 5.4, 5, 6, 5.7, 7, 5.5, 5.7, 5.5, 7, 6.5, 5.5, 5.5, 6.7, 4.9, 5.3, 6.7, 5.8, 6.5, 6, 5.6, 5, 5.5, 6, 6, 6, 3.5, 4.7, 4.5, 5.9, 5, 6, 7, 6, 5.5, 5, 5.8, 5.5, 5.5, 4.8, 5.7, 6, 7, 5.2, 5, 5.2, 5.3, 5.6, 5, 5.3, 6, 5, 5.5, 4.5, 5.7, 6, 4.5, 4.4, 5.2, 5.2, 4.1, 5.2, 5.2, 5.4, 6, 5.5, 6.5, 5, 6, 5.5, 7.5, 5.2, 5.6, 5.4, 5.5, 5, 5, 6, 5.2, 6, 6.3, 6.3, 4.2, 5.1, 3.5, 6, 6, 6, 6, 5, 5, 6, 5, 5.6, 5.5, 5, 5, 6, 5.2, 6, 6.3, 6.3, 4.2, 5.1, 3.8, 4, 7, 5, 6, 4, 5.4, 3.5, 3.6, 5, 6, 4.8, 4.7, 4.4, 5.5, 3.5, 5.3, 4.3, 5.5, 4.5, 5.5, 4.2, 6, 4.3, 4, 4.7, 3.5, 3.7, 4.2, 5, 5, 5.1, 5.7, 5, 3.5, 4, 5.6, 3.9, 3.5, 7, 6, 6, 6, 6.5, 5.5, 4.5, 6.5, 6.5, 3, 5, 5.5, 5.3, 4, 5.5, 6, 4, 5.5, 6, 5, 4, 4.5, 4.5, 4, 3.5, 4.5, 5, 4, 4.5, 5, 4.7, 6, 3.8, 4.5, 4.1, 4, 3.7, 4, 4.5, 5, 6, 4.5, 6, 5.7, 3.7, 5.8, 6.2, 5.5, 5, 3.8, 4, 7, 5, 6, 4, 5.4, 3.5, 3.6, 5, 7, 6.5, 8, 6.5, 5.7, 7.5, 7.3, 7.4, 7, 5.4, 6.5, 6.5, 7.2, 7.4, 6, 6.5, 6, 7, 6, 7, 6.5, 6.5, 6.5, 8, 5.7, 6.5, 6, 7)), class = "data.frame", row.names = c(NA, -243L ))
步骤2:编写分组检验函数
我们定义一个函数grouped_paired_test,输入是每组的数据集,完成以下操作:
- 计算
hypocotyle和epicotyle的差值(配对检验关注的是差值的分布) - 做Shapiro-Wilk检验,判断差值是否符合正态分布
- 根据正态性检验结果,选择配对t检验或Wilcoxon配对秩和检验
- 返回包含所有关键结果的列表
grouped_paired_test <- function(group_data) { # 计算配对差值 diff_vals <- group_data$hypocotyle - group_data$epicotyle # Shapiro-Wilk检验:判断差值的正态性 shapiro_result <- shapiro.test(diff_vals) shapiro_p <- shapiro_result$p.value # 根据正态性选择检验方法 if (shapiro_p > 0.05) { # 正态分布:配对t检验 test_result <- t.test(group_data$epicotyle, group_data$hypocotyle, paired = TRUE) test_type <- "Paired t-test" } else { # 非正态分布:Wilcoxon配对秩和检验 test_result <- wilcox.test(group_data$epicotyle, group_data$hypocotyle, paired = TRUE) test_type <- "Wilcoxon paired test" } # 整理结果 list( shapiro_p = round(shapiro_p, 4), test_type = test_type, test_p = round(test_result$p.value, 4), test_stat = round(test_result$statistic, 4) ) }
步骤3:按分组应用函数
使用by函数按moda分组,对每个分组应用上面的函数:
# 按moda分组执行检验 test_results <- by(data1, data1$moda, grouped_paired_test) # 将结果转换为数据框,方便查看 results_df <- do.call(rbind, lapply(test_results, function(x) as.data.frame(x))) results_df$moda <- rownames(results_df) rownames(results_df) <- NULL # 调整列顺序 results_df <- results_df[, c("moda", "shapiro_p", "test_type", "test_stat", "test_p")] # 查看结果 print(results_df)
相关产品推荐
相关产品推荐

