循环中使用mapply触发‘condition has length >1’错误的解决咨询
问题
需求是优化代码并使用apply系列函数,尝试在循环中调用mapply实现批量处理,但运行报错。相关代码及错误如下:
循环代码:
for (ind in (ind2fix )) { ADPPK[,ind] = mapply(categorize_cov,value = ADPPK[,ind-4], low = ADPPK[,ind-2],high = ADPPK[,ind-1],doserec = ADPPK$EVID) }
自定义函数:
categorize_cov <- function(value, low, high, doserec) { if (doserec == 0) { if (value > high) return("HIGH") else if (value < low ) return("LOW") else return("NORMAL") } else { return(NA) } }
运行错误:
Error in if (value > high) return("HIGH") else if (value < low) return("LOW") else return("NORMAL") : the condition has length > 1
显式指定列名(如mapply(categorize_cov,value = ADPPK$GLU, low = ADPPK$GLUL,high = ADPPK$GLUH,doserec = ADPPK$EVID))可正常运行,但手动重复20次过于繁琐,需实现循环批量处理。
解决方法
错误根源
categorize_cov是标量函数,仅能处理单个值;if语句要求条件长度为1。当循环中用ADPPK[,ind-4]取列时,若ADPPK为tibble(而非普通数据框),该索引会返回tibble对象而非向量,导致mapply传递的参数是数据框而非单个元素,触发条件长度大于1的错误。而用$取列时,返回的是明确向量,mapply会逐个元素传递参数,函数可正常运行。
方案1:改用向量化函数(推荐)
将函数修改为支持向量输入的版本,无需依赖mapply,效率更高:
categorize_cov_vec <- function(value, low, high, doserec) { result <- rep(NA, length(value)) idx <- doserec == 0 result[idx] <- ifelse(value[idx] > high[idx], "HIGH", ifelse(value[idx] < low[idx], "LOW", "NORMAL")) return(result) }
循环调用该向量化函数:
for (ind in ind2fix) { ADPPK[, ind] <- categorize_cov_vec( value = ADPPK[, ind-4], low = ADPPK[, ind-2], high = ADPPK[, ind-1], doserec = ADPPK$EVID ) }
方案2:修复mapply的参数传递
若坚持使用原categorize_cov函数,将循环中的列索引改为[[(确保返回向量而非数据框):
for (ind in ind2fix) { ADPPK[, ind] <- mapply( categorize_cov, value = ADPPK[[ind-4]], low = ADPPK[[ind-2]], high = ADPPK[[ind-1]], doserec = ADPPK$EVID ) }
这样mapply会将每个向量的元素逐个传递给标量函数,if语句可正常执行。
内容的提问来源于stack exchange,提问作者TheCodeNovice
相关产品推荐
相关产品推荐

