2016-01-14 12 views
10

R6オブジェクト内のウィンドウでparLapply()を使用したいと思っています。ノードにR6関数やデータをエクスポートする必要がないことがわかりました(少なくともいくつかの場合)。ここでparLapply in R6 classes

は私がparLapply()内のプライベートメソッドにアクセスすることができます例です。

require(R6);require(parallel) 
square <- 
R6Class("square", 
     public = list(
      numbers = NA, 
      squares = NA, 
      initialize = function(numbers,integer) { 
       self$numbers <- numbers 
       squares <- private$square.numbers() 
      } 
     ), 
     private = list(
      square = function(x) { 
       return(x^2) 
      }, 
      square.numbers = function() { 
       cl <- makeCluster(detectCores()) 
       self$squares <- parLapply(cl, 
              self$numbers, 
              function (x) private$square(x) 
             ) 
       stopCluster(cl) 
      } 
     )) 
##Test 
test <- square$new(list(1,2,3)) 
print(test$squares) 
# [[1]] 
# [1] 1 
# 
# [[2]] 
# [1] 4 
# 
# [[3]] 
# [1] 9 

そして、私はまた、パブリックメンバにアクセスすることができます第二の例:

square2 <- 
R6Class("square2", 
     public = list(
      numbers = NA, 
      squares = NA, 
      integer = NA, 
      initialize = function(numbers,integer) { 
       self$numbers <- numbers 
       self$integer <- integer 
       squares <- private$square.numbers() 
      } 
     ), 
     private = list(
      square = function(x) { 
       return(x^2) 
      }, 
      square.numbers = function() { 
       cl <- makeCluster(detectCores()) 
       self$squares <- parLapply(cl, 
              self$numbers, 
              function (x) private$square(x)+self$integer 
             ) 
       stopCluster(cl) 
      } 
     )) 
##Test 
test2 <- square2$new(list(1,2,3),2) 
print(test2$squares) 
#[[1]] 
#[1] 3 
# 
#[[2]] 
#[1] 6 
# 
#[[3]] 
#[1] 11 

私の質問が二つある:(1 )R6ではこれを可能にして、データオブジェクトや関数をエクスポートする必要はありません。 (2)私はこの振る舞いに頼ることができますか、これはこれらの具体例の人工物ですか?

UPDATE:オブジェクトがインスタンス化された後に、この動作はまた、パブリックメソッドとメンバーを使用して動作しているように見えます

R6クラスと
square3 <- R6Class(
    classname = "square3", 
    public = list(
     numbers = NA, 
     squares = NA, 
     integer = NA, 
     square = function(x) { 
      return(x^2) 
     }, 
     square.numbers = function() { 
      cl <- makeCluster(detectCores()) 
      self$squares <- parLapply(cl, 
             self$numbers, 
            function (x) self$square(x)+self$integer 
           ) 
     stopCluster(cl) 
    }, 
    initialize = function(numbers,integer) { 
     self$numbers <- numbers 
     self$integer <- integer 
    } 
    ) 
) 
test3.obj <- square3$new(list(1,2,3),2) 
test3.obj$square.numbers() 
test3.obj$squares 

# [[1]] 
# [1] 3 
# 
# [[2]] 
# [1] 6 
# 
# [[3]] 
# [1] 11 

答えて

1

、あなたがオブジェクトをインスタンス化するたびに、そのオブジェクト変更された環境で、各関数/メソッドのコピーを取得します。関数には、selfがオブジェクトのパブリック環境(これはオブジェクトのパブリックな面)を指し、privateはオブジェクトのプライベート環境を指し示す環境に割り当てられます。

これは、オブジェクトのインスタンス化ごとにコピーされないS3メソッドとは異なります。

要約:R6ではすべてがオブジェクト内に自己完結しています。 S3では、オブジェクトにはメソッドが含まれていません。

私はparLapplyの使用に慣れていませんが、parLapplyのようなものに頼っても安全だと思います。

+0

ありがとうございます!これは大きな助けとなる – chandler

+0

私はこの説明に少し困惑しています.3Sで同じことをしてはいけません。なぜなら、Rの各フォークがワーキングセットの独自のコピーを取得するからです(OSカーネルはこれをRではなく処理します) ?とにかく、私はいつも 'mclapply'をこのように使っています(私は' parLapply'や明示的なクラスターを使用しません)、私は何もエクスポートする必要がありませんでした。 –

+0

os x/linuxでの作業のようです。私の(限られた)理解から、これらのオペレーティングシステムでは、「フォーク」は作業ディレクトリ全体を取得しますが、これはウィンドウでは発生しません。だからこそ私はWindowsユーザーがメソッドやメンバをエクスポートする必要がないので、この動作について興味がありました(そして、並列実装をはるかに便利にしています)。また、私はs3であまり仕事をしていないので、同様の状況でその行動についてコメントすることはできません – chandler