-
Notifications
You must be signed in to change notification settings - Fork 66
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
Error with factors that have additional classes #1888
Comments
We don't currently support superclassing classes like that. Would you consider using In this example I'm including a package prefix "my_package_", this is good practice because S3 classes are shared globally across the ecosystem. |
Ok, the primary class is meant to be a factor, so I don't see the point of adding a class in front which is more likely to cause problems, especially if the only reason for doing so has to do with some restrictive C-level routine in vctrs. I will also not rename the class as that would be considered an API breaking change to collapse. In general I don't think the order of classes should matter except for method dispatch. If vctrs has an internal method for factors it should dispatch on the factor class regardless of which other classes the object inherits. We have seen similar issues in base R where R Core added the "matrix" class to arrays and it caused havoc for a lot of developers that did illicit checks on the length of the class vector. |
On the contrary, since you're subclassing factor your class should come before your superclasses in the class vector. This is standard practice.
Sorry we don't currently have plans to change this. |
Ok, I will reshuffle the class, in the hope that it doesn't break anything. I still think vctrs is being too restrictive here though. There is, to my knowledge, nothing in R that warrants programs to fail because the order of classes is non-standard. Any user code that manipulates the class attribute could induce such artifacts. |
Thanks, please let me know if this causes trouble elsewhere. The problem in vctrs is that we don't do normal S3 dispatch, we do a limited form of double dispatch where inheritance is explicitly disabled. So superclassing is incompatible with this approach as we only dispatch to the leftmost classes. You will probably have to implement some coercion methods for compatibility with vctrs/tidyverse, to allow your class to be coercible to factor without loss of information, see https://vctrs.r-lib.org/reference/howto-faq-coercion.html. We made the choice of being restrictive in case of class mismatches, though we'd like to be a bit more lenient in the future. |
Ahh ok, I see this will cause errors probably everywhere: library(vctrs)
#> Warning: package 'vctrs' was built under R version 4.3.1
f <- iris$Species
class(f) <- c("na.included", "factor")
vec_ptype2(f, iris$Sepal.Length)
#> Error:
#> ! Can't combine `f` <na.included> and `iris$Sepal.Length` <double>.
#> Backtrace:
#> ▆
#> 1. ├─vctrs::vec_ptype2(f, iris$Sepal.Length)
#> 2. └─vctrs (local) `<fn>`()
#> 3. └─vctrs::vec_default_ptype2(...)
#> 4. ├─base::withRestarts(...)
#> 5. │ └─base (local) withOneRestart(expr, restarts[[1L]])
#> 6. │ └─base (local) doWithOneRestart(return(expr), restart)
#> 7. └─vctrs::stop_incompatible_type(...)
#> 8. └─vctrs:::stop_incompatible(...)
#> 9. └─vctrs:::stop_vctrs(...)
#> 10. └─rlang::abort(message, class = c(class, "vctrs_error"), ..., call = call) Created on 2023-10-26 with reprex v2.0.2 I definitely want to avoid opening a pandora's box that will force |
Isn't the error above expected? You'd only want your class to be coercible to factor and character IIUC? |
Same with |
I see if I export |
😱 I would not do that. That will not solve your issue anyway since the dispatch mechanism will not look into the search (except the global env).
I'd be surprised and I don't think there has been evidence of that in this thread. The error you're seeing is expected behaviour in our stack.
Yes we require explicit coercion behaviour, which must be done by implementing the ptype2 and cast coercion methods for all relevant classes (see linked FAQ). I'm sorry that causes you more work. The main issue with this approach is that it doesn't scale for classes like |
That's a lot of coding expected from my side and I don't see that it solves the issue once and for all, because you could introduce new classes that require coercion to/from factor, and then I would be required to implement the casting methods for that. I'll think about it further, but I think this is not a good option. |
Thanks for your consideration. |
Just a note to anyone reading this thread (referenced in the vec_ptype2.factor.factor <- function(x, y, ...) x in their global namespace, or reclass factors such as library(fastverse)
fastverse_extend(ggplot2)
iris %>%
pivot("Species") %>%
ggplot(aes(x = value, fill = Species)) +
geom_histogram() +
facet_wrap( ~ set_class(variable, "factor")) |
I'm getting a serious error using
ggplot
together withcollapse
, in particular,collapse
optimizes computations on factors by giving them an additional class"na.included"
if they are known to not contain anyNA
's. This class avoids a missing value check when using factors for grouping, joins etc. see https://sebkrantz.github.io/collapse/reference/qF.html. In the example below, I melt a data frame usingcollapse::pivot
which adds the"na.included"
class to the generated 'variable' factor i.e. the class isc("factor", "na.included")
. This produces an error inggplot2
caused byvctrs
. Thanks for considering this issue.Created on 2023-10-26 with reprex v2.0.2
The text was updated successfully, but these errors were encountered: