![](/img/trans.png)
[英]Reading large csv file with missing data using bigmemory package in R
[英]Generating a very large matrix of string combinations using combn() and bigmemory package
我有一個1,344個獨特字符串的向量x。 我想生成一個矩陣,它給我所有可能的三個值組,無論順序如何,並將其導出到csv。
我在m1.large實例w 64bit Ubuntu上運行EC on EC2。 使用combn(x,3)時出現內存不足錯誤:
Error: cannot allocate vector of size 9.0 Gb
得到的矩陣的大小是C1344,3 = 403,716,544行和三列 - 這是combn()函數結果的轉置。
我想使用bigmemory包創建一個文件支持的big.matrix,然后我可以分配combn()函數的結果。 我可以創建一個預分配的大矩陣:
library(bigmemory)
x <- as.character(1:1344)
combos <- 403716544
test <- filebacked.big.matrix(nrow = combos, ncol = 3,
init = 0, backingfile = "test.matrix")
但是當我嘗試分配值test <- combn(x, 3)
我仍然得到相同的結果: Error: cannot allocate vector of size 9.0 Gb
我甚至嘗試強制combn(x,3)
的結果,但我認為因為combn()函數返回錯誤,big.matrix函數也不起作用。
test <- as.big.matrix(matrix(combn(x, 3)), backingfile = "abc")
Error: cannot allocate vector of size 9.0 Gb
Error in as.big.matrix(matrix(combn(x, 3)), backingfile = "abc") :
error in evaluating the argument 'x' in selecting a method for function 'as.big.matrix'
有沒有辦法將這兩個功能結合起來得到我需要的東西? 有沒有其他方法可以實現這一目標? 謝謝。
這是我用R編寫的函數,它目前在LSPM包中找到它的(未導出的)主頁。 你給它的項目總數n
,項目選擇的號碼r
並且希望組合的索引i
; 它返回對應於組合i
1:n
的值。
".combinadic" <- function(n, r, i) {
# http://msdn.microsoft.com/en-us/library/aa289166(VS.71).aspx
# http://en.wikipedia.org/wiki/Combinadic
if(i < 1 | i > choose(n,r)) stop("'i' must be 0 < i <= n!/(n-r)!")
largestV <- function(n, r, i) {
#v <- n-1
v <- n # Adjusted for one-based indexing
#while(choose(v,r) > i) v <- v-1
while(choose(v,r) >= i) v <- v-1 # Adjusted for one-based indexing
return(v)
}
res <- rep(NA,r)
for(j in 1:r) {
res[j] <- largestV(n,r,i)
i <- i-choose(res[j],r)
n <- res[j]
r <- r-1
}
res <- res + 1
return(res)
}
它允許您根據詞典索引的值生成每個組合:
> .combinadic(1344, 3, 1)
[1] 3 2 1
> .combinadic(1344, 3, 2)
[1] 4 2 1
> .combinadic(1344, 3, 403716544)
[1] 1344 1343 1342
所以你只需要遍歷1:403716544並將結果追加到文件中。 這可能需要一段時間,但至少是可行的(參見Dirk的回答)。 你也可能需要在幾個循環中完成它,因為向量1:403716544
將不適合我的機器上的內存。
或者你可以只端口將R代碼,C / C ++,做循環/寫在那里,因為它是快了很多 。
您可以先找到所有雙向組合,然后將它們與3d值組合,同時每次都保存它們。 這需要更少的內存:
combn.mod <- function(x,fname){
tmp <- combn(x,2,simplify=F)
n <- length(x)
for ( i in x[-c(n,n-1)]){
# Drop all combinations that contain value i
id <- which(!unlist(lapply(tmp,function(t) i %in% t)))
tmp <- tmp[id]
# add i to all other combinations and write to file
out <- do.call(rbind,lapply(tmp,c,i))
write(t(out),file=fname,ncolumns=3,append=T,sep=",")
}
}
combn.mod(x,"F:/Tmp/Test.txt")
這不像約書亞的答案那么籠統,它特別針對你的情況。 對於這個特殊情況,我想它更快 - 但是我沒有進行比較。 當應用於x時,功能在我的計算機上運行時使用超過50 Mb(粗略估計)。
編輯
旁注:如果這是出於模擬目的,我發現很難相信任何科學應用程序需要4億多次模擬運行。 你可能在這里問錯了問題的正確答案......
概念證明:
我用tt[[i]]<-out
改變了寫行,在循環之前添加了tt <- list()
並在它之后返回(tt)。 然后:
> do.call(rbind,combn.mod(letters[1:5]))
[,1] [,2] [,3]
[1,] "b" "c" "a"
[2,] "b" "d" "a"
[3,] "b" "e" "a"
[4,] "c" "d" "a"
[5,] "c" "e" "a"
[6,] "d" "e" "a"
[7,] "c" "d" "b"
[8,] "c" "e" "b"
[9,] "d" "e" "b"
[10,] "d" "e" "c"
在第一次近似時, 每個算法都以存儲速度換取速度。
您已嘗試預先分配完全枚舉的組合矩陣。 所以也許你應該嘗試不預先分配這個矩陣,但試試,比方說,
如果您認為需要這些組合,請在其他地方計算它們並將它們存儲在一個簡單的數據庫(或者,平面文件)中並查找它們 - 保存9 gb
利用開源,讀取代碼以combn()
並將其修改為客戶端 - 服務器東西:給定索引號為N的調用,它將循環並返回第N個條目。 效率不高,但可能更容易實現 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.