3

Rオブジェクトを並行して操作する方法はありますか?mclapplyフォークプロセスでparallelは、ワークスペースの内容を各プロセスにコピーすることを理解しています。代わりに、結果を分割して結合することなく、コアにオブジェクトに対して独立したジョブを実行させたいと思います。ユースケースはnumeric、data.frame内のすべての列factorを並列の列に変更することです。別のユースケースは、多数のレベルを持つdata.frameのビニングファクターです。私がこれを行おうとしている主な理由は、1)メモリ不足を回避するため、および2)速度を上げるためです。

以下のオブジェクトbは、data.frame内の列を分割しa、適用後にそれらを結合した結果ですfactor。代わりに、オブジェクトを直接操作したいと思いますa。シリアルでは、ループの副作用として列aを型に変換することができます。並行して、副作用としての列をタイプに変換することはできません。これは、(私が理解しているように)内部で、生成された各プロセスにローカルなオブジェクトを参照しているためです。factorforeach...%do%afactorforeach...%dopar%a

これを可能にするパッケージはありRますか?

a <- data.frame(b=c(1,1,2,2), c=c(2,2,3,3))
str(a)

> str(a)
'data.frame':   4 obs. of  2 variables:
 $ b: num  1 1 2 2
 $ c: num  2 2 3 3

#serial
b <-
  foreach (i = iter(1:ncol(a)), .combine = data.frame) %do% {
    a[,i] <- factor(a[,i])
  }
str(a)
str(b)

> str(a)
'data.frame':   4 obs. of  2 variables:
 $ b: Factor w/ 2 levels "1","2": 1 1 2 2
 $ c: Factor w/ 2 levels "2","3": 1 1 2 2
> str(b)
'data.frame':   4 obs. of  2 variables:
 $ result.1: Factor w/ 2 levels "1","2": 1 1 2 2
 $ result.2: Factor w/ 2 levels "2","3": 1 1 2 2

#parallel
a <- data.frame(b=c(1,1,2,2), c=c(2,2,3,3))
b <-
  foreach (i = iter(1:ncol(a)), .combine = data.frame) %dopar% {
    a[,i] <- factor(a[,i])
  }
str(a)
str(b)

> str(a)
'data.frame':   4 obs. of  2 variables:
 $ b: num  1 1 2 2
 $ c: num  2 2 3 3
> str(b)
'data.frame':   4 obs. of  2 variables:
 $ result.1: Factor w/ 2 levels "1","2": 1 1 2 2
 $ result.2: Factor w/ 2 levels "2","3": 1 1 2 2
4

1 に答える 1

5

まず、Rは(一般的に)call by valueであることに注意する必要があります。そのため、何をするにしても、常にデータフレームの一時的なコピーが作成されます。これは、applyファミリーの通常のバージョンにも当てはまります。関数内で何かを変更すると、オブジェクトが最初にコピーされます。

ただし、ワークスペースの内容全体を子プロセスにコピーすることはmclapplyありません。私が理解している限り、プロセスは同じメモリコンテンツを共有し、変更が加えられた場合にのみコンテンツをコピーします。とにかく、これは多かれ少なかれRが行うことに帰着します。

それでもこれを信頼できない場合は、クラスターアプローチを使用して、パッケージparLapplyから友達と試してみてください。parallelこれはフォークに基づくのではなく、ノードクラスターに基づいています。ここでコアをノードとして見ることができます。この場合、を使用して計算に必要なワークスペースから変数を明示的にエクスポートする必要がありますclusterExport()。これについてはよくわかりませんが、コピーが作成されるのではないかと思います。残りの部分については、parLapply作業する要素のみを別のクラスターにコピーします。繰り返しになりますが、これはlapplyデフォルトの場合とかなり同じです。

データフレームaを操作して、次のようにします。

> require(parallel)
> cl <- makeCluster(2)
> b <- parLapply(cl,a,as.factor)
> str(as.data.frame(b))
'data.frame':   4 obs. of  2 variables:
 $ b: Factor w/ 2 levels "1","2": 1 1 2 2
 $ c: Factor w/ 2 levels "2","3": 1 1 2 2
> stopCluster(cl)       
于 2012-06-14T16:20:50.793 に答える