在 R6 内 parLapply 类
parLapply within R6 classes
我希望在 R6
对象内的 windows 上使用 parLapply()
并注意到(至少在某些情况下)我不需要导出 R6 函数或数据到节点。
这是一个示例,我可以在 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
还有第二个例子,我也可以访问 public 成员:
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) 我可以依赖这种行为还是这些特定示例的产物?
更新:
此行为在实例化对象后使用 public 方法和成员似乎也有效:
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
使用 R6 类,每次实例化对象时,该对象都会获得每个 function/method 的副本,并修改环境。这些函数被分配了一个环境,其中 self
指向对象的 public 环境(这是对象的 public 面),而 private
指向对象的私有环境。
这与 S3 方法不同,S3 方法不会为对象的每个实例化复制。
总结:有了R6,一切都在对象中自成体系;使用 S3,对象不包含方法。
我不太熟悉 parLapply
的使用,但我认为依赖像 parLapply
那样工作的东西是安全的。
我希望在 R6
对象内的 windows 上使用 parLapply()
并注意到(至少在某些情况下)我不需要导出 R6 函数或数据到节点。
这是一个示例,我可以在 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
还有第二个例子,我也可以访问 public 成员:
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) 我可以依赖这种行为还是这些特定示例的产物?
更新:
此行为在实例化对象后使用 public 方法和成员似乎也有效:
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
使用 R6 类,每次实例化对象时,该对象都会获得每个 function/method 的副本,并修改环境。这些函数被分配了一个环境,其中 self
指向对象的 public 环境(这是对象的 public 面),而 private
指向对象的私有环境。
这与 S3 方法不同,S3 方法不会为对象的每个实例化复制。
总结:有了R6,一切都在对象中自成体系;使用 S3,对象不包含方法。
我不太熟悉 parLapply
的使用,但我认为依赖像 parLapply
那样工作的东西是安全的。