linus
linus

Reputation: 457

How to make for-loop work in order to automate plotting

I have

My intent is to plot (scatter) value1 over years and value2 over years somewhat automatically (using scatterplot function and my for loop).

For some reason, the for loop below only generates one plot (the last one in my df). Can someone tell me what I am missing?

for loop:

# Create the loop.vector (all the columns)
loop.vector <- ncol(df)-1

for (i in loop.vector) { # Loop over loop.vector
        
        # store data in column.i as x
        x <- df[i]

        x = unlist(x) #necessary. otherwise ggplot will generate an error
        
        plotname = colnames(df[i])
        
        #plot
        
        jpeg(filename=paste0("/R-Outputs/plots/",plotname,".jpeg"))
        
        plot= ScatterPlot(df,df$year,"year", x, plotname)
       
        print(plot)
        
        dev.off()
}

Scatterplot Function (this works):

ScatterPlot <- function(df, x, x_var_label,y, y_var_label) {
# Input: 
#     df: a data frame
#     x: a column from df in the form of a character vector
#     y: a column from df in the form of a character vector
#
# Output:
#     a ggplot2 plot

require(ggplot2)
        
x_title = x_var_label
y_title = y_var_label
        
time_labels = c("2018", "2019", "2020")
        
ggplot(data = df, aes(x = x, y = y)) +
        geom_point(col="#69b3a2",fill="#69b3a2",alpha=0.5, size = 0) +
        geom_line()+
        geom_smooth(method = "lm", se = FALSE, size = 0.8, col="red") +
        xlab(label = x_title) +
        ylab(label = y_title) +
        theme_bw()+
        theme(axis.text.x=element_text(angle=45, hjust = 1))+
        labs(title = paste0(y_title," over time"))+
        scale_x_continuous("year", labels = as.character(time_labels), 
        breaks = as.integer((time_labels)))
        
}

Upvotes: 1

Views: 815

Answers (1)

Ronak Shah
Ronak Shah

Reputation: 389325

You don't need to pass both values as well as column name. Pass only the column name in the function ScatterPlot.

library(ggplot2)

ScatterPlot <- function(df, x_var_label,y_var_label) {
  # Input: 
  #     df: a data frame
  #     x: a column from df in the form of a character vector
  #     y: a column from df in the form of a character vector
  #
  # Output:
  #     a ggplot2 plot
  
  time_labels = c("2018", "2019", "2020")
  
  ggplot(data = df, aes(x = .data[[x_var_label]], y = .data[[y_var_label]])) +
    geom_point(col="#69b3a2",fill="#69b3a2",alpha=0.5, size = 0) +
    geom_line()+
    geom_smooth(method = "lm", se = FALSE, size = 0.8, col="red") +
    xlab(label = x_var_label) +
    ylab(label = y_var_label) +
    theme_bw()+
    theme(axis.text.x=element_text(angle=45, hjust = 1))+
    labs(title = paste0(y_var_label," over time"))+
    scale_x_continuous("year", labels = time_labels, 
                       breaks = as.integer(time_labels))
  
}

To call this function in a loop something like this should work.

#column names to loop over
loop.vector <- names(df[-1])
plot <- vector('list', length(loop.vector))

for (i in seq_along(loop.vector)) { # Loop over loop.vector
  jpeg(filename=paste0("/R-Outputs/plots/",loop.vector[i],".jpeg"))
  plot[[i]] = ScatterPlot(df,"year", loop.vector[i])
  print(plot[[i]])
  dev.off()
}

We are also saving individual plots in a list which you can verify with plot[[1]], plot[[2]] etc.

Upvotes: 1

Related Questions