2017-10-16 9 views
0

Ich bin in der Dokumentation verloren und wirklich den Überblick darüber, was zu tun ist. Ich denke, dass die Lösung ist, Umgebungen zu verwenden, aber ich kann nicht herausfinden, wie, selbst wenn ich fühle, dass es nicht so kompliziert ist.S4 Methode Subsetting generische ersetzen Umgebung

Hier ist ein einfaches Beispiel zwei Klassen:

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

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

Hier ist die Objekte Schöpfung:

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)); 

ich dann zwei Methoden bin definieren das Alter und die ID zu setzen und ein Verfahren für Untereinstellungen Person:

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]]); 
    }); 

Jetzt ist hier das Problem:

> 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 

Wenn ich das richtig verstanden, so etwas wie Ich habe Umgebungen verwenden zu bekommen:

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]])) 
    }); 

Geht man durch die doc dies ist wirklich kompliziert zu werden. Kann mir jemand einen Hinweis geben, wie das geht?

Vielen Dank.

Antwort

1

Alles, was Sie brauchen, ist [[<- für Ihre PersonList Klasse zu definieren:

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

Dann sollten Sie den Code arbeiten. Sie könnten jedoch etwas Code hinzufügen, um die Integrität zu überprüfen. Wie inherits(value, "Person") und missing(j).

+0

danke !! Das ist schwierig zu verstehen, aber es hat funktioniert. – nicoluca

+0

Ja, es ist schwierig, aber wenn Sie darüber nachdenken, wie die Befehlszeile 'setAge (Mitarbeiter [[1]]) <-56 'wissen sollte, dass es in' Mitarbeiter @ datsetList' schreiben soll, beginnt es Sinn zu machen. Fühlen Sie sich frei, die Antwort zu erhöhen/akzeptieren Sie die Antwort, wenn es für Sie hilfreich war. –