Coercion in tibble subclasses

Suppose I have a tibble and decided to constructed a new subclass with help of new_tibble():

library(dplyr, warn.conflicts = FALSE)
library(tibble, warn.conflicts = FALSE)

set.seed(123)
x <- tibble(x = rnorm(5))
x <- new_tibble(x, nrow = nrow(x), class = "go_away")
class(x)
#> [1] "go_away"    "tbl_df"     "tbl"        "data.frame"

What is the most efficient way to make the object x iterate with the dplyr verbs without keeping the memory of the newly created subclass?

For example, if I try:

mutate(x, tibble(y = 1)) %>% class()
#> [1] "go_away"    "tbl_df"     "tbl"        "data.frame"

The go_away signature is still there.

But, if I do this:

mutate.go_away <- function(.data, ...) {
  mutate(as_tibble(.data), ...)
}

mutate(x, tibble(y = 1)) %>% class()
#> [1] "tbl_df"     "tbl"        "data.frame"
mutate(x, y = 1) %>% class()
#> [1] "tbl_df"     "tbl"        "data.frame"
mutate(x, x) %>% class()
#> [1] "tbl_df"     "tbl"        "data.frame"

The problem is apparently solved (at least for mutate).

Sadly, this solution forces me to create a new method for all the verbs in the tidyverse. This would make sense if I wanted the go_away class to have a life on its own, but my objective is quite the opposite: iteration among tibbles and data.frames should always fallback to the default signature

#> [1] "'tbl_df'"     "'tbl'"        "'data.frame'"

… and nothing else.

Any thoughts on how this could be achieved without having to extend dplyr verbs, like tsibble did (here and here)?

Created on 2021-06-16 by the reprex package (v2.0.0)

Can you motivate why you want tidyverse to strip away your class? Doesn't that help your class be useful, i.e. that it can be manipulated without changing its nature.

What was your intention behind using new_tibble? :thinking:

I'm currently working with functions in which the output is a probability distribution. As so, they obey some restrictions (must be positive, for example).

I don't mind if you want to change the output, but if you do, I can't guarantee they will still be a probability. That's the main motivation to make iterations in the tidyverse fallback to default: tbl_df, tbl, data.frame.

But why create a class, them? Having a class would make it much easier to iterate among other functions. I just have to verify if inherits(some_random_object, "go_away") is TRUE.

It seems like a contradiction to me, you want the presence of the class as a way to knownyou can iterate on it, but you are asking for that class to disappear when it is touched by tidyverse transformations. Seems like these would therefore be fragile classes. I.e. you can use them so long as you don't mutate them, select them,filter them, etc...

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.