在R中快速选择表格中的行的方法是什么?

7

我正在寻找一种快速的方法来从一个更大的表中提取大量的行。我的表的顶部如下所示:

> head(dbsnp)

      snp      gene distance
rs5   rs5     KRIT1        1
rs6   rs6   CYP51A1        1
rs7   rs7 LOC401387        1
rs8   rs8      CDK6        1
rs9   rs9      CDK6        1
rs10 rs10      CDK6        1

还有尺寸:

> dim(dbsnp)
[1] 11934948        3

我想选择那些行名包含在列表中的行:
> head(features)
[1] "rs1367830" "rs5915027" "rs2060113" "rs1594503" "rs1116848" "rs1835693"

> length(features)
[1] 915635

毫不奇怪,直接使用temptable = dbsnp[features,]的方法需要相当长的时间。

我一直在研究如何通过R中的sqldf包来完成。我认为这可能会更快。不幸的是,我无法弄清楚如何在SQL中选择特定行名称的行。

谢谢。


3
请查阅data.table包,您可以使用键来完成此操作。您的“行名称”是否与snp列相同? - Justin
是的,它们两个是一样的。我会研究 data.table。 - Gordon Freeman
1
只是出于兴趣,有人知道如果你首先使用像 foo<-rownames(dbsnp); bar<-which(foo%in%features,arr.ind=TRUE); temptable<-dbsnp[c(bar),] 这样的机制获取行号是否会有任何时间差异吗?(我知道这不是正确的R语法,但你明白我的意思)。 - Carl Witthoft
3个回答

10

data.table 的解法:

library(data.table)
dbsnp <- structure(list(snp = c("rs5", "rs6", "rs7", "rs8", "rs9", "rs10"
), gene = c("KRIT1", "CYP51A1", "LOC401387", "CDK6", "CDK6", 
"CDK6"), distance = c(1L, 1L, 1L, 1L, 1L, 1L)), .Names = c("snp", 
"gene", "distance"), class = "data.frame", row.names = c("rs5", 
"rs6", "rs7", "rs8", "rs9", "rs10"))

DT <- data.table(dbsnp, key='snp')
features <- c('rs5', 'rs7', 'rs9')
DT[features]

   snp      gene distance
1: rs5     KRIT1        1
2: rs7 LOC401387        1
3: rs9      CDK6        1

5

使用 sqldf 时,您需要设置 rownames = TRUE,然后可以使用 row_names 查询行名:

library(sqldf)

## input

test<-read.table(header=T,text="      snp      gene distance
rs5   rs5     KRIT1        1
rs6   rs6   CYP51A1        1
rs7   rs7 LOC401387        1
rs8   rs8      CDK6        1
rs9   rs9      CDK6        1
rs10 rs10      CDK6        1
")
features<-c("rs5","rs7","rs10")

## calculate

inVar <- toString(shQuote(features, type = "csh")) # 'rs5','rs7','rs10'

fn$sqldf("SELECT * FROM test t
          WHERE t.row_names IN ($inVar)"
           , row.names = TRUE)

## result
#      snp      gene distance
#rs5   rs5     KRIT1        1
#rs7   rs7 LOC401387        1
#rs10 rs10      CDK6        1

更新:或者,如果fet是一个数据框,其features列包含要查找的所需项目:
fet <- data.frame(features)
sqldf("SELECT t.* FROM test t
          WHERE t.row_names IN (SELECT features FROM fet)"
           , row.names = TRUE)

如果数据量足够大,我们可以使用索引来加快速度。有关此事和其他详细信息,请参见sqldf主页


4

大多数人最初尝试的方法是:

dbsnp[ rownames(dbsnp) %in% features, ]  # which is probably slower than your code

因为您说这需要很长时间,我怀疑您的 RAM 容量已经超过了限制,导致开始使用虚拟内存。您应该关闭系统,只运行 R 应用程序并尝试避免使用“虚拟内存”。


我尝试按照你建议的方式选择行。这样做速度快得多(我之前不知道可以从列表中使用%in%)。 - Gordon Freeman
从您所显示的内容来看,我认为这两个对象都是“原子向量”,而不是R中的“列表”。我承认有点惊讶它运行得更快。 - IRTFM
好的 - 我下次会记住这个区别。我实际上是从你在这里的帖子中学到了两者之间的区别:https://dev59.com/Q2oy5IYBdhLWcg3wYc8l - Gordon Freeman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接