我希望得到一些关于在R中管理大量组合的建议。
我是一名植物育种研究生,试图计算植物种群中40个亲本的各种组合的后代的最高等级平均值。我首先创建一个矩阵,其中包含通过跨越这些父母获得的值:
# fake data
B <- matrix (data=runif(1600, 1.0, 5.0),ncol=40,nrow=40)
diag(B) <- diag(B) - 1 # diagonals are when plants are crossed to themselves and suffer inbreeding depression
我通过查找包含父母的各种组合的矩阵子集(“perse.hybrid”)的平均值来做到这一点:
SubsetWright <- function (perse.hybrid, subset) {
return (mean(perse.hybrid[subset,subset]))
}
理想情况下,我想为40个父母的所有组合找到后代的值,但稍微更现实一点,我想找到2到11个父母组合的值。这大约有35亿种组合。
我一直在努力加快速度并管理内存。为了加快速度,我将其设置为在Amazon EC2集群上并行运行任务(通常为3 m4.10xlarge机器)。为了解决内存挑战,我试图将数据保存在big.matrix中。但是,我似乎遇到了反对。通常当我到40时选择8,它会崩溃。看着htop,我相信这是因为内存的使用。
我是新手R用户并且不明白如何在R中管理内存。如果我能以某种方式分割出combn函数,这似乎可以得到这些限制,这可能允许我并行运行它并避免内存限制。或者也许有一种方法可以在不使用combn的情况下使用所有组合填充big.matrix。有没有人有任何建议的策略?代码如下。非常感谢你!
#' Test all combinations of parents to find set of offspring with highest estimated mean.
#'
#' @param perse.hybrid A matrix of offspring values, with row[i]=col[j]=parent ID
#' @param min The minimum number of parents to test combinations of
#' @param max The maximum number of parents to test combinations of
#' @param rows Number of rows of top combinations to return, default is to return all rows
#' @param cl cluster to use
#' @return A big.matrix with parent combinations and predicted average offspring values
TestSyn <- function (perse.hybrid, min, max, rows="all", cl) {
clusterExport(cl, list("SubsetWright"))
total <- sum(apply(X=array(min:max),MARGIN=1,FUN=choose,n=nrow(perse.hybrid)))
n <- nrow(perse.hybrid)
start <- 1
stop <- choose(n,min)
syn.data <- big.matrix(nrow=total,ncol=max+1)
for (i in min:max)
{
#add inbred numbers to syn.data. This seems to be what crashes when i gets large (>7)
inbreds <- t(combnPrim(1:n,i))
syn.data[start:stop,1:i] <- inbreds
#add sythetic values to syn.data
syn.data[start:stop,max+1] <- parApply(cl=cl,X=inbreds,MARGIN=1,FUN=SubsetWright,perse.hybrid=perse.hybrid)
start <- stop + 1
stop <- start + choose(n,i+1) - 1
}
# sort by offspring average
mpermute(x=syn.data,cols=max+1,decreasing=TRUE)
if (rows == "all") rows <- nrow(syn.data)
return (syn.data[1:rows,])
}
编辑:
随着更多调查,看起来combinadics可能是解决方案的一部分。 Stackoverflow发布在这里:Generating a very large matrix of string combinations using combn() and bigmemory package
我会做一些测试,看看这是否适用于大数字。