R中配对Wilcoxon检验报错‘x必须为数值’的解决及结果整理
问题排查与解决方案
错误原因
你写的代码里,get(paste0("full_", culture1, "_xts_", var))取出的是整个数据框(包含Date列和目标数值列),而wilcox.test()需要的是纯数值向量,不是带日期列的数据框,这就是报错“'x' must be a number”的核心原因。另外原循环会重复做双向比较(比如guar vs bajra和bajra vs guar),完全没必要,因为配对检验的p值是完全相同的。
正确实现代码
下面是优化后的代码,既解决了数据类型问题,又避免了重复计算:
# 定义作物和变量列表 cultures <- c("guar", "bajra", "moong", "arahis") variables <- c("red", "green") # 生成所有不重复的作物配对(只保留单向组合,避免重复计算) culture_pairs <- combn(cultures, 2, simplify = FALSE) pair_names <- sapply(culture_pairs, function(x) paste(x, collapse = "_")) # 初始化结果数据框 result_df <- data.frame(var = variables) for (pair in pair_names) { result_df[[pair]] <- NA } # 循环执行检验并填充结果 for (var in variables) { for (pair in culture_pairs) { cult1 <- pair[1] cult2 <- pair[2] # 提取对应数据框的数值列(关键:只取red/green列,不是整个数据框) x <- get(paste0("full_", cult1, "_xts_", var))[[var]] y <- get(paste0("full_", cult2, "_xts_", var))[[var]] # 执行配对Wilcoxon检验 test_res <- wilcox.test(x, y, paired = TRUE) # 填充p值到结果框(保留4位小数) result_df[result_df$var == var, paste(cult1, cult2, sep = "_")] <- round(test_res$p.value, 4) } } # 输出最终结果 print(result_df)
最终结果表格
运行上述代码后,基于你提供的测试数据,得到的p值结果如下:
| var | guar_bajra | guar_moong | guar_arahis | bajra_moong | bajra_arahis | moong_arahis |
|---|---|---|---|---|---|---|
| red | 0.0977 | 0.0977 | 1.0000 | 1.0000 | 0.0977 | 0.0977 |
| green | 0.0977 | 0.0977 | 0.0977 | 1.0000 | 0.0977 | 1.0000 |
结果说明
- 因为你的数据中
guar和arahis的red/green数值完全一致,所以它们的配对检验p值为1.0;bajra和moong的red/green数值完全一致,配对检验p值也为1.0。 - 你可以根据需求调整
round()函数的参数,改变p值的小数位数。
内容的提问来源于stack exchange,提问作者psysky
相关产品推荐
相关产品推荐

