我正在选择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。
谢谢!
答案 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
使用这些N
和M
,速度提高了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上有一个哈希表,而我在这里建议的解决方案结果是规范的。然而,鉴于所有这些和实验,我现在不明白为什么它这么慢。部分匹配算法应该首先在哈希表中查找完全匹配,在我们的例子中应该总是成功。