2011-10-28 16 views
5

Je souhaite dessiner des rectangles dans R et ajouter des noms aux valeurs aberrantes. Jusqu'à présent, j'ai trouvé this solution.Etiquetage des valeurs aberrantes Boxplot dans R

La fonction présente toutes les fonctionnalités dont j'ai besoin, mais elle brouille incorrectement les étiquettes. Dans l'exemple suivant, il marque la valeur aberrante comme « u » au lieu de « o »:

library(plyr) 
library(TeachingDemos) 
source("http://www.r-statistics.com/wp-content/uploads/2011/01/boxplot-with-outlier-label-r.txt") # Load the function 
set.seed(1500) 
y <- rnorm(20) 
x1 <- sample(letters[1:2], 20,T) 
lab_y <- sample(letters, 20) 
# plot a boxplot with interactions: 
boxplot.with.outlier.label(y~x1, lab_y) 

Connaissez-vous une solution? La bibliothèque ggplot2 est super sympa, mais ne fournit aucune fonctionnalité (pour autant que je sache). Mon alternative est d'utiliser la fonction text() et d'extraire les informations aberrantes de l'objet boxplot. Cependant, comme cela, les étiquettes peuvent se chevaucher.

Merci beaucoup :-)

+2

Mise à jour: J'ai apporté cette erreur à l'attention de Tal Galili, et w/en heures, il a posté une version éditée du script qui ne présente plus ce problème. –

Répondre

6

J'ai regardé cela avec debug(boxplot.with.outlier.label), et ... il se trouve qu'il ya une bug dans la fonction.

l'erreur se produit sur la ligne 125, où le data.frame DATA est construit à partir x, ylabel_name et.

Précédemment x et y ont été réorganisés, alors que lab_y n'a pas été. Lorsque la valeur fournie de x (votre x1) n'est pas en elle-même déjà en ordre, vous obtiendrez le genre de jumbling que vous avez expérimenté.

En tant que solution immédiate, vous pouvez pré-commander les x valeurs comme celui-ci (ou faire quelque chose de plus élégant)

df <- data.frame(y, x1, lab_y, stringsAsFactors=FALSE) 
df <- df[order(df$x1), ] 
# Needed since lab_y is not searched for in data (though it probably should be) 
lab_y <- df$lab_y 

boxplot.with.outlier.label(y~x1, lab_y, data=df) 

Boxplot produced by procedure described above

+0

Josh: merci.^_^ –

+0

Merci Josh. J'ai rencontré le même problème il y a quelques jours, donc c'était une aide précieuse. +1 – pssguy

+1

Content de vous aider.Comme cela semble être utile à d'autres personnes, je viens d'envoyer un e-mail à l'auteur du script, comme il l'avait demandé aux utilisateurs s'ils trouvaient des erreurs dans le script. –

1

Le intelligent point label placement est une question distincte discuté here ou here. Il n'y a pas de solution ultime et idéale, il vous suffit d'en choisir une.

Donc, vous overplot la boxplot normale avec des étiquettes, comme suit:

set.seed(1501) 
y <- c(4, 0, 7, -5, rnorm(16)) 
x1 <- c("a", "a", "b", "b", sample(letters[1:2], 16, T)) 
lab_y <- sample(letters, 20) 

bx <- boxplot(y~x1) 

out_lab <- c() 
for (i in seq(bx$out)) { 
    out_lab[i] <- lab_y[which(y == bx$out[i])[1]] 
} 

identify(bx$group, bx$out, labels = out_lab, cex = 0.7) 

Puis, au cours de la identify() est en cours d'exécution, cliquez simplement sur la position où vous voulez l'étiquette, comme décrit here. Lorsque vous avez terminé, vous appuyez simplement sur "STOP". Notez que chaque valeur aberrante peut avoir plus d'une étiquette! Dans ma solution, j'ai simplement choisi le premier !! PS: J'ai honte de la boucle for, mais je ne sais pas comment la vectoriser - n'hésitez pas à poster des améliorations.

EDIT: inspiré par le Federico's link maintenant je vois que cela peut être fait beaucoup plus facile! Juste ces 2 commandes:

boxplot(y~x1) 
identify(as.integer(as.factor(x1)), y, labels = lab_y, cex = 0.7) 
+1

La solution identify() est sympa, mais elle n'est pas évolutive, j'ai des centaines de parcelles et je dois les imprimer en PDF :-) –

Questions connexes