我附上下面的代码以便更清晰;我有一个名为grid的S4对象矩阵,每个对象都有一个状态和一个hashmap,如类定义所示。
cell <- setClass(
# Set the name for the class
"cell",
# Define the slots
slots = c(
state = "numeric",
code = "hash"
),
# Set the default values for the slots.
prototype=list(
state = 1
)
)
setGeneric(name="copy_cell",
def= function(x, y){
standardGeneric("copy_cell")
})
setMethod(f = "copy_cell", signature = "cell",
definition = function(x, y) {
x@state = y@state
x@code = copy(y@code)
})
grid <- matrix( sapply(1:(20*20), function(x){
new("cell",
state = ifelse(runif(1)<= 0.5, 3, 1),
code = hash())
}), 20, 20)
我想将此网格的内容复制到nextgrid中。因为对象包含一个hashmap(这是一个环境,通过引用传递),一个简单的:nextgrid = grid
不会这样做。我创建了一个适用于单独创建的单元格的函数:
cell1 = new("cell", state = ifelse(runif(1)<= 0.5, 3, 1), code = hash("a",1))
cell2 = new("cell")
cell2 = copy_cell(cell2, cell1)
但是我很难实现在矩阵的所有单元格上应用函数的方法。下面,我首先将网格复制到nextgrid,以避免重新初始化另一个整个对象矩阵,然后使用sapply。
nextgrid = grid
sapply(grid[,], function(x) copy_cell(nextgrid[,], x))
我收到错误:(函数(classes,fdef,mtable)中的错误:无法为签名'“matrix”'找到函数'copy_cell'的继承方法。 我理解的是因为我似乎将矩阵传递给函数而不是单个单元格...但我不确定如何正确地重写它...
我尝试使用具有漂亮克隆/深度克隆方法的R6对象重写我的类,但是我很难将其矩阵切片用于其他操作,所以我有点卡住了。
思想?
答案 0 :(得分:0)
我建议使用R5引用类中的复制构造函数。注意&#34;哈希&#34;属性在引用类中非常特殊,因为哈希映射的函数名copy
与复制构造函数的名称一致。我们可以使用eval.parent(quote(copy))
作为解决方法来检索复制构造函数。
进一步注意,复制空哈希映射(即copy(hash())
)失败。似乎是哈希库的错误(或功能?)。因此,我还在网格条目的哈希映射中添加了一个对象。
library(hash)
cell <- setRefClass(
# Set the name for the class
"cell",
# Define the slots
fields = list(
state = "numeric",
code = "hash"
),
methods = list(
# Default constructor
initialize = function(state, code) {
.self$state = state
.self$code = code
},
# Copy constructor
copy = function(shallow = FALSE) {
# Get the copy-function for hash from the parent environment
cp <- eval.parent(quote(copy))
# do the copy
cell(.self$state, cp(code))
}
)
)
# Create cell and copy it
cell1 = cell(ifelse(runif(1)<= 0.5, 3, 1), hash("a",1))
cell2 = cell1$copy()
# Let's convince ourselves that we did a deep copy
cell1$code[["a"]]=5
cell2
# Create grid and copy it
grid <- matrix( sapply(1:(20*20), function(x){
cell(ifelse(runif(1)<= 0.5, 3, 1), hash("a",1))
}), 20, 20)
nextgrid = apply(grid, c(1,2), function(x) x[[1]]$copy())
# Let's again convince ourselves that we did a deep copy
grid[[1,1]]$code["a"] = 5
nextgrid[[1,1]]