0

I'm building a function that performs some actions on a dataset, and I want it to return a variety of plots that may or may not be needed at any given time.

My approach to now is to return a list of objects, including some ggplot objects.

The issue is that when I call the function without assignment, or execute the resulting list, the ggplots are plotted alongside the printing of the list summary, a behaviour I want to avoid as the object may include many ggplot objects.

Example:

library(ggplot2)

df <- data.frame(
  x = 1:10,
  y = 10:1,
  g = rep(c('a', 'b'), each=5)
)

df_list <- split(df, df$g)

plot_list <- lapply(df_list, function(d){
  ggplot(d) +
    geom_point(aes(x=x, y=y))
})

plot_list

# $`a`  # plots plot_list$a
# 
# $`b`  # plots plot_list$b

I don't want to modify the default behaviours of the ggplot2 object, though I am open to a more advanced S3 solution where I have no idea how to go about this.

  • to be clear, you want to be able to print the list without printing the plots inside? do other methods of showing the list structure suffice or does it need to involve printing? is it basically that you want to see what is in the list but have some placeholder to indicate that there is a plot in the list? – Calum You Dec 14 '18 at 14:09
  • @CalumYou Specifically the `plot_list` or `print(plot_list)` execution, as that's the most common way it'll be first interrogated. It is specifically this behaviour I'd _like_ to change, preferably by changing the list object/structure itself. edit: As you edited it in, yes. A placeholder output for the print is ideal. – CriminallyVulgar Dec 14 '18 at 14:13
  • If you just want the names inside `plot_list` you could run `names(plot_list)` – Lennyy Dec 14 '18 at 14:16
  • 1
    @hdkrgr Nailed it. Didn't know how to search for that question, but it's what I'm after. – CriminallyVulgar Dec 14 '18 at 14:20
  • Your question was such a good one that I didn't realise you just wanted to call `names`... Anyway you may find my answer useful to prevent accidental printing of your full list. When you have a lot of ggplot objects, you may make your session hang if you just type `plot_list`. – asachet Dec 14 '18 at 14:30
  • @antoine-sac Your answer was good, and very much aligned with what I had in mind with the addition of subclassing the list! I was replying to a now-deleted comment flagging the potential duplicate. As the question is just a specific version of a the duplicated question, I don't think it's good form to accept an answer? Correct me if I'm wrong there. – CriminallyVulgar Dec 14 '18 at 14:51

1 Answers1

0

You can simply override the default behaviour by having your function return an object from a custom class.

Option 1: subclass your plots

Here our plots are now quiet_plot which do not print. To actually print them you'll have to explicitly call print.ggplot

library(ggplot2)

df <- data.frame(
  x = 1:10,
  y = 10:1,
  g = rep(c('a', 'b'), each=5)
)

df_list <- split(df, df$g)

plot_list <- lapply(df_list, function(d){
  out <- ggplot(d) +
    geom_point(aes(x=x, y=y))
  class(out) <- c("quiet_plot", class(out))
  out
})

print.quiet_plot <- function(x, ...) {
  print("A plot not displayed!")
}

plot_list

Option 2 - subclass your list

This allows you to specify how you want the list to be printed when you just type plot_list in the console. Here I had it print the names of the list instead of the full list content.

plot_list <- lapply(df_list, function(d){
  ggplot(d) +
    geom_point(aes(x=x, y=y))
})

class(plot_list) <- c("quiet_list", class(plot_list))

print.quiet_list <- function(x, ...) {
  cat("A list with names:")
  print(names(x))
}

plot_list
asachet
  • 6,620
  • 2
  • 30
  • 74