web-dev-qa-db-fra.com

Tracer plusieurs boîtes à moustaches dans un graphique

J'ai sauvegardé mes données dans un fichier .csv avec 12 colonnes. Les colonnes deux à 11 (intitulées F1, F2, ..., F11) sont features. Column one contient la label de ces fonctions soit good ou bad.

Je voudrais tracer une boxplot de toutes ces 11 caractéristiques par rapport à la label, mais séparées par good ou bad . Mon code jusqu'ici est:

qplot(Label, F1, data=testData, geom = "boxplot", fill=Label, 
          binwidth=0.5, main="Test") + xlab("Label") + ylab("Features")

Cependant, cela ne montre que F1 par rapport à label.

Ma question est la suivante: comment afficher F2, F3, ..., F11 par rapport à la label d'un graphique avec un certain dodge position? J'ai normalisé les fonctionnalités afin qu'elles soient dans la même échelle dans la plage [0 1].

Les données de test peuvent être trouvées ici . J'ai dessiné quelque chose à la main pour expliquer le problème (voir ci-dessous).

hand-drawn boxplot example

65
Samo Jerom

Vous devez obtenir vos données dans un format spécifique en les fondant (voir ci-dessous pour voir à quoi ressemble les données fondues) avant de tracer. Sinon, ce que vous avez fait semble bien se passer.

require(reshape2)
df <- read.csv("TestData.csv", header=T)
# melting by "Label". `melt is from the reshape2 package. 
# do ?melt to see what other things it can do (you will surely need it)
df.m <- melt(df, id.var = "Label")
> df.m # pasting some rows of the melted data.frame

#     Label variable      value
# 1    Good       F1 0.64778924
# 2    Good       F1 0.54608791
# 3    Good       F1 0.46134200
# 4    Good       F1 0.79421221
# 5    Good       F1 0.56919951
# 6    Good       F1 0.73568570
# 7    Good       F1 0.65094207
# 8    Good       F1 0.45749702
# 9    Good       F1 0.80861929
# 10   Good       F1 0.67310067
# 11   Good       F1 0.68781739
# 12   Good       F1 0.47009455
# 13   Good       F1 0.95859182
# 14   Good       F1 1.00000000
# 15   Good       F1 0.46908343
# 16    Bad       F1 0.57875528
# 17    Bad       F1 0.28938046
# 18    Bad       F1 0.68511766

require(ggplot2)
ggplot(data = df.m, aes(x=variable, y=value)) + geom_boxplot(aes(fill=Label))

boxplot_ggplot2

Edit: Je me rends compte que vous pourriez avoir besoin de facette. Voici une implémentation de cela aussi:

p <- ggplot(data = df.m, aes(x=variable, y=value)) + 
             geom_boxplot(aes(fill=Label))
p + facet_wrap( ~ variable, scales="free")

ggplot2_faceted

Edit 2: Comment ajouter x-labels, y-labels, title, changer legend heading, ajouter un jitter?

p <- ggplot(data = df.m, aes(x=variable, y=value)) 
p <- p + geom_boxplot(aes(fill=Label))
p <- p + geom_jitter()
p <- p + facet_wrap( ~ variable, scales="free")
p <- p + xlab("x-axis") + ylab("y-axis") + ggtitle("Title")
p <- p + guides(fill=guide_legend(title="Legend_Title"))
p 

ggplot2_geom_plot

Edit 3: Comment aligner geom_point() pointe vers le centre de la boîte à moustaches? Cela pourrait être fait en utilisant position_dodge. Cela devrait marcher.

require(ggplot2)
p <- ggplot(data = df.m, aes(x=variable, y=value)) 
p <- p + geom_boxplot(aes(fill = Label))
# if you want color for points replace group with colour=Label
p <- p + geom_point(aes(y=value, group=Label), position = position_dodge(width=0.75))
p <- p + facet_wrap( ~ variable, scales="free")
p <- p + xlab("x-axis") + ylab("y-axis") + ggtitle("Title")
p <- p + guides(fill=guide_legend(title="Legend_Title"))
p 

ggplot2_position_dodge_geom_point

97
Arun

Puisque vous ne parlez pas de paquetage, je propose ici d’utiliser Lattice version (je pense qu’il ya plus de réponses ggplot2 que de réponses en treillis, du moins puisque je suis ici dans SO).

 ## reshaping the data( similar to the other answer)
 library(reshape2)
 dat.m <- melt(TestData,id.vars='Label')
 library(lattice)
 bwplot(value~Label |variable,    ## see the powerful conditional formula 
        data=dat.m,
        between=list(y=1),
        main="Bad or Good")

enter image description here

19
agstudy

En utilisant les graphiques de base, nous pouvons utiliser at = pour contrôler la position de la boîte, combiné à boxwex = pour la largeur des boîtes. L'instruction 1st boxplot crée un tracé vierge. Ajoutez ensuite les 2 traces dans les deux déclarations suivantes.

Notez que dans ce qui suit, nous utilisons df[,-1] pour exclure la première colonne (id) des valeurs à tracer. Avec des trames de données différentes, il peut être nécessaire de changer cela en un sous-ensemble pour les colonnes contenant les données que vous voulez tracer.

boxplot(df[,-1], boxfill = NA, border = NA) #invisible boxes - only axes and plot area
boxplot(df[df$id=="Good", -1], xaxt = "n", add = TRUE, boxfill="red", 
  boxwex=0.25, at = 1:ncol(df[,-1]) - 0.15) #shift these left by -0.15
boxplot(df[df$id=="Bad", -1], xaxt = "n", add = TRUE, boxfill="blue", 
  boxwex=0.25, at = 1:ncol(df[,-1]) + 0.15) #shift to the right by +0.15

enter image description here

Quelques données factices:

df <- data.frame(
  id = c(rep("Good",200), rep("Bad", 200)),
  F1 = c(rnorm(200,10,2), rnorm(200,8,1)),
  F2 = c(rnorm(200,7,1),  rnorm(200,6,1)),
  F3 = c(rnorm(200,6,2),  rnorm(200,9,3)),
  F4 = c(rnorm(200,12,3), rnorm(200,8,2)))
12
dww

version ggplot du graphe en treillis:

library(reshape2)
library(ggplot2)
df <- read.csv("TestData.csv", header=T)
df.m <- melt(df, id.var = "Label")

ggplot(data = df.m, aes(x=Label, y=value)) + 
         geom_boxplot() + facet_wrap(~variable,ncol = 4)

Parcelle: enter image description here

11
JT85

Je sais que c’est une question un peu plus ancienne, mais c’est aussi une question que j’avais eue. Bien que les réponses acceptées fonctionnent, il existe un moyen de faire quelque chose de similaire sans en utilisant des paquets supplémentaires comme ggplot ou lattice. Ce n'est pas tout à fait aussi agréable en ce que les boîtes à moustaches se chevauchent plutôt que de les montrer côte à côte mais:

boxplot(data1[,1:4])
boxplot(data2[,1:4],add=TRUE,border="red")

picture of what this does.

Ceci met en place deux ensembles de boîtes à moustaches, le second ayant un contour (pas de remplissage) en rouge, et met également les valeurs aberrantes en rouge. La bonne chose est, cela fonctionne pour deux images différentes plutôt que d'essayer de les remodeler. Manière rapide et sale.

5
user2103050

En base R, une interface de formule avec des interactions (:) peut être utilisée pour y parvenir.

df <- read.csv("~/Desktop/TestData.csv")
df <- data.frame(stack(df[,-1]), Label=df$Label) # reshape to long format

boxplot(values ~ Label:ind, data=df, col=c("red", "limegreen"), las=2)

example

3