R真的很慢矩阵/ data.frame索引选择

时间:2013-01-17 22:19:20

标签: r matrix dataframe

我正在选择data.frame g.raw的子集,如下所示:

g.raw <- read.table(gfile,sep=',', header=F, row.names=1) 
snps = intersect(row.names(na.omit(csnp.raw)),row.names(na.omit(esnp.raw))) 
g = g.raw[snps,] 

有效。但是,最后一行非常慢。

g.raw约为18M行,snps约为1M。我意识到这些是非常大的数字,但这看起来像一个简单的操作,并将g读入内存中保存的矩阵/ data.frame不是问题(花了几分钟),而我上面描述的这个操作正在采取小时。

如何加快速度?我想要的只是缩小g.raw。

谢谢!

2 个答案:

答案 0 :(得分:5)

似乎data.table可以发光。

重现data.frame

set.seed(1)
N <- 1e6    # total number of rows
M <- 1e5    # number of rows to subset

g.raw <- data.frame(sample(1:N, N), sample(1:N, N), sample(1:N, N))
rownames(g.raw) <- sapply(1:N, function(x) paste(sample(letters, 50, replace=T), collapse=""))
snps <- sample(rownames(g.raw), M)

head(g.raw) # looking into newly created data.frame
head(snps)  # and rows for subsetting

data.frame方法:

system.time(g <- g.raw[snps,])
# >    user  system elapsed 
# > 881.039   0.388 884.821 

data.table方法:

require(data.table)
dt.raw <- as.data.table(g.raw, keep.rownames=T)
# rn is a column with rownames(g.raw)
system.time(setkey(dt.raw, rn))
# >  user  system elapsed 
# > 8.029   0.004   8.046 

system.time(dt <- dt.raw[snps,])
# >  user  system elapsed 
# > 0.428   0.000   0.429 

使用这些NM,速度提高了100倍(甚至更好,加速N更快)。

您可以比较结果:

head(g)
head(dt)

答案 1 :(得分:0)

预分配,如果数据是统一类型,则使用矩阵进行构建。请参阅iteratively constructed dataframe in R以获得更美妙的答案。

<强>更新

你是对的 - 瓶颈在于选择。解决方案是查找snps的数字索引,然后只选择那些行,如下所示:

g <- g.raw[match(snps, rownames(g.raw)),]

我是R新手 - 谢谢,这是一个信息丰富的练习。 FWIW,我看过其他人的评论,他们从不使用rownames - 可能是因为这样的事情。

更新2

另请参阅fast subsetting in R,这或多或少是重复的。最重要的是,请注意第一个答案,以及Extract.data.frame的引用,我们发现rowname匹配是部分的,rownames上有一个哈希表,而我在这里建议的解决方案结果是规范的。然而,鉴于所有这些和实验,我现在不明白为什么它这么慢。部分匹配算法应该首先在哈希表中查找完全匹配,在我们的例子中应该总是成功。