1

I'm saving objects to a list and I'd like to clear the plots pane and viewer pane whenever I load those objects. I basically want the back button to grey out after I've gone through the charts in that element of the list.

This is my code

gg <- ggplot(iris, aes(width, length)) + geom_point
l <- list()
l[["element"]] <- gg

I want it so that when I run l$element, it's like I first clicked the broom on the plots and viewer tab in rstudio.

goollan
  • 765
  • 8
  • 19
  • Possible duplicate: https://stackoverflow.com/questions/22640016/code-to-clear-all-plots-in-rstudio – MrFlick Oct 25 '20 at 20:31
  • Would the command `graphics.off(); plot(l$element)` do what you want? – Vincent Guillemot Oct 25 '20 at 20:32
  • Can I make it so that fires just when I call the elemnt in the list? – goollan Oct 25 '20 at 20:32
  • I think it's not a duplicate because I'm asking for it to fire when I call the list element – goollan Oct 25 '20 at 20:33
  • You want to redefine the behavior of subsetting all lists? Or how would the code know to execute just for this list? Maybe write your own function for subsetting instead? There's certainly existing function for this type of unusual behavior. I guess you could create your own class and override the `$` function, but then `l` wouldn't be a basic list. I wouldn't recommend that though because it could be very confusing if anyone else where to use the code. – MrFlick Oct 25 '20 at 20:41
  • Hmm... could I do something like every time I use the selection ^^^ then to this, and I would select elements from a list with l^^^gg – goollan Oct 25 '20 at 20:50

2 Answers2

1

You can do this as long as you store the ggplot inside a custom S3 class whose default print method calls dev.off then plots the enclosed ggplot:

gg_wipe <- function(x) structure(list(plot = x), class = "gg_wipe")

print.gg_wipe <- function(x) {dev.off(); print(x$plot)}

gg <- ggplot(iris, aes(Sepal.Width, Sepal.Length)) + geom_point()
l <- list() 
l[["element"]] <- gg_wipe(gg)

l[["element"]]
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
1

Or rather than wrapping the plot as Allan did (which is a good idea) you can provide a helper function and then provide different ways to get at it. So this calls the helper function directly

l <- list(
   apple=ggplot(data.frame(x=1:3, y=1:3)) + geom_point(aes(x,y)),
   banana=ggplot(data.frame(x=1:3, y=3:1)) + geom_point(aes(x,y))
)
clear_and_print <- function(x, ele) {
   graphics.off(); invisible(print(x[[deparse(substitute(ele))]]))
}
clear_and_print(l, apple)

You can define some new operators but they have to be syntactically valid. You can't have ^^^ bur you could have %^%

`%^%` <- clear_and_print
l %^% apple
l %^% banana

Or you can create a special class for your container

`$.plot_clear` <- function(x, ele) {
  graphics.off(); x[[ele]]
}
class(l) <- "plot_clear"
l$apple
l$banana
MrFlick
  • 195,160
  • 17
  • 277
  • 295