Mes données sont visualisées dans le package ggplot2 via des graphiques à barres avec plusieurs (~ 10) facettes. Je veux d'abord diviser ces facettes en plusieurs rangées. Je peux utiliser la fonction facet_grid() ou facet_wrap() pour cela. Dans les données d'exemple minimales ici, je construis 8 facettes en deux lignes (4x2). Cependant, je dois ajuster les échelles pour différentes facettes, à savoir: la première ligne contient des données à petite échelle, et dans la deuxième ligne, les valeurs sont plus grandes. J'ai donc besoin d'avoir la même échelle pour toutes les données de la première ligne pour les comparer le long de la ligne, et une autre échelle pour la deuxième ligne.

Voici l'exemple minimal et les solutions possibles.

#loading necessary libraries and example data
library(dplyr)
library(tidyr)
library(ggplot2)

trial.facets<-read.csv(text="period,xx,yy
A,2,3
B,1.5,2.5
C,3.2,0.5
D,2.5,1.5
E,11,13
F,16,14
G,8,5
H,5,4")

#arranging data to long format with omission of the "period" variable
trial.facets.tidied<-trial.facets %>% gather(key=newvar,value=newvalue,-period)

Et maintenant se traçant:

#First variant
ggplot(trial.facets.tidied,aes(x=newvar,y=newvalue,position="dodge"))+geom_bar(stat ="identity") +facet_grid(.~period)

#Second variant:
ggplot(trial.facets.tidied,aes(x=newvar,y=newvalue,position="dodge"))+geom_bar(stat ="identity") +facet_wrap(~period,nrow=2,scales="free")

Les résultats pour les première et deuxième variantes sont les suivants:

enter image description here

Dans les deux exemples, nous avons soit des échelles libres pour tous les graphiques, soit des échelles fixes pour tous les graphiques. Pendant ce temps, la première ligne (4 premières facettes) doit être mise à l'échelle quelque peu à 5 et la deuxième ligne à 15.

Comme solution pour utiliser la fonction facet_grid(), je peux ajouter une fausse variable "ligne" qui spécifie, à quelle ligne doit appartenir la lettre correspondante. Le nouvel ensemble de données trial.facets.row (trois lignes affichées uniquement) ressemblerait à ceci:

period,xx,yy,row
C,3.2,0.5,1
D,2.5,1.5,1
E,11,13,2

Ensuite, je peux effectuer le même réarrangement en format long, en omettant les variables «période» et «ligne»:

trial.facets.tidied.2<-trial.facets.row %>% gather(key=newvar,value=newvalue,-period,-row)

Ensuite, j'arrange les facettes le long des variables "ligne" et "période" dans l'espoir d'utiliser l'option scales="free_y" pour ajuster les échelles uniquement sur les lignes:

ggplot(trial.facets.tidied.2,aes(x=newvar,y=newvalue,position="dodge"))+geom_bar(stat ="identity") +facet_grid(row~period,scales="free_y")

Et - surprise: le problème des échelles est résolu, cependant, j'obtiens deux groupes de barres vides, et toutes les données sont à nouveau étirées sur une longue bande:

enter image description here

Toutes les pages de manuel et manuels découverts (utilisant généralement l'ensemble de données mpg et mtcars) ne prennent pas en compte une telle situation de telles données indésirables ou factices

3
astrsk 15 août 2017 à 03:03

2 réponses

Cette approche trace une ligne invisible au maximum pour chaque ligne

#loading necessary libraries and example data
library(dplyr)
library(tidyr)
library(ggplot2)

trial.facets<-read.csv(text="period,xx,yy
                       A,2,3
                       B,1.5,2.5
                       C,3.2,0.5
                       D,2.5,1.5
                       E,11,13
                       F,16,14
                       G,8,5
                       H,5,4")

# define desired number of columns
n_col <- 4

#assign a row number - mmnsodulo number of colu
trial.facets$row <- seq(0, nrow(trial.facets)-1)  %/% n_col

# determine the max by row, and round up to nearest multiple of 5
# join back to original
trial.facets.max <- trial.facets %>% 
  group_by(row) %>% 
  summarize(maxvalue = (1 + max(xx, yy) %/% 5) * 5 )
trial.facets <- trial.facets %>% inner_join(trial.facets.max)

# make long format carrying period, row and maxvalue
trial.facets.tidied<-trial.facets %>% gather(key=newvar,value=newvalue,-period,-row,-maxvalue)

# plot an invisible line at the max
ggplot(trial.facets.tidied,aes(x=newvar,y=newvalue,position="dodge"))+
  geom_bar(stat ="identity") +
  geom_hline(aes(yintercept=maxvalue), alpha = 0) +
  facet_wrap(~period,ncol=n_col,scales="free")

enter image description here

2
Andrew Lavers 15 août 2017 à 01:53

En examinant SO, j'ai rencontré une solution qui pourrait être un peu délicate - d'ici

L'idée est de créer un deuxième faux ensemble de données qui tracerait un seul point à chaque facette. Ce point sera dessiné dans la position, correspondant à la valeur souhaitée la plus élevée pour l'échelle y dans tous les cas. Ainsi, les hauteurs des échelles peuvent être ajustées manuellement pour chaque facette. Voici la solution pour l'ensemble de données en question. Nous voulons l'échelle y (valeur y maximale) de 5 pour la première ligne et de 17 pour la deuxième ligne. Alors créez

df3=data.frame(newvar = rep("xx",8),    
               period = c("A","B","C","D","E","F","G","H"),
               newvalue = c(5,5,5,5,17,17,17,17))

Et maintenant, superposez les nouvelles données sur notre graphique en utilisant geom_point ().

ggplot(trial.facets.tidied,aes(x=newvar,y=newvalue,position="dodge"))+
   geom_bar(stat ="identity") +
   facet_wrap(~period,nrow=2,scales="free_y")+
   geom_point(data=df3,aes(x=newvar,y=newvalue),alpha=1)

Voici ce que nous obtenons:

barplot with fake points, fixing the scale

Ici, je dessine intentionnellement ce point supplémentaire pour clarifier les choses. Ensuite, nous devons le rendre invisible, ce qui peut être réalisé en définissant alpha=0 au lieu de 1 dans la dernière commande.

3
Cole 30 août 2019 à 19:31