How to change facet labels?

后端 未结 20 1668
既然无缘
既然无缘 2020-11-22 14:50

I have used the following ggplot command:

ggplot(survey, aes(x = age)) + stat_bin(aes(n = nrow(h3), y = ..count.. / n), binwidth = 10)
  + scale         


        
相关标签:
20条回答
  • 2020-11-22 15:14

    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.

    0 讨论(0)
  • 2020-11-22 15:15

    If you have two facets hospital and room but want to rename just one, you can use:

    facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names)))
    

    For renaming two facets using the vector-based approach (as in naught101's answer), you can do:

    facet_grid( hospital ~ room, labeller = labeller(hospital = as_labeller(hospital_names),
                                                     room = as_labeller(room_names)))
    
    0 讨论(0)
  • 2020-11-22 15:19

    I have another way to achieve the same goal without changing the underlying data:

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

    What I did above is changing the labels of the factor in the original data frame, and that is the only difference compared with your original code.

    0 讨论(0)
  • 2020-11-22 15:20

    Since I'm not yet allowed to comment on posts, I'm posting this separately as an addendum to Vince's answer and son520804's answer . Credit goes to them.

    Son520804:

    using Iris data:

    I assume:
    You have installed the dplyr package, which has the convenient mutate command, and your dataset is named survey. survey %>% mutate(Hosp1 = Hospital1, Hosp2 = Hospital2,........) This command helps you to rename columns, yet all other columns are kept. Then do the same facet_wrap, you are fine now.

    Using the iris example of Vince and the partial code of son520804, I did this with the mutate function and achieved an easy solution without touching the original dataset. The trick is to create a stand-in name vector and use mutate() inside the pipe to correct the facet names temporarily:

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

    In this example you can see the levels of i$Species is temporarily changed to corresponding common names contained in the new_names vector. The line containing

    mutate(Species=new_names) %>%
    

    can easily be removed to reveal the original naming.

    Word of caution: This may easily introduce errors in names if the new_name vector is not correctly set up. It would probably be much cleaner to use a separate function to replace the variable strings. Keep in mind that the new_name vector may need to be repeated in different ways to match the order of your original dataset. Please double - and - triple check that this is correctly achieved.

    0 讨论(0)
  • 2020-11-22 15:20

    This is working for me.

    Define a factor:

    hospitals.factor<- factor( c("H0","H1","H2") )
    

    and use, in ggplot():

    facet_grid( hospitals.factor[hospital] ~ . )
    
    0 讨论(0)
  • 2020-11-22 15:21

    Change the underlying factor level names with something like:

    # 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 ~ .)
    
    0 讨论(0)
提交回复
热议问题