dtkaplan / statisticalModeling

Other
11 stars 15 forks source link

gf_vline, _hline, _abline don't work #7

Open dtkaplan opened 8 years ago

dtkaplan commented 8 years ago

Problems:

rpruim commented 7 years ago

I can't figure out from the documentation how gf_abline() is supposed to work, but nothing I've tried (even with add = TRUE) does anything but generate errors, so I can confirm "this doesn't work".

  1. What is the intended API for gf_abline()?
  2. Any plans to fix this sooner rather than later?

In the meantime, some helpful text in the documentation would be a good thing. (And gf_abline() should appear among the examples, if it is possible to do anything useful with it.)

dtkaplan commented 7 years ago

gf_abline() is the victim of my indecisiveness. The gf_ functions are designed to create a frame and one layer of graphics. I've vacillated between using ggplot2 notation for added layers, or to create gf_ wrappers for the geoms.

For instance, this works:

require(statisticalModeling)
P <- gf_point(mpg ~ hp + color:cyl, data = mtcars)
P + geom_abline(slope = .02, intercept = 10)

I got caught up, however, on my gf_ functions figuring out whether they are being called as an add-on. I suspect this would just take a few hours of work to understand the ggplot2 +, but perhaps I should just use %>%. But then I'd have to provide a wrapper for xlim() and such.

If you have suggestions about which way to go, I'd love to hear them.

-Danny

On Mon, Feb 20, 2017 at 7:24 PM, Randall Pruim notifications@github.com wrote:

I can't figure out from the documentation how gf_abline() is supposed to work, but nothing I've tried (even with add = TRUE) does anything but generate errors, so I can confirm "this doesn't work".

  1. What is the intended API for gf_abline()?
  2. Any plans to fix this sooner rather than later?

In the meantime, some helpful text in the documentation would be a good thing. (And gf_abline() should appear among the examples, if it is possible to do anything useful with it.)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dtkaplan/statisticalModeling/issues/7#issuecomment-281219272, or mute the thread https://github.com/notifications/unsubscribe-auth/AAggrZdOUEulX9MI3yH3-_-u8uXNa-Erks5rejzMgaJpZM4Iy92q .

--

...

DeWitt Wallace Professor of Mathematics, Statistics, and Computer Science Macalester College

rpruim commented 7 years ago

I guess I misunderstood the design of this. I thought things like this were supposed to work:

gf_point( y ~ x + color:”red”, data = SomeData) + gf_point(y ~ x + color:”blue”, data = OtherData)

If that isn’t the case, then this is much less useful/interesting to me, since I want to be able to stack things, and if I have to teach aes() syntax for all but the first layer, I might as well just use ggplot2 without assistance.

But if first and subsequent layers can have the same syntax, then we have something more useful.

One possible way to do this (admittedly, I’ve not really looked at any code or thought hard about this) would be to have the gf_functions return an object that contains both the information equivalent for an add-on layer and the info needed for new plot creation. This object could have a new class. Depending on how you do it, it might inherit from the class in ggplot2 or not. Addition (+) could be defined for these objects so that the add-on layer portion is used rather than the initial layer portion.

If using %>% makes life easier, that doesn’t both me too much as an alternative to + (at least not at the moment). And that’s the direction things are going with ggvis. In this case, I could imagine something like this

gf_foo <- function(placeholder = NULL, …) { if (is.null(placeholder)) { return ggplot object with one layer } else { return placeholder + new layer }

Does that work? Any reason not to name placeholder something like p or object? Do you currently use placeholder for anything or is it just taking up space waiting for you to implement stuff?

On Feb 21, 2017, at 12:18 PM, Daniel Kaplan notifications@github.com wrote:

gf_abline() is the victim of my indecisiveness. The gf_ functions are designed to create a frame and one layer of graphics. I've vacillated between using ggplot2 notation for added layers, or to create gf_ wrappers for the geoms.

For instance, this works:

require(statisticalModeling)
P <- gf_point(mpg ~ hp + color:cyl, data = mtcars)
P + geom_abline(slope = .02, intercept = 10)

I got caught up, however, on my gf_ functions figuring out whether they are being called as an add-on. I suspect this would just take a few hours of work to understand the ggplot2 +, but perhaps I should just use %>%. But then I'd have to provide a wrapper for xlim() and such.

If you have suggestions about which way to go, I'd love to hear them.

-Danny

On Mon, Feb 20, 2017 at 7:24 PM, Randall Pruim notifications@github.com wrote:

I can't figure out from the documentation how gf_abline() is supposed to work, but nothing I've tried (even with add = TRUE) does anything but generate errors, so I can confirm "this doesn't work".

  1. What is the intended API for gf_abline()?
  2. Any plans to fix this sooner rather than later?

In the meantime, some helpful text in the documentation would be a good thing. (And gf_abline() should appear among the examples, if it is possible to do anything useful with it.)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dtkaplan/statisticalModeling/issues/7#issuecomment-281219272, or mute the thread https://github.com/notifications/unsubscribe-auth/AAggrZdOUEulX9MI3yH3-_-u8uXNa-Erks5rejzMgaJpZM4Iy92q .

--

...

DeWitt Wallace Professor of Mathematics, Statistics, and Computer Science Macalester College — You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/dtkaplan/statisticalModeling/issues/7#issuecomment-281412065, or mute the thread https://github.com/notifications/unsubscribe-auth/AAsFN-mvie2HkLG7XNEvykJMgg45RjR-ks5rexxJgaJpZM4Iy92q.

rpruim commented 7 years ago

I managed to get this to work

gf_point(length ~ width, data = KidsFeet) %>% gf_abline(slope = 3, intercept = -3)

editing just a few lines of code. Basically, I've changed the default for add to add = inherits(placeholder, c("gg", "ggplot")) in the function returned from gf_factory().

rpruim commented 7 years ago

But if you want + to work, I think then you need to have the gf_ function produce an object that does not yet know whether add is TRUE but can go either way because + will be dispatched on the class of its operands.

dtkaplan commented 7 years ago

The placeholder stuff wasn't well thought out.

I think I have to use the apparatus already in place for ggplot2:

ggplot2:::`+.gg`
ggplot2:::add_ggplot
ggplot2:::ggplot.data.frame

I'm reading these for the first time, and I think I see what's going on.

I think I can get the required behavior by pre-pending a "gf" class to the objects created by the gf_ functions. Then I'll do something like this:

`+.gf` <- function(e1, e2) {
  second <- substitute(e2)
  new_e2 <- statisticalModeling::evaluate_as_layer(second, context = e1) #
to be written
  ggplot2:::`+.gg`(e1, new_e2)
}

evaluate_as_layer() will set a flag so that the gf_ functions know not to include the ggplot component --- it will just return the geom part of the function. If e2 isn't a gf_ creation, then it won't know or care about the flag. At the end of evaluate_as_layer(), I'll unset the flag so that future calls to gf_ functions will create the ggplot + layer that's expected, unless they are again being evaluated by +.

On Tue, Feb 21, 2017 at 3:11 PM, Randall Pruim notifications@github.com wrote:

I guess I misunderstood the design of this. I thought things like this were supposed to work:

gf_point( y ~ x + color:”red”, data = SomeData) + gf_point(y ~ x + color:”blue”, data = OtherData)

If that isn’t the case, then this is much less useful/interesting to me, since I want to be able to stack things, and if I have to teach aes() syntax for all but the first layer, I might as well just use ggplot2 without assistance.

But if first and subsequent layers can have the same syntax, then we have something more useful.

One possible way to do this (admittedly, I’ve not really looked at any code or thought hard about this) would be to have the gf_functions return an object that contains both the information equivalent for an add-on layer and the info needed for new plot creation. This object could have a new class. Depending on how you do it, it might inherit from the class in ggplot2 or not. Addition (+) could be defined for these objects so that the add-on layer portion is used rather than the initial layer portion.

If using %>% makes life easier, that doesn’t both me too much as an alternative to + (at least not at the moment). And that’s the direction things are going with ggvis. In this case, I could imagine something like this

gf_foo <- function(placeholder = NULL, …) { if (is.null(placeholder)) { return ggplot object with one layer } else { return placeholder + new layer }

Does that work? Any reason not to name placeholder something like p or object? Do you currently use placeholder for anything or is it just taking up space waiting for you to implement stuff?

On Feb 21, 2017, at 12:18 PM, Daniel Kaplan notifications@github.com wrote:

gf_abline() is the victim of my indecisiveness. The gf_ functions are designed to create a frame and one layer of graphics. I've vacillated between using ggplot2 notation for added layers, or to create gf_ wrappers for the geoms.

For instance, this works:

require(statisticalModeling)
P <- gf_point(mpg ~ hp + color:cyl, data = mtcars)
P + geom_abline(slope = .02, intercept = 10)

I got caught up, however, on my gf_ functions figuring out whether they are being called as an add-on. I suspect this would just take a few hours of work to understand the ggplot2 +, but perhaps I should just use %>%. But then I'd have to provide a wrapper for xlim() and such.

If you have suggestions about which way to go, I'd love to hear them.

-Danny

On Mon, Feb 20, 2017 at 7:24 PM, Randall Pruim <notifications@github.com

wrote:

I can't figure out from the documentation how gf_abline() is supposed to work, but nothing I've tried (even with add = TRUE) does anything but generate errors, so I can confirm "this doesn't work".

  1. What is the intended API for gf_abline()?
  2. Any plans to fix this sooner rather than later?

In the meantime, some helpful text in the documentation would be a good thing. (And gf_abline() should appear among the examples, if it is possible to do anything useful with it.)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dtkaplan/statisticalModeling/issues/7# issuecomment-281219272, or mute the thread https://github.com/notifications/unsubscribe- auth/AAggrZdOUEulX9MI3yH3-_-u8uXNa-Erks5rejzMgaJpZM4Iy92q .

--

...

DeWitt Wallace Professor of Mathematics, Statistics, and Computer Science Macalester College — You are receiving this because you commented. Reply to this email directly, view it on GitHub < https://github.com/dtkaplan/statisticalModeling/issues/7# issuecomment-281412065>, or mute the thread https://github.com/ notifications/unsubscribe-auth/AAsFN-mvie2HkLG7XNEvykJMgg45RjR- ks5rexxJgaJpZM4Iy92q.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dtkaplan/statisticalModeling/issues/7#issuecomment-281481783, or mute the thread https://github.com/notifications/unsubscribe-auth/AAggrRH9DhfC2OHoFxmloJxibLJrcZ_sks5re1MMgaJpZM4Iy92q .

--

...

DeWitt Wallace Professor of Mathematics, Statistics, and Computer Science Macalester College

rpruim commented 7 years ago

We'll see how you fare. I find it challenging to augment classes and methods defined in other packages. I think R doesn't intend to make this easy/possible to do.

rpruim commented 7 years ago

As for the multiple slope/intercepts. I have this working too (by replacing unlist() with a customized function).

gf_point(mpg ~ hp + color:cyl + size:wt, data = mtcars) %>%
  gf_abline(color = "red", slope = -0.10, intercept = 33:36)

image