Mario Niepel
Mario Niepel

Reputation: 1165

using mapply with ggplot

Continuing on my quest to work with functions and ggplot:

I sorted out basic ways on how to use lapply and ggplot to cycle through a list of y_columns to make some individual plots:

require(ggplot2)
# using lapply with ggplot

df <- data.frame(x=c("a", "b", "c"), col1=c(1, 2, 3), col2=c(3, 2, 1), col3=c(4, 2, 3))
cols <- colnames(df[2:4])
myplots <- vector('list', 3)

plot_function <- function(y_column, data) { 
     ggplot(data, aes_string(x="x", y=y_column, fill = "x")) +
     geom_col() + 
     labs(title=paste("lapply:", y_column))
}

myplots <- lapply(cols, plot_function, df)
myplots[[3]])

lapply_plot_3

I know what to bring in a second variable that I will use to select rows. In my minimal example I am skipping the selection and just reusing the same plots and dfs as before, I simply add 3 iterations. So I would like to generate the same three plots as above, but now labelled as iteration A, B, and C.

I took me a while to sort out the syntax, but I now get that mapply needs to vectors of identical length that get passed on to the function as matched pairs. So I am using expand.grid to generate all pairs of variable 1 and variable 2 to create a dataframe and then pass the first and second column on via mapply. The next problem to sort out was that I need to pass on the dataframe as list MoreArgs =. So it seems like everything should be good to go. I am using the same syntax for aes_string() as above in my lapply example.

However, for some reason now it is not evaluating the y_column properly, but simply taking it as a value to plot, not as an indicator to plate the values contained in df$col1.

HELP!

require(ggplot2)
# using mapply with ggplot

df <- data.frame(x=c("a", "b", "c"), col1=c(1, 2, 3), col2=c(3, 2, 1), col3=c(4, 2, 3))
cols <- colnames(df[2:4])
iteration <- c("Iteration A", "Iteration B", "Iteration C")

multi_plot_function <- function(y_column, iteration, data) { 
     plot <- ggplot(data, aes_string(x="x", y=y_column, fill = "x")) +
     geom_col() + 
     labs(title=paste("mapply:", y_column, "___", iteration))
}

# mapply call 
combo <- expand.grid(cols=cols, iteration=iteration)
myplots <- mapply(multi_plot_function, combo[[1]], combo[[2]], MoreArgs = list(df), SIMPLIFY = F) 
myplots[[3]]

mapply_plot_3

Upvotes: 1

Views: 362

Answers (1)

akrun
akrun

Reputation: 887153

We may need to use rowwise here

out <- lapply(asplit(combo, 1), function(x)
           multi_plot_function(x[1], x[2], df))

In the OP's code, the only issue is that the columns are factor for 'combo', so it is not parsed correctly. If we change it to character, it works

out2 <- mapply(multi_plot_function, as.character(combo[[1]]), 
    as.character(combo[[2]]), MoreArgs = list(df), SIMPLIFY = FALSE) 

-testing

out2[[1]]

enter image description here

Upvotes: 1

Related Questions