3

我正在选择一个 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 读入内存中的 matrix/data.frame 不是问题(花了几分钟),而我上面描述的这个操作需要小时。

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

谢谢!

4

2 回答 2

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好吧,使用这些和100 倍快M(并且使用更大的 甚至可以更好地加速N)。

您可以比较结果:

head(g)
head(dt)
于 2013-01-17T23:59:22.967 回答
0

预分配,如果数据是统一类型,则使用矩阵进行构建。请参阅R 中迭代构建的数据框以获得更漂亮的答案。

更新

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

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

我是 R 新手 - 谢谢,这是一个内容丰富的练习。FWIW,我看到其他人评论说他们从不使用行名——可能是因为这样的事情。

更新 2

另请参阅R 中的快速子集,这或多或少是重复的。最重要的是,请注意第一个答案和对Extract.data.frame的引用,我们发现行名匹配是部分的,行名上有一个哈希表,而且我在这里建议的解决方案是规范的。但是,考虑到所有这些和实验,我现在不明白为什么它这么慢。部分匹配算法应该首先在哈希表中查找精确匹配,在我们的例子中应该总是成功的。

于 2013-01-17T22:30:10.633 回答