-
Notifications
You must be signed in to change notification settings - Fork 2.1k
fortify.default() accepts data-frame-like objects #5404
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
`fortify.default()` now accepts a data-frame-like object granted the object exhibits healthy `dim()`, `colnames()`, and `as.data.frame()` behaviors. Closes #5390.
Looks like the |
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.
Hi Hervé,
Thanks so much for putting in the work for this PR!
I think the validation of the data.frame looks great. In fact, I think its usefulness might extend beyond just the use in fortify()
to check any 'untrusted' data.frame.
I understand that this isn't an immediate concern for S4Vectors compatibility, so I'm not asking you to implement all the comments. I'd be happy to take on this extension myself in a follow up PR if this isn't in your direct line of interest, in which case you can consider the comments as 'notes to self'.
From the BioC side, the requirement of having to return appropriate dim()
might mean that we cannot directly put a GenomicRanges::GRanges
class into the data
argument, even though it has an as.data.frame
method. Is this intentional?
Thanks for the feeback and happy to revise as suggested. It's good to know about About your suggestion to not do any error cacthing in Let me explain: I usually advocate against excessive use of
Letting
But catching the error with
This error message makes it clear that this is not a ggplot2 problem and it also gives a precise description of what Now I need to get more familiar with Best, |
I think the trick to this is using library(rlang)
setClass("OnDiskRectangularBlob", slots=c(stuff="ANY"))
setMethod("dim", "OnDiskRectangularBlob", function(x) stop("failed to access resource X for reason Y"))
blob <- new("OnDiskRectangularBlob")
validate <- function(x) {
my_dims <- dim(x)
if (length(my_dims) != 2) {
stop("Invalid dims")
}
my_dims
}
wrapper <- function(x) {
try_fetch(
validate(x),
error = function(cnd) cli::cli_abort("Cannot wrap", parent = cnd)
)
}
# Failure in upstream functions
wrapper(blob)
#> Error in `wrapper()`:
#> ! Cannot wrap
#> Caused by error in `dim()`:
#> ! failed to access resource X for reason Y
# Not valid
wrapper(array(dim = 2:4))
#> Error in `wrapper()`:
#> ! Cannot wrap
#> Caused by error in `validate()`:
#> ! Invalid dims
# Valid
wrapper(matrix())
#> [1] 1 1 Created on 2023-09-06 with reprex v2.0.2 |
That's very useful, thank you! |
Hi @teunbrand, Thanks again for the feedback. I've implemented your suggestions:
Overall this makes the code significantly simpler/shorter. 2 small things I didn't implement:
Let me know if you think I should make these changes nevertheless, and I'll be happy to do it. Thanks again for taking the time to look at this. Best, |
Note that the |
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.
Hi Hervé,
Thank you for incorporating the suggestions!
I think the code looks good as a whole and your latest changes definitely made it more maintainable.
I agree with your assessment about the column names and check_data_frame()
.
I only have a few nit-picks with regards to phrasing and some {cli} specific fidgeting.
The devel check time-out is because of some {vdiffr} compilation issue that is unrelated to this PR.
If you could have a look at those then I think this should be ready to merge.
Best,
Teun
Done. Thanks again! |
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.
This looks great! Thanks for the contribution Hervé, I hope this makes BioC <> Tidyverse interface a little bit easier :)
It definitely will. There was a strong demand for this feature in the BioC community. Thanks again for the guidance! |
fortify.default()
now accepts a data-frame-like object granted the object exhibits healthydim()
,colnames()
, andas.data.frame()
behaviors. Closes #5390.Some notes:
.as_data_frame_trust_no_one()
can fail in many ways and I'm using detailed error messages that I hope are informative/useful. However I'm not sure if that level of verbosity is ok. Let me know if I should use shorter error messages.expect_error()
statements in the unit tests don't check the error message but I can change that.ggplot()
work directly on a DataFrame object (and now it works 😉) but I didn't add unit tests for this because that would requireSuggests
'ing the S4Vectors package where the DataFrame class is implemented.fortify.default()
is now a no-op on a data.frame object sofortify.data.frame()
is no longer needed but this PR keeps it anyways in order to keep it focused and minimalist.Thanks