Search code examples
rplotpnglapplypar

How to save several plots generated from par(mfrow) and lapply?


I am trying to save in my pc all the plots obtained using par(mfrow). The idea is to save each png image adding a number to avoid replacements.

This is a toy example were I use lapply and par(mfrow) to generate several histograms.

par(mfrow=c(1,2))
  lapply(1:ncol(mtcars), function(x){
    hist(mtcars[,x])
  })

Something that I have tried (without success) is to use another lapply to save the images with different names.

lapply(1:ceiling(ncol(mtcars)/2), function(n){
  
  png(paste0("../Desktop/histogram_", n, ".png"))
  
  par(mfrow=c(1,2))
  lapply(1:ncol(mtcars), function(x){
    hist(mtcars[,x])
  })
  dev.off()
})

It works at 50%. It saves the different histograms with different names, but it saves the last plot several times.

How can I save the first plot till the last one?

Important note: I don't want to save each individual histogram, I want to save each pair of histograms that are kept in each image.

I found a similar post to do this, but it uses a for loop and if statements (something that I want to avoid).

Any help will be very appreciated.

Thanks in advance


Solution

  • How about

    lapply(
      seq(1, ncol(mtcars), 2),
      function(x) {
        png(paste0("histogram_", x, ".png"))
        par(mfrow=c(1, 2))
        hist(mtcars[, x])
        if (x < ncol(mtcars)) hist(mtcars[, (x+1)])
        dev.off()
      }
    )
    

    which runs the function on pairs of columns...

    Here is a variation that will work for any number of rows and columns and any data frame (that contains only numeric columns).

    makePlots <- function(df, nr, nc) {
      k <- nr * nc
      lapply(
        seq(1, ncol(df), k),
        function(x, df, nr, nc) {
          png(paste0("histogram_", x, ".png"))
          par(mfrow=c(nr, nc))
          for (z in x:(x+k-1)) {
            if (z <= ncol(df)) hist(df[, z])
          }
          dev.off()
        },
        nr = nr,
        nc = nc,
        df = df
      )
    }
    
    makePlots(mtcars, 3, 2)