3

I am trying to plot multiple factor columns in one go, using ggplot2 as plotting engine.

Plotting multiple metric columns is straight forward:

library(ggplot2)
library(dplyr) # dplyr 0.5.0 select_if
library(purrr)
data(diamonds)


diamonds %>% 
  select_if(is.numeric) %>% 
  gather %>% 
  ggplot(aes(x = value)) + 
  geom_histogram() + 
  facet_wrap(~key)

plot multiple quantitative variables

However, I did not success in plotting multiple factor (qualitative) columns in one shot. I would like to choose columns programmatically, ie., not directly naming them.

I tried this, but it does not produce a sensible result:

diamonds %>% 
  select_if(is.factor) %>% 
  gather %>% 
  ggplot(aes(x = value)) + geom_bar() +
  facet_wrap(~key) +
  coord_flip()

enter image description here

I assume that there might a solution along these lines:

diamonds %>% 
  select_if(is.factor) %>% 
  ggplot(aes(x = .[[1]])) + geom_bar()

Where .[[1]] should be replaced by some column placeholder (so here I directly named the column, which I would like to avoid, as I have a large number of columns in reality).

A for-loop will probably do the job, but I would like to get there with dplyr.

2
  • 1
    Could you explain what you would consider a sensible result, i.e. how your second figure differs from your desired output? Is the main problem the the fact that each plot doesn't have its own Y-axis (and therefore the alphabetical sorting is pretty meaningless)? Commented Jul 4, 2016 at 12:16
  • 1
    #mkt, thanks for your comment, #Axeman had a good idea, that was what I was looking for Commented Jul 4, 2016 at 17:57

2 Answers 2

3

The trick here is to use scales = free within your facet call. For example:

diamonds %>% 
    select_if(is.factor) %>% 
    gather %>% 
    ggplot(aes(x = value)) + geom_bar() +
    facet_wrap(~key, scales = 'free') +
    theme_bw() +
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))

enter image description here

Unfortunately free scales and coord_flip don't play nice. You can either use geom_barh from the ggstance package. Or you can use lapply on each column to get a list of ggplot objects and use the cowplot package to stitch them together in one figure.

Sign up to request clarification or add additional context in comments.

1 Comment

It just came to my mind that lapply might also be a way, maybe easier to play together with coord_flip@Axeman
1

Maybe less elegant than @Axeman, but also working, and cooperates with coord_flip:

library(gridExtra)


gg_bar <- function(x, ...){
  { 
    ggplot(data_frame(x), aes(x = x)) + 
      geom_bar() +
      coord_flip() 
  }
}

diamonds %>% 
  select_if(negate(is.numeric)) %>% 
  lapply(., function(x) gg_bar(x)) -> gg_bar_list

do.call(grid.arrange, gg_bar_list)

enter image description here

However, the name of the variable ("x") is not shown, that's not too beautiful.

1 Comment

See cowplot::plot_grid instead of grid.arrange to do automatic alignment and subplot annotation. You can use the annotations as variable labels, and not show the y-axis label.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.