Extracting values from a tibble using a custom class object

I'd like to extract values from a tbl_df object using a character string with a custom class but I'm getting the following error:

bar <- structure("x", class = c("foo", "character"))
tbl <- tibble::tibble(x = 1:3, y = letters[1:3])
tbl[[bar]]

#> Error in `tbl[[bar]]`:
#> ! Can't extract column with `bar`.
#> ✖ `bar` must be numeric or character, not a <foo/character> object.

Is there a work around for this that doesn't consist in removing the tbl_df/tbl classes of the tibble or rewriting accessor methods?

What's the motivation? Are you trying to use a rowname selector?

I'm developing a package that has functions generating objects with a custom class to perform input checks and work with some S3 methods. Some of these objects can be used to get data from a tibble. Currently, what I'm doing is removing the class of these object to extract the data and setting it back afterward but I don't like that.

That's probably easier than writing a new dispatch function for a tibble object.

To work with S3 vectors in the tidyverse context, use the vctrs library. I adapted the following by quickly reading the S3 vectors vignette :

library(tibble)
library(vctrs)

{#setup ####
new_foo <- function(x=character()){
  if(!is.character(x)){
    abort("foo must wrap a character type")
  }
  new_vctr(x,class="vctrs_foo")
}

vec_ptype2.vctrs_foo.character <- function(x,y,...)character()
vec_ptype2.character.vctrs_foo <- function(x,y,...)character()
vec_cast.vctrs_foo.vctrs_foo <- function(x,to ,...) x
vec_cast.vctrs_foo.character <- function(x, to, ...) new_foo(x)
vec_cast.character.vctrs_foo <- function(x, to, ...) vec_data(x)
}

tbl <- tibble::tibble(x = 1:3, y = letters[1:3])
(bar <- new_foo("x"))

tbl[[bar]]
1 Like

Thanks, that suits me better! Will have a look at the vignette to learn more.

This topic was automatically closed 7 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.