I'm trying to understand how to build objects with vectors. I thought this was straightforwards, but then had trouble when I used c() on my object.
Our object has two attributes, x and descriptor, both strings in this case (my object will have attributes with differing types). We've built a constructor, new_toy_vector. I haven't built a convenience function in this example yet.
new_toy_vector <- function(
x = character(),
descriptor = character()) {
vctrs::vec_assert(x,character())
vctrs::vec_assert(descriptor, character())
vctrs::new_vctr(x,
descriptor = descriptor,
class = "toy_vector")
}
format.toy_vector <- function(x, ...) {
paste0(vctrs::vec_data(x)," is ", attr(x, "descriptor"))
}
obj_print_data.toy_vector <- function(x) {
cat(format(x), sep = "\n")
}
c(new_toy_vector("Hello", "Foo"), new_toy_vector("World", "Bar"))
#> Error: No common type for `..1` <toy_vector> and `..2` <toy_vector>.
Created on 2020-04-26 by the reprex package (v0.3.0)
I then tried to create a coercion with itself unless the default method wasn't defined for some reason:
> vec_ptype2.toy_vector.toy_vector <- function(x, y, ...) new_toy_vector()
> c(new_toy_vector("Hello", "Foo"), new_toy_vector("World", "Bar"))
Error: Can't convert <toy_vector> to <toy_vector>.
Any ideas what I'm missing or misunderstanding? Why can't I combine the two objects in the example?
Add an explicit
`[.toy_vector`which subsets thedescriptorattribute.Like this:
I'm not sure how to get attributes to 'subset' in this way using
vctrs, or even if it's possible. But using this method we can basically do whatvctrsdoes, and then some.Bear in mind that subsetting generic will no longer call the
`[.vctrs_vctr`method, so you'll lose othervctrsfunctionallity (such as subsetting sub-classes withvec_restore()) and may need to implement further fixes in the`[.toy_vector`method.Created on 2021-01-19 by the reprex package (v0.3.0)