Unlist behaviour on vctr_rcrd class objects

66 views Asked by At

I have a vctr_record type object that I want to serve as input for code I can't/shouldn't change.

The problem I'm having is, that the lapply-then-unlist behaviour in that code is causing my vctr_record type object to be flattened. However that is not behaviour that I want, I want that the vctr_record type is preserved after unlisting.

I'm aware of why unlist doesn't preserve attributes or such, but I'm hoping somebody would know a workaround that doesn't involve me filing a github issue that can take quite some time to turn around.

Below is an example of this behaviour:

library(vctrs)

# Setting up a constructor
facvec <- function(f) {
  vec_assert(f, partial_factor())
  new_rcrd(fields = list(f = f), class = "facvec")
}

# Setting up how facvec's should be combined
# Based on: https://vctrs.r-lib.org/articles/s3-vector.html
vec_ptype2.facvec <- function(x, y, ...) UseMethod("vec_ptype2.facvec", y)
vec_ptype2.facvec.default <- function(x, y, ..., x_arg = "x", y_arg = "y") {
  vec_default_ptype2(x, y, x_arg = x_arg, y_arg = y_arg)
}
vec_ptype2.facvec.facvec <- function(x, y, ...) {
  facvec(f = vec_c(field(x, "f"), field(y, "f")))
}

# Just for prettier printing
format.facvec <- function(x) {
  field(x, "f")
}

# Some dummy data
a <- facvec(factor(c("a", "b")))
b <- facvec(factor(c("c")))

# The problematic operation
unlist(list(a, b))
#> f1 f2  f 
#>  a  b  c 
#> Levels: a b c

# What I would like the unlist to return
c(a, b)
#> <facvec[3]>
#> [1] a b c
#> Levels: a b c

Created on 2019-12-18 by the reprex package (v0.3.0)

The problem gets worse as more fields are added to the vctr_record type object.

Is there maybe some smart trick in the vctrs package that can help me get around this problem? I'm afraid I really can't change the unlist in the other code.

0

There are 0 answers