-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Make add_ggplot an S3 method #3815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
If there is a better approach, I am all for it! Thank you! |
|
@thomasp85 While true, the current state still doesn't work.
I'd like a generic for the left hand side of Is there a way to define my own method if I know the classes of the right and left side? From
|
We might consider integrating vctrs with ggplot2 (c.f. Hadley said so hadley/adv-r#1195 (comment)), which will enable double dispatch. Until then, maybe you can use S4 to do double dispatch? |
Pulling in @yutannihilation's example which matches my use case. My situation is exactly like library(ggplot2)
set.seed(100)
d1 <- data.frame(x = 1:100, y = cumsum(runif(100)))
d2 <- data.frame(x = 1:100, y = cumsum(runif(100)))
plot_all <- function(...) {
l <- lapply(list(...), function(d) ggplot(d, aes(x, y)) + geom_line())
l <- unname(l)
class(l) <- "manyplot"
l
}
print.manyplot <- function(x, ...) {
do.call(gridExtra::grid.arrange, x)
}
p <- plot_all(d1, d2)
p `+.manyplot` <- function(e1, e2) {
l <- lapply(e1, function(x) x + e2)
class(l) <- "manyplot"
l
}
p + theme_bw()
#> Warning: Incompatible methods ("+.manyplot", "+.gg") for "+"
#> Error in p + theme_bw(): non-numeric argument to binary operator
Since both objects are not S4 objects, I believe https://stat.ethz.ch/R-manual/R-devel/library/methods/html/Methods_for_S3.html
Using an example from Advanced R, the S4 dispatch does not work as expected. setGeneric("type", function(x) standardGeneric("type"))
#> [1] "type"
setMethod("type", signature("matrix"), function(x) "matrix")
setMethod("type", signature("character"), function(x) "character")
type(letters)
#> [1] "character"
type(matrix(letters, ncol = 2))
#> [1] "matrix"
foo <- structure(list(x = 1), class = "foo")
type(foo) # expected to fail
#> Error in (function (classes, fdef, mtable) : unable to find an inherited method for function 'type' for signature '"foo"'
setOldClass("foo")
setMethod("type", signature("foo"), function(x) "foo")
type(foo)
#> [1] "foo"
setMethod("+", signature(e1 = "foo", e2 = "numeric"), function(e1, e2) {
structure(list(x = e1$x + e2), class = "foo")
})
foo + 3
#> Error in foo + 3: non-numeric argument to binary operator Created on 2020-02-10 by the reprex package (v0.3.0) |
I think I overcame this issue after this, but don't remember the details... |
I think I defined library(ggplot2)
set.seed(100)
d1 <- data.frame(x = 1:100, y = cumsum(runif(100)))
d2 <- data.frame(x = 1:100, y = cumsum(runif(100)))
setClass("manyplot", slots = c(plots = "list"))
plot_all <- function(...) {
l <- lapply(list(...), function(d) ggplot(d, aes(x, y)) + geom_line())
l <- unname(l)
new("manyplot", plots = l)
}
setMethod("show", signature = "manyplot", function(object) {
do.call(gridExtra::grid.arrange, object@plots)
})
p <- plot_all(d1, d2)
p setOldClass(c("theme", "gg"))
setMethod("+", signature = c(e1 = "manyplot", e2 = "gg"), function(e1, e2) {
e1@plots <- lapply(e1@plots, function(x) x + e2)
e1
})
p + theme_bw() Created on 2020-02-11 by the reprex package (v0.3.0) |
"ggmatrix"
. I would like to be able to add themes and labels.+.gg
, which produces a warning.Created on 2020-02-10 by the reprex package (v0.3.0)
From https://r.789695.n4.nabble.com/quot-Incompatible-methods-quot-for-overloaded-operator-td4633362.html, Martin states that there can not be two
+
methods. 😞I have tried this with my
ggmatrix
class and can confirm it doesn't work as intended:I propose that that the
add_ggplot
method become an S3 method to allow for other classes to control the left side.For my specific case, I would be able to add a method of
add_ggplot.ggmatrix
. From here, I can have a hook to the addition and not produce a warning.cc @hafen