problems with converting a string into a variable name and use it for plot in a loop in R

Viewed 66

I want to make a series of plots with a for loop, then store all the plots in a list, and at last print all the plots to a .pdf file. All my y variable names are stored in a char vector, and I need to loop through this vector to make a plot for each of them.

data <- data.frame(index = seq(1, 10, 1), var1 = (1:10)^2, var2 = (1:10)^3, var3 = (1:10) ^4)
varnames <- c("var1", "var2", "var3") # store all the names in a char vector. 
plot.list <- list() # make a list to store the result
for (i in varnames) {
  plot.list[[i]] = 
    ggplot(data, aes(x = index, y = as.name(i))) +
  geom_point() 
}

Here are my questions:

  1. when I used y = as.name(i) to convert each element of varnames into a varible name, I got an error. The error is like this:

Don't know how to automatically pick scale for object of type name. Defaulting to continuous. Error: Aesthetics must be valid data columns. Problematic aesthetic(s): y = as.name(i). Did you mistype the name of a data column or forget to add after_stat()?

Why did this happen and how to resolve it?

  1. I want to store each plot into the plot.list, is this the right way to do it?

plot.list = some_plot_funtion()

  1. How to plot all the elements in the plot.list to a .pdf Thanks.
2 Answers

You can use lapply to plot since it returns a list by default.

library(ggplot2)

plot.list <- lapply(varnames, function(x) 
                    ggplot(data, aes(index, .data[[x]])) + geom_point())


ggsave(filename = "plots.pdf", 
  plot = gridExtra::marrangeGrob(plot.list, nrow=1, ncol=1), 
  width = 15, height = 9)

You can adjust width and height as per your choice.

Try this very minor modification of your code. The get function acts in the manner both you and I think that as.name should work (but doesn't):

data <- data.frame(index = seq(1, 10, 1), var1 = (1:10)^2, var2 = (1:10)^3, var3 = (1:10) ^4)
varnames <- c("var1", "var2", "var3") # store all the names in a char vector. 
plot.list <- list() # make a list to store the result
for (i in varnames) {
    p = 
        ggplot(data, aes(x = index, y = get(i) )) +
        geom_point() ;  print(p); plot.list[[i]] <- p
}

You also need to do something to force evaluation of the print object. I tried using force but that failed. So I used print which does have the disadvantage of a side-effect of getting the individual plots to appear on your active graphics device.

Related