Create plots in a loop using mapply()

There are three things needed to create plots in a loop (according to the way I do things):

1. A vertically-split data frame
2. A user-defined plotting function
3. mapply()

Since I rewrote my FRED.example3.R script with this technique, I will use it as the example here. I rewrote the distribution plots to be built in a loop using mapply(). You can follow along with the example by going to this website to download (View Raw) the agg.2013 data frame .RData file.

Step 1 – Vertically split the data frame

  1. We will create a custom function that takes two arguments:
    1. A data frame with the both columns we want to plot and the column by which we want to facet the data
    2. A character string of the facet variable (i.e. "PartyWinner")
  2. Within the function, a second user-defined function will be constructed which does two things:
    1. Assigns both a single variable and the facet variable to a data frame
    2. Assigns the column names c("Variable", "Facet") to the data frame
  3. The second user-defined function will then be ran within an lapply() function
  4. Variable names will then be assigned to the list
  5. The list of data frames will be returned
split.agg <- function(data, facet = NULL){
    if(!is.null(facet) & (facet %in% names(data))){
        data2 <- data[, !names(data) %in% facet]
    } else{
        data2 <- data
    split.df <- function(x, facet){
        shdw.list <- data.frame()        ## to hold data in loop
        shdw.list <- data[,c(x, facet)]
        colnames(shdw.list) <- c("Variable", "Facet")
    agg.list <- lapply(names(data2), split.df, facet = facet)
    names(agg.list) <- names(data2)              ## name it

Step 2 – Create a user-defined plotting function

  1. Using ggplot2 we will create a ggplot object that sets the data and declares the mappings
  2. Then we will create layers (histogram and density plots)
  3. Then we will assign colors for the two facet variable values (Democrat and Republican)
  4. Then we will facet the data
  5. Then we will add mean and median lines to the plot
dist.plot <- function(.data,, facet.exists = TRUE){
    ### check to see if a facet exists in the data frame
            Facet = NULL
    ### begin writing the plot
        ggplot(data = .data, mapping = aes(x = Variable, fill = Facet)) +
            xlab( +
            geom_histogram(aes(y = ..density..), bins =  50, alpha = .5) +
            geom_density(aes(color = Facet), alpha = .1) +
            scale_color_manual(values = c("#0000FF", "#FF0000")) +
            scale_fill_manual(values = c("#0000FF", "#FF0000")) +
            facet_grid(. ~ Facet) +
            geom_vline(data = .data,
                       aes(xintercept = mean(Variable),linetype = "dashed"),
                       size = 1) +
            geom_vline(data = .data,
                       aes(xintercept = median(Variable), linetype="solid"),
                       size = 1) +
            scale_linetype_identity(guide="legend", label = c("Mean", "Median"))

Step 3 – Run the split data frame (list) through the new function in a mapply() loop

  1. Now, it’s just a matter of supplying two lists to the dist.plot function:
    1. The list of data frames
    2. The names of the data frames in the list
    distribution.plots <- mapply(FUN = dist.plot,
                                 .data = split.agg.2013,
                        = names(split.agg.2013),
                                 SIMPLIFY = FALSE)


Now it’s time to execute the code.

split.agg.2013 <- split.agg(data = agg.2013[ , 2:7], facet = "PartyWinner")
distribution.plots <- mapply(FUN = dist.plot,
                             .data = split.agg.2013,
                    = names(split.agg.2013),
                             SIMPLIFY = FALSE)

And here are two examples:




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s