Comment faire la médiane des scissions au sein des niveaux de facteur dans la R?

StackOverflow https://stackoverflow.com/questions/1259867

  •  12-09-2019
  •  | 
  •  

Question

Ici, je fais une nouvelle colonne pour indiquer si myData est au-dessus ou en dessous de sa médiane

### MedianSplits based on Whole Data
#create some test data
myDataFrame=data.frame(myData=runif(15),myFactor=rep(c("A","B","C"),5)) 

#create column showing median split
myBreaks= quantile(myDataFrame$myData,c(0,.5,1))
myDataFrame$MedianSplitWholeData = cut(
    myDataFrame$myData,
    breaks=myBreaks, 
    include.lowest=TRUE,
    labels=c("Below","Above"))

#Check if it's correct
myDataFrame$AboveWholeMedian = myDataFrame$myData > median(myDataFrame$myData)
myDataFrame

fonctionne très bien. Maintenant, je veux faire la même chose, mais calculer la valeur médiane des scissions au sein de chaque niveau de myFactor.

Je suis venu avec ceci:

#Median splits within factor levels
byOutput=by(myDataFrame$myData,myDataFrame$myFactor, function (x) {
     myBreaks= quantile(x,c(0,.5,1))
     MedianSplitByGroup=cut(x,
       breaks=myBreaks, 
       include.lowest=TRUE,
       labels=c("Below","Above"))
     MedianSplitByGroup
     })

byOutput contient ce que je veux. Il catégorise chaque élément de facteurs A, B et C correctement. Cependant, je voudrais créer une nouvelle colonne, myDataFrame $ FactorLevelMedianSplit, qui montre la division médiane nouvellement calculé.

Comment convertir la sortie du « par » commande dans une colonne utile trame de données?

Je pense que peut-être le « par » commande n'est pas R comme façon de le faire ...

Mise à jour :

Avec l'exemple de Thierry de la façon d'utiliser le facteur () intelligemment, et en découvrant la fonction « ave » dans le livre de Spector, j'ai trouvé cette solution, qui ne nécessite pas d'autres paquets.

myDataFrame$MediansByFactor=ave(
    myDataFrame$myData,
    myDataFrame$myFactor,
    FUN=median)

myDataFrame$FactorLevelMedianSplit = factor(
    myDataFrame$myData>myDataFrame$MediansByFactor, 
    levels = c(TRUE, FALSE), 
    labels = c("Above", "Below"))
Était-ce utile?

La solution

Voici une solution en utilisant le package plyr.

myDataFrame <- data.frame(myData=runif(15),myFactor=rep(c("A","B","C"),5))
library(plyr)
ddply(myDataFrame, "myFactor", function(x){
    x$Median <- median(x$myData)
    x$FactorLevelMedianSplit <- factor(x$myData <= x$Median, levels = c(TRUE, FALSE), labels = c("Below", "Above"))
    x
})

Autres conseils

Voici un moyen hack-ish. Hadley peut venir avec quelque chose de plus élégant:

Pour commencer, nous simplement concaténer la sortie by:

 R> do.call(c,byOutput)
A1 A2 A3 A4 A5 B1 B2 B3 B4 B5 C1 C2 C3 C4 C5 
 1  2  2  1  1  1  1  2  1  2  1  2  1  1  2 

et ce qui compte que nous obtenons les niveaux de facteur 1 et 2 ici que nous pouvons utiliser pour réindexer un nouveau facteur avec les niveaux:

R> c("Below","Above")[do.call(c,byOutput)]
 [1] "Below" "Above" "Above" "Below" "Below" "Below" "Below" "Above" 
 [8] "Below" "Above" "Below" "Above" "Below" "Below" "Above"
R> as.factor(c("Below","Above")[do.call(c,byOutput)])
[1] Below Above Above Below Below Below Below Above Below Above 
[11] Below Above Below Below Above
Levels: Above Below

que nous pouvons attribuer dans le data.frame que vous vouliez modifier:

R> myDataFrame$FactorLevelMedianSplit <- 
      as.factor(c("Below","Above")[do.call(c,byOutput)])

Mise à jour : Peu importe, nous aurions besoin de réindexer myDataFrame à trier A A ... A ... B ... C C et avant d'ajouter la nouvelle colonne. Gauche comme un exercice ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top