2017-10-16 14 views
0

Je me perds dans la documentation et perd vraiment la trace de ce qu'il faut faire. Je pense que la solution consiste à utiliser des environnements mais je n'arrive pas à comprendre comment, même si je pense que ce n'est pas si compliqué.S4 méthode sous-ensemble générique remplacement environnement

Voici un exemple simple en utilisant deux classes:

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

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

Voici la création d'objets:

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

Je suis en train de définir alors deux méthodes pour définir l'âge et l'identité, et une méthode pour sous-réglage 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]]); 
    }); 

maintenant est le problème ici:

> 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 

Si je comprends bien, je dois utiliser des environnements pour obtenir quelque chose comme:

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

En passant par le doc cela devient vraiment compliqué. Quelqu'un peut-il me donner un indice sur la façon de faire cela?

Merci beaucoup.

Répondre

1

Tout ce que vous avez besoin est de définir [[<- pour votre PersonList classe:

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

Ensuite, votre code devrait fonctionner. Vous pouvez cependant ajouter du code pour vérifier l'intégrité. Comme inherits(value, "Person") et missing(j).

+0

merci !! C'est difficile à comprendre mais ça a marché. – nicoluca

+0

Oui, c'est difficile, mais si vous pensez à, Comment la ligne de commande 'setAge (employees [[1]]) <-56' sait-elle qu'elle devrait écrire' employees @ datsetList' ?, elle commence à avoir du sens. N'hésitez pas à upvote/accepter la réponse si cela vous a été utile. –