R语言变异类型分类报错:if条件长度大于1的解决方法
解决变异类型分类的R代码报错问题
问题场景
输入示例
A T G C T AG C T TT C AT CC
对应数据结构
df = structure(c("A", "G", "T", "C", "TT", "AT", "T", "C", "AG", "T", "C", "CC"), dim = c(6L, 2L), dimnames = list(NULL, c("REF", "ALT"))) %>% as.data.frame()
分类规则
- 当
ALT长度与REF长度均为1时,标记为SNP; - 当
ALT长度等于REF长度(且长度大于1)时,标记为MNV; - 当
ALT长度小于REF长度时,标记为Deletion(缺失); - 当
REF长度小于ALT长度时,标记为Insertion(插入)。
期望输出
REF ALT VARIANTTYPE 1 A T SNP 2 G C SNP 3 T AG Insertion 4 C T SNP 5 TT C Deletion 6 AT CC MNV
错误代码与报错信息
用户尝试的代码
variants = data.frame( REF = file@fix[, 4], ALT = file@fix[, 5], VARIANTTYPE = if (nchar(file@fix[, 4]) == nchar(file@fix[, 5])) {ifelse(nchar(file@fix[, 4]) == 1 & nchar(file@fix[, 5]) == 1, "Single nucleotide variant", "Multinucleotide variant")} else if (nchar(file@fix[, 4]) < nchar(file@fix[, 5])) {"Insertion"} else if (nchar(file@fix[, 4]) > nchar(file@fix[, 5])) {"Deletion"} else {"nothing"})
报错信息
Error in if (nchar(file@fix[, 4]) == nchar(file@fix[, 5])) { : the condition has length > 1
问题原因
基础if语句只能处理长度为1的逻辑条件,但nchar()函数返回的是对应每一行的长度向量(长度大于1),直接用if判断会触发报错。
解决方案
方法1:嵌套ifelse实现向量式多条件判断
ifelse支持向量操作,可以嵌套实现多层逻辑判断:
# 先计算REF和ALT的长度向量 ref_len <- nchar(file@fix[, 4]) alt_len <- nchar(file@fix[, 5]) variants <- data.frame( REF = file@fix[, 4], ALT = file@fix[, 5], VARIANTTYPE = ifelse( # 第一层:判断长度是否相等 ref_len == alt_len, # 长度相等时,再判断是否为单碱基 ifelse(ref_len == 1, "SNP", "MNV"), # 长度不等时,判断插入/缺失 ifelse(ref_len < alt_len, "Insertion", "Deletion") ) )
方法2:用dplyr::case_when实现更清晰的多条件判断
如果使用dplyr包,case_when可以按顺序编写多条件规则,可读性更强:
library(dplyr) variants <- file@fix %>% as.data.frame() %>% # 提取REF和ALT列(对应原代码的第4、5列) select(REF = V4, ALT = V5) %>% mutate( ref_len = nchar(REF), alt_len = nchar(ALT), # 按规则依次判断 VARIANTTYPE = case_when( ref_len == alt_len & ref_len == 1 ~ "SNP", ref_len == alt_len ~ "MNV", ref_len < alt_len ~ "Insertion", ref_len > alt_len ~ "Deletion", # 兜底处理异常情况 TRUE ~ "Unknown" ) ) %>% # 移除中间计算的长度列 select(-ref_len, -alt_len)
测试验证
用提供的测试数据运行方法1,得到的结果与期望输出一致:
# 测试数据 df <- structure(c("A", "G", "T", "C", "TT", "AT", "T", "C", "AG", "T", "C", "CC"), dim = c(6L, 2L), dimnames = list(NULL, c("REF", "ALT"))) %>% as.data.frame() ref_len <- nchar(df$REF) alt_len <- nchar(df$ALT) df$VARIANTTYPE <- ifelse( ref_len == alt_len, ifelse(ref_len ==1, "SNP", "MNV"), ifelse(ref_len < alt_len, "Insertion", "Deletion") ) print(df)
输出:
REF ALT VARIANTTYPE 1 A T SNP 2 G C SNP 3 T AG Insertion 4 C T SNP 5 TT C Deletion 6 AT CC MNV
内容的提问来源于stack exchange,提问作者user25420086
相关产品推荐
相关产品推荐

