Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
339 views
in Technique[技术] by (71.8m points)

r - How to change facet labels?

I have used the following ggplot command:

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 ~ .)
  + theme(panel.background = theme_blank())

to produce

alt text

I'd like to change the facet labels, however, to something shorter (like Hosp 1, Hosp 2...) because they are too long now and look cramped (increasing the height of the graph is not an option, it would take too much space in the document). I looked at the facet_grid help page but cannot figure out how.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here is a solution that avoids editing your data:

Say your plot is facetted by the group part of your dataframe, which has levels control, test1, test2, then create a list named by those values:

hospital_names <- list(
  'Hospital#1'="Some Hospital",
  'Hospital#2'="Another Hospital",
  'Hospital#3'="Hospital Number 3",
  'Hospital#4'="The Other Hospital"
)

Then create a 'labeller' function, and push it into your facet_grid call:

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)
 ...

This uses the levels of the data frame to index the hospital_names list, returning the list values (the correct names).


Please note that this only works if you only have one faceting variable. If you have two facets, then your labeller function needs to return a different name vector for each facet. You can do this with something like :

plot_labeller <- function(variable,value){
  if (variable=='facet1') {
    return(facet1_names[value])
  } else {
    return(facet2_names[value])
  }
}

Where facet1_names and facet2_names are pre-defined lists of names indexed by the facet index names ('Hostpital#1', etc.).


Edit: The above method fails if you pass a variable/value combination that the labeller doesn't know. You can add a fail-safe for unknown variables like this:

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))
  }
}

Answer adapted from how to change strip.text labels in ggplot with facet and margin=TRUE


edit: WARNING: if you're using this method to facet by a character column, you may be getting incorrect labels. See this bug report. fixed in recent versions of ggplot2.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...