R遍历data.frame行调用自定义if-else函数apply/sapply报错如何解决
报错原因分析
apply报错原因:apply处理data.frame按行遍历时,会将每行转换为同类型向量,你的数据包含字符列(seqnames、strand),因此所有数值列(start、end)会被强制转为字符型,做加减运算时就会触发非数值参数报错。sapply报错原因:sapply传入data.frame时默认按列遍历,每次传给函数的是单独一列数据,根本不存在strand字段,判断条件返回NA,自然报错缺失TRUE/FALSE值。- 你的问题确实包含函数未向量化的问题,同时存在遍历函数选择错误、自定义函数无返回值的问题。
解决方案
最优方案:直接向量化操作(无需遍历)
R中优先用向量化操作替代循环/遍历,性能更高且代码简洁:
# 处理正链:start+100赋值给end example$end <- ifelse(example$strand == "+", example$start + 100, example$end) # 处理负链:end-100赋值给start example$start <- ifelse(example$strand == "-", example$end - 100, example$start)
方案2:如果需要保留自定义函数逻辑
可以使用dplyr的rowwise按行处理,同时修改函数补充返回值:
library(dplyr) # 修改自定义函数,补充返回值 extension <- function(peak_row) { peak_row <- as.list(peak_row) # 转为列表避免类型强制转换 if(peak_row$strand == '+'){ peak_row$end = peak_row$start + 100 } else if (peak_row$strand == '-') { peak_row$start = peak_row$end - 100 } return(as.data.frame(peak_row)) } # 按行调用函数 result <- example %>% rowwise() %>% group_modify(~extension(.x)) %>% ungroup()
运行后得到的结果符合预期:
seqnames start end width strand <chr> <dbl> <dbl> <int> <chr> 1 chr1 14660 14760 77 + 2 chr1 661861 661961 69 + 3 chr1 662314 662414 55 - 4 chr1 700226 700326 111 - 5 chr1 703330 703430 72 - 6 chr1 713295 713395 76 -
内容的提问来源于stack exchange,提问作者moth
相关产品推荐
相关产品推荐

