vctrs 0.6.5

vctrs 0.6.4

vctrs 0.6.3

vctrs 0.6.2

vctrs 0.6.1

vctrs 0.6.0

vctrs 0.5.2

vctrs 0.5.1

vctrs 0.5.0

Following this change, the role of list_of() is mainly to carry type information for potential optimisations, rather than to guarantee a certain type throughout an analysis.

"unique_quiet" and "universal_quiet" are also newly accepted for the name repair argument of several other functions that do not expose a quiet argument: data_frame(), df_list(), vec_c(), list_unchop(), vec_interleave(), vec_rbind(), and vec_cbind() (@jennybc, #1716).

vctrs 0.4.2

vctrs 0.4.1

vctrs 0.4.0

This may result in unhelpful arguments being mentioned in error messages. In general, you should consider snapshotting vctrs error messages thrown in your package and supply arg and call arguments if the error context is not adequately reported to your users.

Note that default vec_cast() and vec_ptype2() methods automatically support this if they pass ... to the corresponding vec_default_ functions. If you throw a non-internal error from a non-default method, add a call = caller_env() argument in the method and pass it to rlang::abort().

vctrs 0.3.8

vctrs 0.3.7

vctrs 0.3.6

vctrs 0.3.5

vctrs 0.3.4

vctrs 0.3.3

``` zap_outer_spec <- function(outer, inner) if (is_character(inner)) inner

# NULL names rather than a vector of "" names(vec_c(a = 1:2, .name_spec = zap_outer_spec)) #> NULL

# Names are allocated when inner names exist names(vec_c(a = 1:2, c(b = 3L), .name_spec = zap_outer_spec)) #> [1] "" "" "b" ```

vctrs 0.3.2

vctrs 0.3.1

CRAN results

vctrs 0.3.0

This version features an overhaul of the coercion system to make it more consistent and easier to implement. See the Breaking changes and Type system sections for details.

There are three new documentation topics if you'd like to learn how to implement coercion methods to make your class compatible with tidyverse packages like dplyr:

Reverse dependencies troubleshooting

The following errors are caused by breaking changes.

vec_cast() no longer converts to list. Use vec_chop() or as.list() instead.

vec_cast() no longer converts to character. Use as.character()to deparse objects.

Names of list-columns are now preserved by vec_rbind(). Adjust tests accordingly.

Breaking changes

For example, a tibble subclass no longer inherits from the vec_ptype2() methods between tbl_df and data.frame. This means that you explicitly need to implement vec_ptype2() methods with tbl_df and data.frame.

This change requires a bit more work from class maintainers but is safer because the coercion hierarchies are generally different from class hierarchies. See the S3 dispatch section of ?vec_ptype2 for more information.

Type system

#' @export <- function(x, y, ...) new_foo()

vctrs also takes care of implementing the default and unspecified methods. If you have implemented these methods, they are no longer called and can now be removed.

One consequence of the new dispatch mechanism is that NextMethod() is now completely unsupported. This is for the best as it never worked correctly in a double-dispatch setting. Parent methods must now be called manually.

If necessary, the row names are repaired verbosely but without error to make them unique. This should be a mostly harmless change for users, but it could break unit tests in packages if they make assumptions about the row names.

Compatibility and fallbacks

This is particularly problematic with subclasses of data frames for which throwing incompatible errors would be too incovenient for users. To work around this, we have implemented a fallback to the relevant base data frame class (either data.frame or tbl_df) in coercion methods (#981). This fallback is silent unless you set the vctrs:::warn_on_fallback option to TRUE.

In the future we may extend this fallback principle to other base types when they are explicitly included in the class vector (such as "list").

These fallbacks do not make your class completely compatible with vctrs-powered packages, but they should help in many simple cases.

Vector operations

For instance, column-binding a grouped data frame with a data frame now produces a tibble (the simplified class of a grouped data frame).


Indexing and names


CRAN results

vctrs 0.2.4

vctrs 0.2.3

x <- list(1, 2) vec_slice(x, 1) <- NA x #> [[1]] #> NULL #> #> [[2]] #> 2

vctrs 0.2.2

We introduced this breaking change in a patch release because new_vctr() now adds the base type to the class vector by default, which caused vec_ptype2() to dispatch erroneously to the methods for base types. We'll finish switching to this approach in vctrs 0.3.0 for the rest of the base S3 classes (dates, data frames, ...).

vctrs 0.2.1

Maintenance release for CRAN checks.

vctrs 0.2.0

With the 0.2.0 release, many vctrs functions have been rewritten with native C code to improve performance. Functions like vec_c() and vec_rbind() should now be fast enough to be used in packages. This is an ongoing effort, for instance the handling of factors and dates has not been rewritten yet. These classes still slow down vctrs primitives.

The API in 0.2.0 has been updated, please see a list of breaking changes below. vctrs has now graduated from experimental to a maturing package. Please note that API changes are still planned for future releases, for instance vec_ptype2() and vec_cast() might need to return a sentinel instead of failing with an error when there is no common type or possible cast.

Breaking changes

`` vec_c(foo = c(a = 1)) #> Error: Can't merge the outer namefoowith a named vector. #> Please supply a.name_spec` specification.

vec_c(foo = 1:3) #> Error: Can't merge the outer name foo with a vector of length > 1. #> Please supply a .name_spec specification. ```

You can supply a name specification that describes how to combine the external name of the input with its internal names or positions:

``` # Name spec as glue string: vec_c(foo = c(a = 1), .name_spec = "{outer}_{inner}")

# Name spec as a function: vec_c(foo = c(a = 1), .name_spec = function(outer, inner) paste(outer, inner, sep = "")) vec_c(foo = c(a = 1), .name_spec = ~ paste(.x, .y, sep = "")) ```

Consequently, vec_ptype() was renamed to vec_ptype_show().

New features

The most common case where you need to implement vec_proxy() is for S3 lists. In vctrs, S3 lists are treated as scalars by default. This way we don't treat objects like model fits as vectors. To prevent vctrs from treating your S3 list as a scalar, unclass it from the vec_proxy() method. For instance here is the definition for list_of:

#' @export vec_proxy.vctrs_list_of <- function(x) { unclass(x) }

If you inherit from vctrs_vctr or vctrs_rcrd you don't need to implement vec_proxy().

``` df1 <- tibble(foo = tibble(bar = tibble(x = 1:3, y = letters[1:3]))) df2 <- tibble(foo = tibble(bar = tibble(x = 1:3, y = 4:6)))

vec_rbind(df1, df2) #> Error: No common type for ..1$foo$bar$y and ..2$foo$bar$y . ```

r data <- tibble::tibble(x = 1:3, y = letters[1:3]) data <- vec_cbind(data, packed = data) data # A tibble: 3 x 3 x y packed$x $y <int> <chr> <int> <chr> 1 1 a 1 a 2 2 b 2 b 3 3 c 3 c

Packed data frames are nested in a single column. This makes it possible to access it through a single name:

r data$packed # A tibble: 3 x 2 x y <int> <chr> 1 1 a 2 2 b 3 3 c

We are planning to use this syntax more widely in the tidyverse.

Called without a specific type or size, vec_assert() tests whether an object is a data vector or a scalar. S3 lists are treated as scalars by default. Implement a vec_is_vector() for your class to override this property (or derive from vctrs_vctr).

Other features and bug fixes

Try the vctrs package in your browser

Any scripts or data that you put into this service are public.

vctrs documentation built on May 29, 2024, 11:39 a.m.