2015-12-25 103 views
1

为了更加清晰,我附上了以下代码:我有一个名为grid的S4对象矩阵,每个对象都有一个状态和一个hashmap,如类定义中所示。S4对象深度复制

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) { 
      [email protected] = [email protected] 
      [email protected] = copy([email protected]) 

      }) 

grid <- matrix(sapply(1:(20*20), function(x){ 
    new("cell", 
     state = ifelse(runif(1)<= 0.5, 3, 1), 
     code = hash()) 
}), 20, 20) 

我想复制这个网格的内容到nextgrid。因为该对象包含一个散列表(它是一个通过引用传递的环境),所以一个简单的: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)) 

我得到的错误:错误(函数(类,FDEF,mtable):无法找到函数继承的方法“copy_cell”签字“‘矩阵’” 这我理解,因为我似乎要传递一个矩阵的功能,而不是单个细胞......但我不知道如何正确地重新写它...

我试着用R6对象重写我的类,有一个很好的克隆/深层克隆方法,但是我很难将我的矩阵切片为其他操作,所以我有点卡住了。

想法?

回答

0

我建议使用R5参考类的拷贝构造函数。请注意,哈希映射的函数名称copy与复制构造函数的名称一致,因此“哈希”属性在参考类中非常特殊。我们可以使用eval.parent(quote(copy))作为解决方法来检索复制构造函数。

此外请注意,复制空的散列映射(即copy(hash()))失败。似乎是哈希库的一个bug(或一个特性?)。因此,我还将一个对象添加到网格条目的哈希映射中。

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]] 
+0

没错。你将如何创建一个当前设置的网格?并说我想确保第一行和最后一行中的所有单元格以及第一列和最后一列的状态= 1,是否有一种有效的方法可以做到这一点? –

+0

只需向下滚动即可查看网格是如何创建的:)您可以使用'grid [20,] < - lapply(1:20,function(x)cell(x,hash()))'将值分配给最后一行。 –