2013-01-17 95 views
2

我選擇data.frame g.raw的一個子集,這樣的:[R很慢矩陣/ data.frame指數選擇

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.raw很多。

謝謝!

+0

我不認爲還有比您的解決方案更快的方法。 –

+2

我可以看到如何通過字符索引可能會很慢,但我很難包裝我的頭,這可能需要幾個小時。你能提供一個更完整的代碼示例嗎? – joran

+3

在%snps中創建邏輯矢量'ind < - rownames(g.raw)%並使用'ind'創建子集。這是否更快? – joran

回答

0

預分配,並使用矩陣構建如果數據是均勻的類型。請參閱iteratively constructed dataframe in R以獲得更美妙的答案。

UPDATE

你是對的 - 瓶頸是選擇。解決的辦法是查找SNP的數字指標,一次,然後只選擇那些行,像這樣:

​​

我的R新手 - 感謝,這是一個內容豐富的運動。 FWIW,我看過其他人的評論,他們從不使用rownames - 可能是因爲這樣的事情。

UPDATE 2

參見fast subsetting in R,這是更多或更少的重複。最顯著,注意第一個答案,而提及Extract.data.frame,我們發現,rowname匹配是局部的,即有上rownames一個哈希表,那我建議這裏的解決方案被證明是規範一個。但是,考慮到這一切以及實驗,我現在不明白爲什麼它如此緩慢。部分匹配算法應首先在哈希表中查找完全匹配,在我們的情況下應該總是成功。

+0

我不太瞭解預分配如何提供幫助。只需要幾分鐘的時間即可將所有數據(從文件存儲到內存中)加載。我的代碼是a = g [子集],其中g已經存在。似乎慢速部分不會分配內存,但出於某種原因選擇子集。 – user1988705

+0

查看更新..... –

5

這似乎是在那裏data.table可以發光的情況。

再現data.frame:快與這些NM(甚至更好SPEE

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 

好,100倍倍:

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方法與更大的N)。

您可以比較的結果:

head(g) 
head(dt)