调用epiR::epi.conf出现tmp.dat下标越界错误求助
问题排查:R循环报错
subscript out of bounds 报错信息
Error in tmp.dat[, 2] : subscript out of bounds
未手动定义过tmp.dat对象,运行以下代码时触发该错误:
for (ii in 1:dim(mytable)[1]) { mytable[ii,c("X95.Low","X95.High")] <- (epiR::epi.conf(cbind(mytable[ii,"Yes"],mytable[ii,"No"]), ctype="prop.single")[c(3,4)])*100 }
mytable结构截图:
问题根源
tmp.dat是epiR::epi.conf()函数内部生成的临时对象,报错说明该内部对象下标越界。结合你提供的mytable截图,原因是部分行的Yes或No列存在0值,导致epi.conf()计算置信区间时,内部处理临时数据的逻辑失效,触发下标错误。
解决方案
方案1:提前过滤无效行
先移除Yes和No同时为0(或其中一个为0,按需调整)的行,再运行循环:
# 保留Yes和No均大于0的行 mytable_clean <- mytable[mytable$Yes > 0 & mytable$No > 0, ] # 对清理后的表执行循环 for (ii in 1:dim(mytable_clean)[1]) { mytable_clean[ii,c("X95.Low","X95.High")] <- (epiR::epi.conf(cbind(mytable_clean[ii,"Yes"],mytable_clean[ii,"No"]), ctype="prop.single")[c(3,4)])*100 }
方案2:循环内增加判断逻辑
不删除行,在循环中跳过无法计算的行并标记:
for (ii in 1:dim(mytable)[1]) { yes_val <- mytable[ii,"Yes"] no_val <- mytable[ii,"No"] # 仅当两个值均大于0时计算置信区间 if (yes_val > 0 & no_val > 0) { mytable[ii,c("X95.Low","X95.High")] <- (epiR::epi.conf(cbind(yes_val, no_val), ctype="prop.single")[c(3,4)])*100 } else { # 无效行赋值NA作为标记 mytable[ii,c("X95.Low","X95.High")] <- NA } }
方案3:用向量化操作替代循环(更高效)
使用apply函数批量处理,避免循环冗余:
calc_ci <- function(row) { yes <- row["Yes"] no <- row["No"] if (yes > 0 & no > 0) { ci <- epiR::epi.conf(cbind(yes, no), ctype="prop.single")[c(3,4)] * 100 return(ci) } else { return(c(NA, NA)) } } # 将函数应用到mytable的每一行 mytable[, c("X95.Low", "X95.High")] <- t(apply(mytable, 1, calc_ci))
内容的提问来源于stack exchange,提问作者Rach
相关产品推荐
相关产品推荐

