循环执行Chi square test检验基因型p值时遇报错求修正
解决卡方检验循环中的"至少一个entry为正"错误
首先,这个报错的原因很明确:当你执行chisq.test()时,传入的observed向量里存在**全0、至少一个元素非正(比如0或NA)**的情况,卡方检验无法对这类无效数据进行计算。结合你的代码来看,还有几个变量名和逻辑上的小问题,我帮你一步步修正:
1. 先梳理代码里的问题点
- 变量名混乱:你初始化的是
aaxab.res,但循环里却用了abxaa.res来拼接,这会触发未定义变量的错误 T.value是未定义的变量,你应该是想判断卡方检验返回的p值是否为NA- 用
c()循环累加结果效率很低,更推荐直接初始化一个长度匹配的数值向量 - 没有提前处理观测值无效的情况(比如全0)
2. 修正后的代码
# 初始化结果向量,长度和gt一致,避免循环累加的低效问题 aaxab.res <- numeric(length(gt)) for (i in 1:length(gt)) { observed <- c(aa.count[i], ab.count[i]) # 先检查观测值是否有效:至少有一个正数,且没有NA if (all(observed >= 0) && sum(observed) > 0) { # 执行卡方检验,设置correct=TRUE(默认)处理小样本,同时捕获可能的NA chisq_result <- suppressWarnings(chisq.test(observed, p = c(0.5, 0.5))) p.value <- chisq_result$p.value # 如果p值是NA(比如期望频数太小),手动保留NA标记 p.value <- ifelse(is.na(p.value), NA, p.value) } else { # 如果观测值无效,直接标记为NA p.value <- NA } # 将结果存入对应位置 aaxab.res[i] <- p.value }
3. 关键改进说明
- 有效性检查:在执行卡方检验前先判断
observed是否合法,从根源避免触发报错 suppressWarnings:当观测值很小(比如其中一个是1),卡方检验会抛出"Chi-squared approximation may be incorrect"的警告,用这个函数可以屏蔽无关警告(如果需要保留警告可以去掉)- 结果存储:直接给向量的对应位置赋值,比循环用
c()拼接高效得多,也避免了变量名错误 - NA处理:明确处理p值为NA的情况,让结果更清晰
额外建议
如果你想更简洁地实现这个功能,可以不用for循环,改用purrr包的map_dbl函数,代码会更简洁:
library(purrr) aaxab.res <- map_dbl(1:length(gt), function(i) { observed <- c(aa.count[i], ab.count[i]) if (all(observed >=0) && sum(observed) >0) { suppressWarnings(chisq.test(observed, p=c(0.5,0.5))$p.value) } else { NA_real_ } })
内容的提问来源于stack exchange,提问作者sailajah vishwanathan
相关产品推荐
相关产品推荐

