S4方法子集化通用替换环境

时间:2017-10-16 00:16:39

标签: r generics subset environment 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){
        theObject@age <- value;
        return(theObject);
    });

setReplaceMethod(

    f = "setid",

    signature = "Person",

    definition = function(theObject, value){
        theObject@id <- value;
        return(theObject);
    });

setMethod(

    f = "[[",

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

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

        return(x@datasetList[[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 个答案:

答案 0 :(得分:1)

您只需要为[[<-课程定义PersonList

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

那么你的代码应该可行。但是,您可以添加一些代码来检查完整性。与inherits(value, "Person")missing(j)一样。