如何用strsplit基于行名筛选DataFrame?报错解决方案咨询
按行名中的基因ID筛选DataFrame行的解决方案
问题说明
现有如下结构的DataFrame:
dput(gene_exp[1:5,1:5]) structure(list(en_Adipose_Subcutaneous.db = c(0.0531016390078734, -0.00413407782001034, -0.035434632568444, 0.00968736935965742, 0.0523714252287003), en_Adipose_Visceral_Omentum.db = c(0, 0, 0, 0, 0), en_Adrenal_Gland.db = c(0, 0, 0, 0, 0), en_Artery_Aorta.db = c(0, 0, 0, 0, 0), en_Artery_Coronary.db = c(0, 0, 0, 0, 0)), row.names = c("rs1041770_ENSG00000283633.1", "rs12628452_ENSG00000283633.1", "rs915675_ENSG00000283633.1", "rs11089130_ENSG00000283633.1", "rs36061596_ENSG00000283633.1"), class = "data.frame")
需求是筛选出行名中包含基因ID ENSG00000283633.1 的行,编写的代码出现报错:
gene <- gene_exp %>% filter(unlist(strsplit(rownames(gene_exp), "_")) %in% "ENSG00000283633.1")
报错信息:
Error in `filter()`: ℹ In argument: `unlist(strsplit(rownames(gene_exp), "_")) %in% "ENSG00000283633.1"`. Caused by error: ! `..1` must be of size 5956 or 1, not size 11902. Run `rlang::last_trace()` to see where the error occurred.
错误原因
strsplit(rownames(gene_exp), "_")会将每个行名拆分为两个元素(如rs1041770和ENSG00000283633.1),unlist后得到的向量长度是原DataFrame行数的2倍,而filter要求传入的逻辑向量长度必须与DataFrame行数一致,因此维度不匹配导致报错。
解决方法
方法1:将行名转为列后筛选(dplyr风格)
将行名转为单独的列,筛选完成后可选择重新设为行名:
library(dplyr) gene <- gene_exp %>% tibble::rownames_to_column("row_id") %>% filter(grepl("ENSG00000283633.1", row_id)) %>% tibble::column_to_rownames("row_id")
方法2:直接基于行名生成逻辑向量
方式A:用grepl直接匹配行名
最简洁的基础R写法:
gene <- gene_exp[grepl("ENSG00000283633.1", rownames(gene_exp)), ]
方式B:拆分后判断每个行名是否包含目标ID
通过sapply对每个拆分后的行名列表进行判断:
gene <- gene_exp[sapply(strsplit(rownames(gene_exp), "_"), function(x) "ENSG00000283633.1" %in% x), ]
方法3:使用stringr包的字符串检测函数
借助stringr的str_detect函数实现更直观的筛选:
library(stringr) gene <- gene_exp %>% filter(str_detect(rownames(.), "ENSG00000283633.1"))
内容的提问来源于stack exchange,提问作者rheabedi1
相关产品推荐
相关产品推荐

