1

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 を使用せずにすべての組み合わせを 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,])
    }

編集:

さらに調査すると、コンビナディクスが解決策の一部になる可能性があるようです。Stackoverflow の投稿はこちら: Combn() と bigmemory パッケージを使用して非常に大きな文字列の組み合わせのマトリックスを生成する

これが大きな数に耐えられるかどうかを確認するために、いくつかのテストを行います。

4

0 に答える 0