J'ai utilisé la commande suivante ggplot:
ggplot(survey,aes(x=age))+stat_bin(aes(n=nrow(h3),y=..count../n), binwidth=10)
+scale_y_continuous(formatter = "percent", breaks=c(0, 0.1, 0.2))
+ facet_grid(hospital ~ .)
+ opts(panel.background = theme_blank())
produire
Je voudrais cependant changer les étiquettes facet en quelque chose de plus court (comme Hosp 1, Hosp 2 ...) car elles sont trop longues maintenant et ont l’air étriquées (augmenter la hauteur du graphique n’est pas une option). , cela prendrait trop de place dans le document). J'ai regardé la page facet_grid help mais je ne sais pas comment.
Modifiez les noms de niveau de facteur sous-jacents avec quelque chose comme:
# Using the Iris data
> i <- iris
> levels(i$Species)
[1] "setosa" "versicolor" "virginica"
> levels(i$Species) <- c("S", "Ve", "Vi")
> ggplot(i, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ .)
Voici une solution qui évite de modifier vos données:
Supposons que votre parcelle est facettée par la partie group
de votre cadre de données, qui a les niveaux control, test1, test2
, puis créez une liste nommée par ces valeurs:
hospital_names <- list(
'Hospital#1'="Some Hospital",
'Hospital#2'="Another Hospital",
'Hospital#3'="Hospital Number 3",
'Hospital#4'="The Other Hospital"
)
Créez ensuite une fonction 'étiqueteuse' et insérez-la dans votre appel facet_grid:
hospital_labeller <- function(variable,value){
return(hospital_names[value])
}
ggplot(survey,aes(x=age)) + stat_bin(aes(n=nrow(h3),y=..count../n), binwidth=10)
+ facet_grid(hospital ~ ., labeller=hospital_labeller)
...
Ceci utilise les niveaux du cadre de données pour indexer la liste hospital_names, en renvoyant les valeurs de la liste (les noms corrects).
Veuillez noter que cela ne fonctionne que si vous n'avez qu'une seule variable facettée. Si vous avez deux facettes, votre fonction d'étiquetage doit renvoyer un vecteur de nom différent pour chaque facette. Vous pouvez le faire avec quelque chose comme:
plot_labeller <- function(variable,value){
if (variable=='facet1') {
return(facet1_names[value])
} else {
return(facet2_names[value])
}
}
Où facet1_names
et facet2_names
sont des listes prédéfinies de noms indexés par les noms d'index de facettes ('Hostpital # 1', etc.).
Edit: La méthode ci-dessus échoue si vous transmettez une combinaison variable/valeur que l'étiqueteuse ne connaît pas. Vous pouvez ajouter une sécurité intrinsèque aux variables inconnues, comme ceci:
plot_labeller <- function(variable,value){
if (variable=='facet1') {
return(facet1_names[value])
} else if (variable=='facet2') {
return(facet2_names[value])
} else {
return(as.character(value))
}
}
Réponse adaptée de comment changer les étiquettes strip.text dans ggplot avec facette et marge = TRUE
edit: WARNING: si vous utilisez cette méthode comme facette avec une colonne caractère, vous obtiendrez peut-être des étiquettes incorrectes. Voir ce rapport de bogue . corrigé dans les versions récentes de ggplot2.
Voici une autre solution qui est dans l'esprit de celle donnée par @ naught101, mais plus simple et ne jette pas non plus d'avertissement sur la dernière version de ggplot2.
Fondamentalement, vous créez d'abord un vecteur de caractère nommé
hospital_names <- c(
`Hospital#1` = "Some Hospital",
`Hospital#2` = "Another Hospital",
`Hospital#3` = "Hospital Number 3",
`Hospital#4` = "The Other Hospital"
)
Et vous l’utilisez ensuite comme étiqueteuse, en modifiant simplement la dernière ligne du code donné par @ naught101
... + facet_grid(hospital ~ ., labeller = as_labeller(hospital_names))
J'espère que cela t'aides.
Voici comment je l'ai fait avec facet_grid(yfacet~xfacet)
en utilisant ggplot2, version 2.2.1:
facet_grid(
yfacet~xfacet,
labeller = labeller(
yfacet = c(`0` = "an y label", `1` = "another y label"),
xfacet = c(`10` = "an x label", `20` = "another x label")
)
)
Notez que cela ne contient pas d'appel à as_labeller()
- quelque chose avec lequel j'ai lutté pendant un moment.
Cette approche s’inspire du dernier exemple de la page d’aide Fonction de forçage en étiqueteuse .
Si vous avez deux facettes hospital
et room
mais que vous souhaitez renommer une seule, vous pouvez utiliser:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names)))
Pour renommer deux facettes en utilisant l'approche vectorielle (comme dans la réponse de naught101), vous pouvez faire:
facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names),
room = as_labeller(room_names)))
Cette solution est très proche de celle de @domi, mais est conçue pour raccourcir le nom en récupérant les 4 premières lettres et le dernier numéro.
library(ggplot2)
# simulate some data
xy <- data.frame(hospital = rep(paste("Hospital #", 1:3, sep = ""), each = 30),
value = rnorm(90))
shortener <- function(string) {
abb <- substr(string, start = 1, stop = 4) # fetch only first 4 strings
num <- gsub("^.*(\\d{1})$", "\\1", string) # using regular expression, fetch last number
out <- paste(abb, num) # put everything together
out
}
ggplot(xy, aes(x = value)) +
theme_bw() +
geom_histogram() +
facet_grid(hospital ~ ., labeller = labeller(hospital = shortener))
Notez que cette solution ne fonctionnera pas correctement si ggplot affichera moins de facteurs que votre variable n'en contient (ce qui pourrait arriver si vous aviez par exemple sous-défini):
library(ggplot2)
labeli <- function(variable, value){
names_li <- list("versicolor"="versi", "virginica"="virg")
return(names_li[value])
}
dat <- subset(iris,Species!="setosa")
ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli)
Une solution simple (en plus d'ajouter tous les facteurs inutilisés dans names_li, ce qui peut s'avérer fastidieux) consiste à supprimer les facteurs inutilisés avec droplevels (), soit dans le jeu de données d'origine, soit dans la fonction labbeler, voir:
labeli2 <- function(variable, value){
value <- droplevels(value)
names_li <- list("versicolor"="versi", "virginica"="virg")
return(names_li[value])
}
dat <- subset(iris,Species!="setosa")
ggplot(dat, aes(Petal.Length)) + stat_bin() + facet_grid(Species ~ ., labeller=labeli2)
facet_wrap
et facet_grid
acceptent également les entrées de ifelse
en tant qu'argument. Donc, si la variable utilisée pour le facettage est logique, la solution est très simple:
facet_wrap(~ifelse(variable, "Label if true", "Label if false"))
Si la variable a plus de catégories, l'instruction ifelse
doit être imbriquée .
En tant qu'effet secondaire, cela permet également à la création des groupes d'être facettée dans l'appel ggplot
.
Ajout d'une autre solution similaire à @ domi avec l'analyse de symboles mathématiques, exposant, indice, parenthèse/crochet, .etc.
library(tidyverse)
theme_set(theme_bw(base_size = 18))
### create separate name vectors
# run `demo(plotmath)` for more examples of mathematical annotation in R
am_names <- c(
`0` = "delta^{15}*N-NO[3]^-{}",
`1` = "sqrt(x,y)"
)
# use `scriptstyle` to reduce the size of the parentheses &
# `bgroup` to make adding `)` possible
cyl_names <- c(
`4` = 'scriptstyle(bgroup("", a, ")"))~T~-~5*"%"',
`6` = 'scriptstyle(bgroup("", b, ")"))~T~+~10~degree*C',
`8` = 'scriptstyle(bgroup("", c, ")"))~T~+~30*"%"'
)
ggplot(mtcars, aes(wt, mpg)) +
geom_jitter() +
facet_grid(am ~ cyl,
labeller = labeller(am = as_labeller(am_names, label_parsed),
cyl = as_labeller(cyl_names, label_parsed))
) +
geom_text(x = 4, y = 25, size = 4, Nudge_y = 1,
parse = TRUE, check_overlap = TRUE,
label = as.character(expression(paste("Log"["10"], bgroup("(", frac("x", "y"), ")")))))
### OR create new variables then assign labels directly
# reverse facet orders just for fun
mtcars <- mtcars %>%
mutate(am2 = factor(am, labels = am_names),
cyl2 = factor(cyl, labels = rev(cyl_names), levels = rev(attr(cyl_names, "names")))
)
ggplot(mtcars, aes(wt, mpg)) +
geom_jitter() +
facet_grid(am2 ~ cyl2,
labeller = label_parsed) +
annotate("text", x = 4, y = 30, size = 5,
parse = TRUE,
label = as.character(expression(paste("speed [", m * s^{-1}, "]"))))
Créé le 2019-03-30 par le paquet reprex (v0.2.1.9000)
La définition de la fonction d'étiquetage avec variable, value
comme argument ne fonctionnerait pas pour moi. De même, si vous souhaitez utiliser une expression, vous devez utiliser lapply et ne pas simplement utiliser arr[val]
, car l'argument de la fonction est un nom data.frame.
Ce code a fonctionné:
libary(latex2exp)
library(ggplot2)
arr <- list('virginica'=TeX("x_1"), "versicolor"=TeX("x_2"), "setosa"=TeX("x_3"))
mylabel <- function(val) { return(lapply(val, function(x) arr[x])) }
ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) + geom_line() + facet_wrap(~Species, labeller=mylabel)
Je pense que toutes les autres solutions sont vraiment utiles pour le faire, mais il existe encore un autre moyen.
Je suppose:
dplyr
, qui contient la commande pratique mutate
, et votre jeu de données s'appelle survey
.
enquête%>% mutez (Hosp1 = Hospital1, Hosp2 = Hospital2, ........)
Cette commande vous aide à renommer les colonnes, mais toutes les autres colonnes sont conservées.
Ensuite, faites la même chose avec facet_wrap
, tout va bien maintenant.
Étant donné que je ne suis pas encore autorisé à commenter les messages, je le publie séparément sous la forme d'un addendum à la réponse de Vince et la réponse de son520804 . Le crédit leur revient.
Son520804:
en utilisant les données Iris:
Je suppose:
Vous avez installé le package dplyr, qui contient la commande pratique mutate, et votre jeu de données s'appelle survey .survey %>% mutate(Hosp1 = Hospital1, Hosp2 = Hospital2,........)
Cette commande vous aide à renommer les colonnes, mais toutes les autres colonnes sont conservées . Ensuite, faites la même chose facet_wrap, vous allez bien maintenant.
En utilisant l'exemple de l'iris de Vince et le code partiel de son520804, je l'ai fait avec la fonction mutate et j'ai obtenu une solution simple sans toucher au jeu de données d'origine . L'astuce consiste à créer un vecteur de nom de remplacement et à utiliser mutate (). à l'intérieur du tuyau pour corriger temporairement les noms de facettes:
i <- iris
levels(i$Species)
[1] "setosa" "versicolor" "virginica"
new_names <- c(
rep("Bristle-pointed iris", 50),
rep("Poison flag iris",50),
rep("Virginia iris", 50))
i %>% mutate(Species=new_names) %>%
ggplot(aes(Petal.Length))+
stat_bin()+
facet_grid(Species ~ .)
Dans cet exemple, vous pouvez voir que les niveaux de i $ Species sont temporairement modifiés en noms communs correspondants contenus dans le vecteur new_names. La ligne contenant
mutate(Species=new_names) %>%
peut facilement être retiré pour révéler le nom d'origine.
Mot d'avertissement: Cela peut facilement introduire des erreurs dans les noms si le vecteur new_name n'est pas correctement configuré. Il serait probablement beaucoup plus propre d'utiliser une fonction distincte pour remplacer les chaînes de variables. N'oubliez pas que le vecteur new_name peut devoir être répété de différentes manières pour correspondre à l'ordre de votre jeu de données d'origine. S'il vous plaît double et triple vérifier que cela est correctement réalisé.
Le moyen le plus facile de changer sans modifier les données sous-jacentes est:
1) Créez un objet à l'aide de la fonction as_labeller
en ajoutant la coche arrière pour chacune des valeurs par défaut :
hum.names <- as_labeller(c(`50` = "RH% 50", `60` = "RH% 60",`70` = "RH% 70", `80` = "RH% 80",`90` = "RH% 90", `100` = "RH% 100")) #Necesarry to put RH% into the facet labels
2) Nous ajoutons dans le GGplot:
ggplot(dataframe, aes(x=Temperature.C,y=fit))+geom_line()+ facet_wrap(~Humidity.RH., nrow=2,labeller=hum.names)
J'ai un autre moyen d'atteindre le même objectif sans changer les données sous-jacentes:
ggplot(transform(survey, survey = factor(survey,
labels = c("Hosp 1", "Hosp 2", "Hosp 3", "Hosp 4"))), aes(x = age)) +
stat_bin(aes(n = nrow(h3),y=..count../n), binwidth = 10) +
scale_y_continuous(formatter = "percent", breaks = c(0, 0.1, 0.2)) +
facet_grid(hospital ~ .) +
opts(panel.background = theme_blank())
Ce que j'ai fait ci-dessus, c'est changer les étiquettes du facteur dans le bloc de données d'origine, et c'est la seule différence par rapport à votre code d'origine.
Étendre juste la réponse de naught101 - le mérite lui revient
plot_labeller <- function(variable,value, facetVar1='<name-of-1st-facetting-var>', var1NamesMapping=<pass-list-of-name-mappings-here>, facetVar2='', var2NamesMapping=list() )
{
#print (variable)
#print (value)
if (variable==facetVar1)
{
value <- as.character(value)
return(var1NamesMapping[value])
}
else if (variable==facetVar2)
{
value <- as.character(value)
return(var2NamesMapping[value])
}
else
{
return(as.character(value))
}
}
Ce que vous devez faire est de créer une liste avec un mappage de nom en nom
clusteringDistance_names <- list(
'100'="100",
'200'="200",
'300'="300",
'400'="400",
'600'="500"
)
et redéfinissez plot_labeller()
avec les nouveaux arguments par défaut:
plot_labeller <- function(variable,value, facetVar1='clusteringDistance', var1NamesMapping=clusteringDistance_names, facetVar2='', var1NamesMapping=list() )
Et alors:
ggplot() +
facet_grid(clusteringDistance ~ . , labeller=plot_labeller)
Vous pouvez également créer une fonction dédiée pour chacune des modifications d'étiquette que vous souhaitez apporter.
Cela fonctionne pour moi.
Définir un facteur:
hospitals.factor<- factor( c("H0","H1","H2") )
et utiliser, en ggplot()
:
facet_grid( hospitals.factor[hospital] ~ . )
Avez-vous essayé de modifier les niveaux spécifiques de votre vecteur Hospital
?
levels(survey$hospital)[levels(survey$hospital) == "Hospital #1"] <- "Hosp 1"
levels(survey$hospital)[levels(survey$hospital) == "Hospital #2"] <- "Hosp 2"
levels(survey$hospital)[levels(survey$hospital) == "Hospital #3"] <- "Hosp 3"