tapply change le type...

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

tapply change le type...

Messagepar Christophe Genolini » 24 Oct 2008, 16:33

Bonjour

Quand on applique un tapply, il nous renvoie un array. Ce faisant, il change le type de nos données initiales. Existe-t-il un outil qui nous retournerait un objet du meme type que ce qu'on utilise ?

Exemple qui me pose problème :

Code : Tout sélectionner

###Les cat ne sont la que pour le débugage
Lmedian <- function(variable){cat("G");UseMethod("Lmedian")}

Lmedian.numeric <- function(variable){cat("N");median(variable,na.rm=TRUE)}

Lmedian.ordered <- function(variable){
    cat("O");
    sort(variable)[floor((length(variable)+1)/2)]
}

Lmedian.formula <- function(variable){cat("F");
    xGauche <- eval(variable[[2]],envir=parent.frame(n=1))
    xDroite <- eval(variable[[3]],envir=parent.frame(n=1))
    return(tapply(xGauche,xDroite,Lmedian))
}


### Tests :
groupe <- rep(c("A","B","C"),time=7)
bac <- ordered(rep(c("R","AB","AB","P","B","F","B"),time=3),level=c("R","P","AB","B","TB","F"))

Lmedian(bac)
# [1] AB
# Levels: R < P < AB < B < TB < F

Lmedian(bac~groupe)
# A B C
#  3 3 3


Le Lmedian de bac marche et retourne un ordered, mais le Lmedian de bac en fonction des groupes retournes un array de numeric (et donc 3 3 3) au lieu d'un ordered (dans ce cas : AB AB AB)

Des idées ?

Christophe

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 24 Oct 2008, 21:18

Je ne suis pas sur que ca interesse beaucoup de monde, mais puisqu'après avoir découpé la fonction tapply, j'ai trouvé, je me réponds...

Code : Tout sélectionner

Lmedian.formula <- function(variable){cat("F");
    xGauche <- eval(variable[[2]],envir=parent.frame(n=1))
    xDroite <- eval(variable[[3]],envir=parent.frame(n=1))
    return(unlist(lapply(split(xGauche,xDroite),Lmedian)))
}

Lmedian(bac~groupe)
# GFGOGOGO A  B  C
# AB AB AB
# Levels: R P AB B TB F


Ca marche presque, seul petit détail, unlist transforme les "ordered factor" en "factor". Encore un mystère bien mystérieux de R...

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 27 Oct 2008, 08:49

Bonjour,

La réponse est dans l'aide de tapply :
If FUN returns a single atomic value for each such cell (e.g., functions mean or var) and when simplify is TRUE, tapply returns a multi-way array containing the values, and NA for the empty cells. The array has the same number of dimensions as INDEX has components; the number of levels in a dimension is the number of levels (nlevels()) in the corresponding component of INDEX. Note that if the return value has a class (e.g. an object of class "Date") the class is discarded.


Si tu enlève tu remplaces simplify=TRUE par FALSE :

Code : Tout sélectionner

Lmedian.formula <- function(variable){
  xGauche <- eval(variable[[2]],envir=parent.frame(n=1))
  xDroite <- eval(variable[[3]],envir=parent.frame(n=1))
  do.call("ordered",list(unlist(tapply(xGauche,xDroite,Lmedian,simplify=FALSE)),levels=levels(xGauche)))
  }


Et ici en sortie tu as bien un facteur ordonné.

Maxime

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 27 Oct 2008, 13:38

Super, merci !


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité