0

I have a custom function that makes 3 plots for each cut of the data. The first plot is the overall results, and it should be followed by the breakdown of results by location and level (although whether location or level comes second or third is okay, as long as it's consistent).

Though my function works, it puts the location plot first, then the overall, and then the level. I'm confused why this is happening because the 2 subplots are made in plot2, and in my output, I explicitly specify that the overall plot should come first.

This post was extremely helpful in getting my custom function to produce 2 outputs, but this post didn't cover how to constrain your output to be in a certain order.

Here's my code:


#Data
test <- tibble(s1 = c("Agree", "Neutral", "Strongly disagree"),
               s2rl = c("Agree", "Neutral", "Strongly disagree"),
               f1 = c("Strongly agree", "Disagree", "Strongly disagree"),
               f2rl = c("Strongly agree", "Disagree", "Strongly disagree"),
               level = c("Manager", "Employee", "Employee"),
               location = c("USA", "USA", "AUS"))

#Get just test items for name
test_items <- test %>%
  dplyr::select(s1, s2rl, f1, f2rl)

#titles of plots for R to iterate over
titles <- c("S1 results", "Results for S2RL", "Fiscal Results for F1", "Financial Status of F2RL")


#group levels
group_name <- c("level", "location")

#custom ggplot function
faceted_plots = function(variable, group, title) {
  
  plot1 <- test %>%
    count(.data[[variable]]) %>%
    mutate(percent = 100*(n / sum(n, na.rm = TRUE))) %>%
    ggplot(aes(x = .data[[variable]], y = percent, fill = .data[[variable]])) + 
    geom_bar(stat = "identity") +
    ggtitle(title)

  plot2 <- test %>%
    count(.data[[group]], .data[[variable]]) %>%
    mutate(percent = 100*(n / sum(n, na.rm = TRUE))) %>%
    drop_na() %>%
    ggplot(aes(x = .data[[variable]], y = percent, fill = .data[[variable]])) + 
    geom_bar(stat = "identity") +
    geom_text(aes(label= paste0(percent, "%"), fontface = "bold", family = "Arial", size=14), vjust= 0, hjust = -.5) +
    labs(
      title = title) +
    facet_grid(~.data[[group]])
  
  output <- list(plot1, plot2)
  return(output)
}

#pmap call
my_plots <- expand_grid(tibble(item = names(test_items), title=titles),
                        group = group_name) %>%
  pmap(function(item, group, title)
    faceted_plots(item, group, title))

my_plots
J.Sabree
  • 2,280
  • 19
  • 48
  • @akrun, no that order is correct. What I mean is, for instance, for the s1results slide. The first S1 result plot should be the overall results (e.g., plot1). Then, the next s1results plot should be the one for location (or level). However, currently R is jumping the order of the plots within a certain category (e.g., all the s1result plots are out of order but they are all 3 next to each other, and the same goes for all the others). – J.Sabree Aug 19 '21 at 19:19
  • First, can you reduce the question to two simple plots so that it is easier to understand? `ggplot(mtcars, aes(....)) + geom_point()` or `geom_line()`. I don't think we need all the detailed calculation and `theme` part to reproduce the issue ? – Ronak Shah Aug 20 '21 at 04:05
  • @RonakShah, thanks for the suggestion. I edited the question. I kept the same data because my final dataset is close in nature to it, but I removed everything that was extraneous (e.g., theme, additional calculations by group, etc.). – J.Sabree Aug 20 '21 at 13:26
  • What is the expected output? Do you need to change the order of plots in each list? So `my_plots[[1]][[1]]` should be `my_plots[[1]][[2]]` and vice versa ? – Ronak Shah Aug 20 '21 at 13:40
  • @RonakShah, The first plot is the overall results, and it should be followed by the breakdown of results by location and level (though the exact order of location/level can be switched--just as long as it stays consistent). I've tried playing around with the indexing, but I can't figure it out. I've tried viewing the structure of the list too, but it's so deep that I don't know which element is embedded at what point. – J.Sabree Aug 20 '21 at 13:48
  • @RonakShah, another issue that I think is happening is it's making plot1 (the overall plot) twice because it's iterating multiple groups, but I don't know how to stop that from happening and perhaps that would fix the issue. – J.Sabree Aug 20 '21 at 13:49

1 Answers1

0

Though I didn't figure out how to coerce the elements in a certain order, I was able to find how to remove duplicates (which was the issue in my above example--the overall plot, or plot1, was being produced twice) based on this answer.

Adapted for this example, that would be:

# make a copy of my original list of plots to avoid duplicates
my_plots_duplicate <- my_plots
# take set difference between contents of list elements and accumulated elements
my_plots_duplicate[-1] <- mapply(setdiff, my_plots_duplicate[-1],
                       head(Reduce(c, my_plots, accumulate=TRUE), -1))

my_plots_duplicate
J.Sabree
  • 2,280
  • 19
  • 48