Home > database >  Add title to ggplot objects in function that will be used with map()
Add title to ggplot objects in function that will be used with map()

Time:12-17

I have a function that does several things including produce ggplot objects. I then pass this function to purrr::map() to iterate over nested data. I need to add an id as a ggtitle to each ggplot object in my function, but the ggplot objects are created by another function from another R package, so I have to add the ggtitle AFTER the ggplot object is created in my function. When I try to iterate using purrr::map() I get an error.

I think this thread might be helpful, but I couldn't figure out how to code it for my example: Add titles to ggplots created with map()

Here is a very simplified function that I think replicates my issue:

library("tidyverse")

dat <- 
  structure(list(id = c("07060710", "07060710", "07060710", "07060710", 
  "07060710", "07060710", "07060710", "07060710", "07060710", "07060710", 
  "07263295", "07263295", "07263295", "07263295", "07263295", "07263295", 
  "07263295", "07263295", "07263295", "07263295"), y = c(-0.1, 
  0.1, 0, 0, -0.1, -0.1, -0.1, 0, -0.1, -0.2, 0.4, 0.5, 0.5, 0.5, 
  0.9, 0.7, 0.9, 0.9, 0.4, 0.4), x = c(1, 1.8, 1.3, 1.3, 0.7, 0.3, 
  1.5, 0.9, 1, 0.5, 1.1, 1, -0.1, -0.4, 3.2, 2.4, 3, 3.3, 0.7, 
  1)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
  -20L))

runLM = function(df) {
  # Here I try to extract the id
  # And I think this is what causes the error
  id_title <- unique(df$id)
  
  lm_fit <- lm(y ~ x, data = df)
  
  # This is a simplified plot function for this example
  # The actual initial plot is created by a function from another package
  # So I cannot manipulate the initial ggplot function
  # I can only manipulate the ggplot object after it is created
  plot_init <- 
    df %>% 
    ggplot(aes(x = x, y = y))  
    geom_point()
  
  # Here I try to add the 'id' as a the plot title
  plot_fin <- plot_init  
    ggtitle(id_title)
  
  return(plot_fin)
}

I then pass this function along to:

fit_lm <-
  dat %>% 
  group_by(id) %>% 
  nest() %>% 
  mutate(model = map(data, ~runLM(df = .x)))

# Here should be the plot, but I get an error when I try to iterate using map()
fit_lm[[3]][[1]]

CodePudding user response:

After nesting there is no column id in the dataframes stored in the list column data. Instead add an argument id_title to your function and use map2 to loop over both the id and the data column of your nested data:

library("tidyverse")
runLM = function(df, id_title) {
  lm_fit <- lm(y ~ x, data = df)
  
  plot_init <- 
    df %>% 
    ggplot(aes(x = x, y = y))  
    geom_point()
  
  plot_fin <- plot_init  
    ggtitle(id_title)
  
  return(plot_fin)
}

fit_lm <- dat %>% 
  group_by(id) %>% 
  nest() %>% 
  mutate(model = map2(data, id, ~runLM(df = .x, id_title = .y)))

fit_lm$model
#> [[1]]

#> 
#> [[2]]

  • Related