Skip to content

Add error messages when using + with layers and scales #2057

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

Merged
merged 3 commits into from
Mar 1, 2017

Conversation

jrnold
Copy link
Contributor

@jrnold jrnold commented Feb 25, 2017

In my experience, one of the most common and inscrutable error messages for new users is when they forget a + and get the error message: non-numeric argument to binary operator. For example, something like this:

> ggplot(mtcars, aes(x = disp, y = mpg))
> geom_point() + geom_smooth()
Error in geom_point() + geom_smooth() : 
  non-numeric argument to binary operator

I would like to add a more informative error message in the style of #2056 and the error messages in dplyr, e.g. this.

> ggplot(mtcars, aes(x = disp, y = mpg))
> geom_point() + geom_smooth()
Error in `+.gg`(scale_fill_brewer(), geom_point()) : 
  Cannot add ggproto objects together. Did you forget to add this object to a ggplot() object?

The obvious approach would be to add a function(s) +.Layer or +.ggproto, but when there is a valid addition of a ggplot and Layer object that produced an "Incompatible Methods" error since S3 generics in the Ops group dispatch on both arguments and only work if only one has a specific method, or both have the same method. Something which it seems like you encountered before here.

So the only way I could make this work is to make ggplot, theme and ggproto inherit from the same S3 class, and define the + method with that class. As far as I can tell, currently the gg class is used for this purpose with respect to the ggplot and theme classes, with only the +.gg method defined. My solution was to change the class given to default ggproto() objects to c("ggproto", "gg"). This feels unclean, but didn't break any of the tests. But, it seemed like the simplest way accomplish the stated objective. Given that this is adding a class to ggproto objects, it may not be worth it to change the error messages, but I thought I'd propose the change.

@jrnold jrnold changed the title Error messages for adding to layers/scales, etc. Add error messages when using + with layers and scales Feb 27, 2017
Copy link
Member

@hadley hadley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a reasonable thing to do.

Can you please make this one small change and add a bullet to NEWS?

@@ -46,6 +46,10 @@

if (is.theme(e1)) add_theme(e1, e2, e2name)
else if (is.ggplot(e1)) add_ggplot(e1, e2, e2name)
else if (is.ggproto(e1)) {
stop("Cannot add ggproto objects together.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs call. = FALSE

@jrnold
Copy link
Contributor Author

jrnold commented Mar 1, 2017

I also realized that this change could cause problems for anyone who has written code that tests for class the wrong way, class(x) == "ggproto".

@hadley hadley merged commit e801f8d into tidyverse:master Mar 1, 2017
@hadley
Copy link
Member

hadley commented Mar 1, 2017

Thanks!

I think it's ok to break code that doesn't use inherits()

@lock
Copy link

lock bot commented Jan 18, 2019

This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/

@lock lock bot locked and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants