Home > Net >  How to plot multiple plots for all variables of listed dataframes
How to plot multiple plots for all variables of listed dataframes

Time:05-01

I have a listed dataframe with the code:

df1 <- data.frame(ID = rep(c("P-1000", "P-10001", "P-10002", "P-1003", "P-1004"),3),
                Visit = c(rep("M1",5), rep("M4",5), rep("M17",5)),
                Value = runif(15))

df2 <- data.frame(ID = rep(c("P-1000", "P-10001", "P-10002", "P-1003", "P-1004"),3),
                Visit = c(rep("M1",5), rep("M4",5), rep("M17",5)),
                Value = runif(15))

df3 <- data.frame(ID = rep(c("P-1000", "P-10001", "P-10002", "P-1003", "P-1004"),3),
                Visit = c(rep("M1",5), rep("M4",5), rep("M17",5)),
                Value = runif(15))

sampledata<- list(df1, df2, df3)
names(sampledata)<- c("A", "C", "Z")

for which I am trying to make plots for. I am trying to make plots per ID per dataframe (e.g., 1 plot would be for P-1000 in dataframe A). In the end, I would like to save these plots in separate pdfs by dataframes (e.g., 1 pdf for all plots pertaining to dataframe A, another for dataframe B, etc). I'm not quite sure how to do this. My current trial of code is the following:

sample_data_plots <- lapply(seq_along(sampledata),function(i) {
  sampledata[[i]] %>% filter(!is.na(Visit)) %>% group_by(ID) %>%
    mutate(Visit = factor(Visit, levels = c("M1", "M4", "M17"))) %>%
    ggplot(aes(x = Visit, y = Value))   geom_boxplot()  
    labs(title = paste("Values of", names(sampledata)[i], "for", "ID", 
#this is the variable ID
),
         y = "Value",
         x = "Visit")}) 

I have no issues in running:

lapply(seq_along(sampledata), function(i) {
  sampledata[[i]] %>% filter(!is.na(Visit)) %>% 
    mutate(Visit = factor(Visit, levels = c "M1", "M4", "M17"))) %>% 
    ggplot(aes(x = Visit, y = Value))   geom_boxplot()   
    labs(title = paste("Value", names(sampledata)[i]),
         y = "Value",
         x = "Visit") })

but this gives graphs per dataframes for all ID

Any help would be greatly appreciated. Thank you!

CodePudding user response:

Consider purrr::map2 to apply a function across list of data frames and their names and dplyr::group_map to apply functions by ID groups.

build_plot <- function(sub_df) {
  sub_df %>%
     filter(!is.na(Visit)) %>% 
     mutate(Visit = factor(Visit, levels=c("M1", "M4", "M17"))) %>% 
     ggplot(aes(x=Visit, y=Value))   
       geom_boxplot()   
       labs(title = paste("Value", sub_df$ID[1]), y="Value", x="Visit")
}

run_groups <- function(main_df, df_name) {
  # BUILD PLOTS BY ID
  plot_list <- main_df %>%
      group_by(ID) %>%
      group_map(build_plot)

  # SAVE PLOTS TO SINGLE PDF
  ggplot2::ggsave(
      filename = paste0(df_name, "_plots.pdf"), 
      plot = gridExtra::marrangeGrob(plot_list, nrow=1, ncol=1),
      width = 15, height = 9
  )

  return(plot_list)
}

# CREATE PDFS BY DATA FRAME
myplots <- purr::map2(sample_data, names(sample_data), run_groups)

The analogous base R methods respectively would be siblings to lapply: Map (wrapper to mapply) and by (wrapper to tapply).

run_groups <- function(main_df, df_name) {
  # BUILD PLOTS BY ID
  plot_list <- by(main_df, main_df$ID, build_plot)
  ...
}

# CREATE PDFS BY DATA FRAME
myplots <- Map(run_groups, sample_data, names(sample_data))
  • Related