在R中使用rbind函数时重复添加行的问题求助
问题描述
我有一个R数据框,结构如下:
dput(trans_eqtl[1:5,1:6]) structure(list(Gene = c("ENSG00000166086", "ENSG00000166086", "ENSG00000265688", "ENSG00000265688", "ENSG00000265688"), `Gene-Chr` = c(11, 11, 17, 17, 17), `Gene-Pos` = c(133980358, 133980358, 79887167, 79887167, 79887167), RsId = c("rs3811444", "rs35340377", "rs705705", "rs1131017", "rs10876864"), `SNP-Chr` = c(1, 1, 12, 12, 12), `SNP-Pos` = c(248039451, 248038210, 56435504, 56435929, 56401085 )), row.names = c(NA, 5L), class = "data.frame")
我需要判断Gene-Chr和SNP-Chr是否属于同一条染色体,编写了循环代码,用rbind将符合条件的行存入inter和intra变量,但结果里出现大量重复行。
我的代码如下:
##check for intra and inter chrom: ##intra: inter <- NULL intra <- NULL for(i in 1:240){ if(!(trans_eqtl$`Gene-Chr`[i] %in% trans_eqtl$`SNP-Chr`[i])){ x <- which(!(trans_eqtl$`Gene-Chr`[i] %in% trans_eqtl$`SNP-Chr`[i]==TRUE)) value <- trans_eqtl[x,] } inter <- rbind(inter,value) } ##check for intra: for(i in 1:240){ if(trans_eqtl$`Gene-Chr`[i] %in% trans_eqtl$`SNP-Chr`[i]){ y <- which((trans_eqtl$`Gene-Chr`[i] %in% trans_eqtl$`SNP-Chr`[i]==TRUE)) value1 <- trans_eqtl[y,] } intra <- rbind(intra,value1) }
输出的intra和inter都有重复行,示例:
dput(intra[1:5,1:6]) structure(list(Gene = c("ENSG00000166086", "ENSG00000166086", "ENSG00000166086", "ENSG00000166086", "ENSG00000166086"), `Gene-Chr` = c(11, 11, 11, 11, 11), `Gene-Pos` = c(133980358, 133980358, 133980358, 133980358, 133980358), RsId = c("rs3811444", "rs3811444", "rs3811444", "rs3811444", "rs3811444"), `SNP-Chr` = c(1, 1, 1, 1, 1), `SNP-Pos` = c(248039451, 248039451, 248039451, 248039451, 248039451)), row.names = c(NA, 5L), class = "data.frame") dput(inter[1:5,1:6]) structure(list(Gene = c("ENSG00000166086", "ENSG00000166086", "ENSG00000166086", "ENSG00000166086", "ENSG00000166086"), `Gene-Chr` = c(11, 11, 11, 11, 11), `Gene-Pos` = c(133980358, 133980358, 133980358, 133980358, 133980358), RsId = c("rs3811444", "rs3811444", "rs3811444", "rs3811444", "rs3811444"), `SNP-Chr` = c(1, 1, 1, 1, 1), `SNP-Pos` = c(248039451, 248039451, 248039451, 248039451, 248039451)), row.names = c(NA, 5L), class = "data.frame")
错误原因分析
- 循环逻辑错误:每次用
which时,错误地返回了所有满足条件的行索引,而非当前行。循环240次就会把符合条件的行重复添加240次。 - rbind位置错误:
rbind放在循环的每次迭代中,不管if条件是否满足都会执行。若某次循环未进入if,value会保留上一次的值,导致重复添加。
解决方法
方法1:向量化筛选(推荐,R高效操作方式)
R的核心优势是向量化运算,无需循环即可完成筛选:
# 生成同/异染色体的判断条件 is_intra <- trans_eqtl$`Gene-Chr` == trans_eqtl$`SNP-Chr` # 分别筛选结果 intra <- trans_eqtl[is_intra, ] inter <- trans_eqtl[!is_intra, ]
方法2:修正循环写法(若需保留循环逻辑)
调整循环逻辑,仅处理当前行,且仅在条件满足时添加:
inter <- NULL intra <- NULL # 用nrow代替固定值240,适配任意数据量 for(i in 1:nrow(trans_eqtl)){ gene_chr <- trans_eqtl$`Gene-Chr`[i] snp_chr <- trans_eqtl$`SNP-Chr`[i] if(gene_chr != snp_chr){ inter <- rbind(inter, trans_eqtl[i, ]) } else { intra <- rbind(intra, trans_eqtl[i, ]) } }
注意:循环中多次
rbind效率较低,数据量大时建议预先分配空间,或优先使用向量化方法。
验证结果
运行上述代码后,intra和inter将正确筛选出对应行,不会出现重复。
内容的提问来源于stack exchange,提问作者rheabedi1
相关产品推荐
相关产品推荐

