2017-10-16 227 views
0

我迷失在文檔中,真的失去了做什麼的軌道。我認爲解決方案是使用環境,但即使我覺得它不那麼複雜,我也無法弄清楚。S4方法子集化通用替換環境

下面是使用兩個類一個簡單的例子:

Person <- setClass(  
    Class = "Person", 
    slots = c(name = "character", 
      id = "numeric", 
      age = "numeric")); 

PersonList <- setClass( 
    Class = "PersonList", 
    slots = c(datasetList = "list")); 

這裏是對象的創建:

mary <- new("Person", name = "Mary", id = 1, age = 35); 
peter <- new("Person", name = "Peter", id = 2, age = 39); 
john <- new("Person", name = "John", id = 3, age = 25); 
employees <- new("PersonList", datasetList = list(mary, peter, john)); 

我再定義兩個方法來設置年齡和ID和方法對於子設置PersonList:

setGeneric(name = "setAge<-", def = function(theObject, value){standardGeneric("setAge<-");}); 
setGeneric(name = "setid<-", def = function(theObject, value){standardGeneric("setid<-");}); 

setReplaceMethod(

    f = "setAge", 

    signature = "Person", 

    definition = function(theObject, value){ 
     [email protected] <- value; 
     return(theObject); 
    }); 

setReplaceMethod(

    f = "setid", 

    signature = "Person", 

    definition = function(theObject, value){ 
     [email protected] <- value; 
     return(theObject); 
    }); 

setMethod(

    f = "[[", 

    signature = c("PersonList", "ANY", "ANY"), 

    definition = function(x, i, j, ...){ 

     return([email protected][[i]]); 
    }); 

現在,這裏的問題是:

> setAge(employees[[1]]) <-56 
Error in `[[<-`(`*tmp*`, 1, value = new("Person", 
      name = "Mary", id = 1, : 
        [[<- defined for objects of type "S4" only for subclasses of environment 

如果我理解正確的話我必須使用環境中得到的東西,如:

setMethod(

    f = "[[<-", 

    signature = c("PersonList", "ANY", "ANY"), 

    definition = function(x, i, j, ...){ 

     if environment is setid return(setId(x[[i]])) 
     if environment is setAge return(setAge(x[[i]])) 
    }); 

通過文檔,這是越來越複雜,真正走出去。任何人都可以給我一個關於如何做到這一點的提示嗎?

非常感謝。

回答

1

所有你需要的是定義[[<-PersonList類:

setMethod(
    f = "[[<-", 
    signature = c("PersonList"), 
    definition=function(x,i,j,value) { 
     [email protected][[i]] <- value 
     return(x) 
    }) 

那麼你的代碼應該工作。不過,您可以添加一些代碼來檢查完整性。像inherits(value, "Person")missing(j)

+0

謝謝!!這是棘手的理解,但它的工作。 – nicoluca

+0

是的,它是棘手的,但如果你想一想,命令行'setAge(employees [[1]])<-56'應該如何知道它應該寫入'employees @ datsetList'?,它開始有意義。如果對你有幫助,隨時歡迎/接受答案。 –