2016-08-17 1 views
3

J'essaie de produire un boxplot de résultats numériques, ventilé par condition de traitement et numéro de visite, avec le nombre d'observations dans chaque boîte placée sous la placette, et les numéros de visite étiqueté aussi bien. Voici quelques fausses données qui serviront à illustrer, et je donne deux exemples de choses que j'ai essayées qui n'ont pas vraiment fonctionné.Annoter l'axe des abscisses avec N dans un tracé à facettes

library(ggplot2) 
library(plyr) 

trt  <- factor(rep(LETTERS[1:2],150),ordered=TRUE) 
vis  <- factor(c(rep(1,150),rep(2,100),rep(3,50)),ordered=TRUE) 
val  <- rnorm(300) 
data  <- data.frame(trt,vis,val) 
data.sum <- ddply(data, .(vis, trt), summarise, 
      N=length(na.omit(val))) 
mytheme <- theme_bw() + theme(panel.margin = unit(0, "lines"), strip.background = element_blank()) 

Le code ci-dessous produit une parcelle qui a N étiquettes où je les veux. Il le fait en saisissant des données récapitulatives à partir d'un jeu de données auxiliaire que j'ai créé. Cependant, je ne pouvais pas comprendre comment étiqueter la visite sur l'axe des x (idéalement, sous les étiquettes des boîtes individuelles), ou délimiter visuellement les visites d'autres façons (par exemple, les lignes les séparant en panneaux).

plot1 <- ggplot(data) + 
      geom_boxplot(aes(x=vis:trt,y=val,group=vis:trt,colour=trt), show.legend=FALSE) + 
      scale_x_discrete(labels=paste(data.sum$trt,data.sum$N,sep="\n")) + 
      labs(x="Visit") + mytheme 

L'intrigue ci-dessous est plus proche de ce que je veux que celui ci-dessus, en ce qu'elle a une belle hiérarchie des traitements et des visites, et un joli format définissant les visites. Cependant, pour chaque panneau, il saisit le N de la première ligne dans les données récapitulatives qui correspondent à la condition de traitement, car il ne "sait" pas que chaque facette doit utiliser la ligne correspondant à cette visite.

plot2 <- ggplot(data) +  geom_boxplot(aes(x=trt,y=val,group=trt,colour=trt), show.legend=FALSE) + 
      facet_wrap(~ vis, drop=FALSE, switch="x", nrow=1) + 
      scale_x_discrete(labels=paste(data.sum$trt,data.sum$N,sep="\n")) + 
      labs(x="Visit") + mytheme 

Répondre

2

Une solution consiste à manipuler votre ensemble de données afin que votre variable x est l'interaction entre trt et N.

En travaillant sur ce que vous avez déjà, vous pouvez ajouter N à l'ensemble de données original via un merge.

test = merge(data, data.sum) 

Ensuite, faire une nouvelle variable qui est la combinaison de trt et N.

test = transform(test, trt2 = paste(trt, N, sep = "\n")) 

maintenant faire l'intrigue, en utilisant la nouvelle variable trt2 sur l'axe x et en utilisant scales = "free_x" en facet_wrap pour permettre les différentes étiquettes par facette.

ggplot(test) +  
    geom_boxplot(aes(x = trt2, y = val, group = trt, colour = trt), show.legend = FALSE) + 
    facet_wrap(~ vis, drop = FALSE, switch="x", nrow = 1, scales = "free_x") + 
    labs(x="Visit") + 
    mytheme 

enter image description here

+0

Cela m'a fait la plupart du chemin. Malheureusement, 'scales =" free_x "' semble se battre avec 'drop = FALSE'. Dans mon contexte plus large, j'utilise grid.arrange pour faire un überplot qui inclut également un deuxième tracé pour le changement de Visit 1, et je veux arranger le plot 2 de sorte que (Vis2-Vis1) s'aligne visuellement avec Vis2 dans Plot 1.Cela marche bien sans mes labels grâce à drop = FALSE, mais quand j'ajoute scales = "free_x" il échoue avec le message d'erreur suivant: '" Erreur dans if (zero_range (from) || zero_range (to)) {: valeur manquante où TRUE/FALSE était nécessaire "' Je n'ai pas encore compris s'il existe une solution de contournement. – ErinMcJ

+0

@ErinMcJ Avez-vous un exemple? Vous pourriez poser une nouvelle question avec un exemple de votre situation réelle. Il se peut que l'annotation avec la taille de l'échantillon à l'intérieur du tracé ou l'évitement de facettes et l'utilisation de solutions de type gridExtra finissent par mieux fonctionner pour vous. – aosmith

+0

Merci. Voici la question de suivi plus complexe. http://stackoverflow.com/questions/39027770/annotating-x-axis-with-n-in-faceted-plot-but-preserve-empty-facets – ErinMcJ

1

Étant donné que cette fonctionnalité ne se construit pas dans un bon travail autour est grid.extra:

library(gridExtra) 
p1 <- ggplot(data[data$vis==1,]) +  geom_boxplot(aes(x=trt,y=val,group=trt,colour=trt), show.legend=FALSE) + 
    #facet_wrap(~ vis, drop=FALSE, switch="x", nrow=1) + 
    scale_x_discrete(labels=lb[1:2]) + #paste(data.sum$trt,data.sum$N,sep="\n") 
    labs(x="Visit") + mytheme 

p2 <- ggplot(data[data$vis==2,]) +  geom_boxplot(aes(x=trt,y=val,group=trt,colour=trt), show.legend=FALSE) + 
    #facet_wrap(~ vis, drop=FALSE, switch="x", nrow=1) + 
    scale_x_discrete(labels=lb[3:4]) + #paste(data.sum$trt,data.sum$N,sep="\n") 
    labs(x="Visit") + mytheme 

p3 <- ggplot(data[data$vis==3,]) +  geom_boxplot(aes(x=trt,y=val,group=trt,colour=trt), show.legend=FALSE) + 
    #facet_wrap(~ vis, drop=FALSE, switch="x", nrow=1) + 
    scale_x_discrete(labels=lb[5:6]) + #paste(data.sum$trt,data.sum$N,sep="\n") 
    labs(x="Visit") + mytheme 


grid.arrange(p1,p2,p3,nrow=1,ncol=3) # fully customizable 

enter image description here

connexes: Varying axis labels formatter per facet in ggplot/R

Vous pouvez également les faire verticale ou faire d'autres transformations:

enter image description here