1
votes

I'd like to loop through columns with purrr::map and print a histogram for each of them. This works.

library(tidyverse)
library(patchwork)

iris %>% # example data
  select(-Species) %>% # drop one non-numeric col
  map( ~ ggplot(iris, aes(x = .)) + # loop through cols... for col, take it as x aes
         geom_histogram() # graph histogram
       ) %>% # output is list of graphs
  wrap_plots() # wrap list using patchwork

But the graphs are pretty cryptic without titles to tell you which graph belongs to which column.

I tried adding a ggtitle option.

library(tidyverse)
library(patchwork)

iris %>% 
  select(-Species) %>% 
  map( ~ ggplot(iris, aes(x = .)) + 
         geom_histogram() +
         ggtitle(.)
       ) %>% 
  wrap_plots()

However, it prints the first value of each column as the title, not the colname.

head(iris, 1) # for reference

What should I be doing differently to get colnames as graph titles for the individual graphs? I can make do with proper x axis labels as well.

2
If you use map2() one can reference a second vector of column names in the pipeline as illustrated in my answer.Len Greski

2 Answers

2
votes

This doesn't answer your question exactly, but if your use case is EDA only, you can take a massive shortcut and just use the skimr package. Basic histograms are printed in the console output.

skimr::skim(iris)


Skim summary statistics
 n obs: 150 
 n variables: 5 

-- Variable type:factor --------------------------------------------------------
 variable missing complete   n n_unique                       top_counts ordered
  Species       0      150 150        3 set: 50, ver: 50, vir: 50, NA: 0   FALSE

-- Variable type:numeric -------------------------------------------------------
     variable missing complete   n mean   sd  p0 p25  p50 p75 p100     hist
 Petal.Length       0      150 150 3.76 1.77 1   1.6 4.35 5.1  6.9 ▇▁▁▂▅▅▃▁
  Petal.Width       0      150 150 1.2  0.76 0.1 0.3 1.3  1.8  2.5 ▇▁▁▅▃▃▂▂
 Sepal.Length       0      150 150 5.84 0.83 4.3 5.1 5.8  6.4  7.9 ▂▇▅▇▆▅▂▂
  Sepal.Width       0      150 150 3.06 0.44 2   2.8 3    3.3  4.4 ▁▂▅▇▃▂▁▁
2
votes

Update: A solution with map2() is as follows. By extracting the column names to a separate vector as the .y argument, we can use it as the argument to xlab().

iris %>% 
     select(-Species) %>% 
     map2(.,.y = colnames(.), ~ ggplot(iris, aes(x = .x)) + 
               geom_histogram() +
               xlab(.y)
     ) %>% 
     wrap_plots()

...and the output:

enter image description here

Original Post: One solution with lapply() looks like this.

chartList <- lapply(1:4,function(y){
     ggplot(iris, aes(x = iris[[y]])) + 
          geom_histogram() +
          ggtitle(colnames(iris[y]))

})
wrap_plots(chartList)

...and the output:

enter image description here

We can clean things up a bit if we replace ggtitle() with xlab() so the label prints below the x axis.

chartList <- lapply(1:4,function(y){
     ggplot(iris, aes(x = iris[[y]])) + 
          geom_histogram() +
          xlab(colnames(iris[y]))

})
wrap_plots(chartList) 

enter image description here