Vector Helpers

Defines new notions of prototype and size that are used to provide tools for consistent and well-founded type-coercion and size-recycling, and are in turn connected to ideas of type- and size-stability useful for analysing function interfaces.

Travis buildstatus Coveragestatus lifecycle

There are three main goals to the vctrs package, each described in a vignette:

  • To propose vec_size() and vec_type() as alternatives to length() and class(); vignette("type-size"). These definitions are paired with a framework for type-coercion and size-recycling.

  • To define type- and size-stability as desirable function properties, use them to analyse existing base function, and to propose better alternatives; vignette("stability"). This work has been particularly motivated by thinking about the ideal properties of c(), ifelse(), and rbind().

  • To provide a new vctr base class that makes it easy to create new S3 vectors; vignette("s3-vector"). vctrs provides methods for many base generics in terms of a few new vctrs generics, making implementation considerably simpler and more robust.

vctrs is a developer focused package. Understanding and extending vctrs requires some effort from developers, but should be invisible to most users. It’s our hope that having an underlying theory will mean that users can build up an accurate mental model without explicitly learning the theory. vctrs will typically be used by other packages, making it easy for them to provide new classes of S3 vectors that are supported throughout the tidyverse (and beyond). For that reason, vctrs has few dependencies.


vctrs is not currently on CRAN. Install the development version from GitHub with:

# install.packages("devtools")


# Prototypes
str(vec_type_common(FALSE, 1L, 2.5))
#>  num(0)
str(vec_cast_common(FALSE, 1L, 2.5))
#> List of 3
#>  $ : num 0
#>  $ : num 1
#>  $ : num 2.5
# Sizes
str(vec_size_common(1, 1:10))
#>  int 10
str(vec_recycle_common(1, 1:10))
#> List of 2
#>  $ : num [1:10] 1 1 1 1 1 1 1 1 1 1
#>  $ : int [1:10] 1 2 3 4 5 6 7 8 9 10


The original motivation for vctrs from two separate, but related problems. The first problem is that base::c() has rather undesirable behaviour when you mix different S3 vectors:

# combining factors makes integers
c(factor("a"), factor("b"))
#> [1] 1 1
# combing dates and date-times give incorrect values
dt <- as.Date("2020-01-1")
dttm <- as.POSIXct(dt)
c(dt, dttm)
#> [1] "2020-01-01"    "4321940-06-07"
c(dttm, dt)
#> [1] "2019-12-31 18:00:00 CST" "1969-12-31 23:04:22 CST"

This behaviour arises because c() has dual purposes: as well as it’s primary duty of combining vectors, it has a secondary duty of stripping attributes. For example, ?POSIXct suggests that you should use c() if you want to reset the timezone.

The second problem is that dplyr::bind_rows() is not extensible by others. Currently, it handles arbitrary S3 classes using heuristics, but these often fail, and it feels like we really need to think through the problem in order to build a principled solution. This intersects with the need to cleanly support more types of data frame columns including lists of data frames, data frames, and matrices.


Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


0.3.7 by Lionel Henry, 24 days ago

Report a bug at

Browse source code at

Authors: Hadley Wickham [aut] , Lionel Henry [aut, cre] , Davis Vaughan [aut] , data.table team [cph] (Radix sort based on data.table's forder() and their contribution to R's order()) , RStudio [cph]

Documentation:   PDF Manual  

MIT + file LICENSE license

Imports ellipsis, glue, rlang

Suggests bit64, covr, crayon, dplyr, generics, knitr, pillar, pkgdown, rmarkdown, testthat, tibble, withr, xml2, waldo, zeallot

Imported by AzureCosmosR, AzureTableStor, Microsoft365R, RSDA, SpatialKDE, almanac, arrow, bigsnpr, bioseq, blob, cleaner, clock, codebook, dbplyr, decor, dials, distributional, dm, downlit, dplyr, drake, dtplyr, eflm, era, evaluator, exuber, fabletools, feasts, ftExtra, furrr, ggdist, ggh4x, ggip, googlesheets4, gratia, groupr, hardhat, haven, hms, i2extras, incidence2, ipaddress, isoreader, jpmesh, jsontools, labelled, lvmisc, mobr, modelr, multidplyr, nestr, node2vec, pammtools, parsnip, pillar, plotly, pmdplyr, probably, projects, prt, reliabilitydiag, retroharmonize, ricu, riingo, rsample, salesforcer, santoku, sfcr, simTool, skimr, slider, sparklyr, spatialsample, supernova, tabnet, tarchetypes, targets, term, textrecipes, tfdatasets, tibble, tibbletime, tibblify, tidyRSS, tidypaleo, tidyposterior, tidyr, tidyselect, tidytable, tidytext, trending, triangulr, tsibble, tsibbletalk, tune,, vitae, vroom, waterquality, wkutils, workflows, workflowsets, yardstick.

Suggested by AzureGraph, SplitGLM,, bench, cpp11, cutpointr, errors, fastai, fauxnaif, fs, geos, glue, lubridate, multifear, quantities, rlang, rmarkdown, s2, sf, testthat, tidyjson, tinylabels, units, winch, wk.

See at CRAN