2015-12-25 144 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()))'將值分配給最後一行。 –