-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Clearer error messages for invalid aesthetics #3091
Clearer error messages for invalid aesthetics #3091
Conversation
@thomasp85 Could you take a look at the code? It looks good to me but would be good to get a second pair of eyes on it. @batpigandme Would you mind looking this over for the phrasing of the error messages? |
It appears to be good, but I can for the love of me not shake the feeling that it will error out in some fringe cases where it should not... But I'm pretty sure that's just me — can't think of any instances where data could be other than atomic or recursive... |
@batpigandme if you are ok with the wording you can approve and merge |
R/layer.r
Outdated
if(length(nondata_cols) > 0){ | ||
msg <- paste0( | ||
"Aesthetics must be valid data columns: ", nondata_cols, | ||
". Did you forget to add stat()?" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is forgetting stat()
really the most likely cause?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's two ways to get to this point: Forgetting stat()
or mistyping a column name in such way that the result is a function, e.g. typing mean
when the data column is called Mean
. How about: "Did you mistype the name of a data column or forget to add stat()?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we display the thing that they actually typed? Then we could hint to check that blah
is a column in the data frame.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how to get it to print the actual typed statement, but now it prints the problematic aesthetic (along with the tilde).
Situation 1:
ggplot(mtcars, aes(x = mpg, stat(density))) + geom_tile(stat = "density") + geom_point()
Error: Aesthetics must be valid computed stats: ~stat(density)
. Did you map your stat in the wrong layer?
Situation 2:
ggplot(mtcars, aes(x = mpg, fill = density)) + geom_tile(stat = "density") + geom_point()
Don't know how to automatically pick scale for object of type function. Defaulting to continuous.
Error: Aesthetics must be valid data columns: ~density
. Did you mistype the name of a data column or forget to add stat()?
I discussed this with @hadley at the developers day and the more I think about it the more I think it's right. Note that we're already performing a similar check on all incoming data, here: Lines 440 to 444 in e9d4e5d
Though now that I think about it, maybe this check and the new check in this PR should be combined into one? Do we need to call tibble to validate the input data or could we simply run something like the |
@clairemcwhite do you want to have a go at finishing this PR off? |
I can take a shot this weekend |
39cf111
to
33c953d
Compare
R/layer.r
Outdated
nondata_cols <- check_nondata_cols(evaled) | ||
if (length(nondata_cols) > 0) { | ||
msg <- paste0( | ||
"Aesthetics must be valid data columns: `", deparse(aesthetics[[nondata_cols]]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to use as_label()
instead of deparse()
.
R/layer.r
Outdated
nondata_stat_cols <- check_nondata_cols(stat_data) | ||
if (length(nondata_stat_cols) > 0) { | ||
msg <- paste0( | ||
"Aesthetics must be valid computed stats: `", deparse(aesthetics[[nondata_stat_cols]]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
As I said in the code comments, I think you should use |
Deparse is now replaced with rlang::as_label. Current behavior is :
Error: Aesthetics must be valid computed stats:
Don't know how to automatically pick scale for object of type function. Defaulting to continuous. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've looked at everything carefully once more and saw a few more minor nitpicks (see code comments). Also, I'm still not 100% convinced by the error message. I feel it needs a better lead into the aesthetic names that are the problem. E.g.:
Error: Aesthetics must be valid computed stats. Problematic aesthetic(s): stat(density).
@batpigandme Could you comment?
Finally, Claire, you'll have to resolve the merge conflict before merging. You can do that by merging the current ggplot2 master into your branch.
Claire, could you check what happens when there are multiple problematic aesthetics in one layer? I just realized that that case may not work yet. It probably needs a
Also make sure the test functions check against the final text in the error message. You can probably just delete the final colon. |
#3242 is merged now. |
…ics to resolve conflict Conflicts: NEWS.md R/layer.r
NEWS.md
Outdated
@@ -81,6 +81,10 @@ core developer team. | |||
|
|||
* ggplot2 now works in Turkish locale (@yutannihilation, #3011). | |||
|
|||
* Clearer error messages for inappropriate aesthetics (@clairemcwhite, #3060). | |||
|
|||
* `geom_rug()` gains an "outside" option to allow for moving the rug tassels to outside the plot area. (@njtierney, #3085) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have an idea of where this news item comes from? It should have been present in NEWS.md already, but it isn't, so I'm confused about both why it was lost and how it made its reappearance here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, it was moved in this commit: 230e8f7 so you can just delete it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, will do in next commit.
Claire, just a reminder, the deadline to merge this for the 3.2.0 release is April 30. It would be great if you could complete this by this deadline. Thanks! |
Multiple problem aesthetics now work. Case 1:
Case 2:
The only improvement I can think of would be to have the error include the type of aesthetic, like: "Problematic aesthetics(s): fill = stat(density), color = stat(density)". The variable "nondata_cols" is a vector c("fill", "color"), so there should be a quick way to construct this kind of error statement. |
Very good! Final set of comments, I promise. :-)
function(x) {paste0(x, " = ", as_label(aesthetics[[x]]))}
|
Case 1:
Case 2:
One note is that this approach anglicizes my "color" to "colour"
|
Super, thanks! Assuming the automated regression tests pass I'll merge. |
The AppVeyor build fails, for reasons that I can't discern. It doesn't seem to have anything to do with the changes that were made in this PR. The tests that break are visual tests for the date scale. @thomasp85, any idea what's happening? Can we merge and hope for the best? |
It has been going on since 5aacacb... I think it is fair to assume it has nothing to do with this PR If it propagates to master I'll fix it in a dedicated PR |
Thanks! |
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/ |
Fixes #3060
Previously, if a stat wasn't valid for layers, the error message was confusing
The new error message for this code is now
In the same vein, if a function like density was used as an aesthetic, the error message is clarified from the old:
to the new error message below that prompts the user to use stat(density)
This was done by adding two checks in R/layer.r
For the first change:
and for the second change:
Both use a new R/utilities.R function
check_nondata_cols()
There are two test in tests/testthat/test-layer.r for these two situations