| Title: | Construct Mixed Type Data Structures with Vectors of Vectors |
|---|---|
| Description: | Mixed type vectors are useful for combining semantically similar classes. Some examples of semantically related classes include time across different granularities (e.g. daily, monthly, annual) and probability distributions (e.g. Normal, Uniform, Poisson). These groups of vector types typically share common statistical operations which vary in results with the attributes of each vector. The 'vecvec' data structure facilitates efficient storage and computation across multiple vectors within the same object. |
| Authors: | Mitchell O'Hara-Wild [aut, cre] (ORCID: <https://orcid.org/0000-0001-6729-7695>) |
| Maintainer: | Mitchell O'Hara-Wild <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.1.0 |
| Built: | 2026-06-03 21:59:10 UTC |
| Source: | https://github.com/mitchelloharawild/vecvec |
class_vecvec() constructs a new vecvec object from a list of vectors. It is
designed to be performant with minimal checks on the inputs. Direct use of
class_vecvec() is useful for developers, but for users it is recommended to
use vecvec() to create vecvec objects.
class_vecvec(x = list(), i = seq_len(sum(lengths(x))))class_vecvec(x = list(), i = seq_len(sum(lengths(x))))
x |
An unnamed list of arbitrary vectors. The vectors can be of different types and lengths, but they must all be vectors (according to vctrs::vec_is). Adjacent vectors of the same type will be combined together into a single vector. |
i |
A vector of integers specifying the location of each element in |
A vector of vectors of S7 object of class class_vecvec.
# Create a vecvec prototype class_vecvec() # Construct a vecvec from a list of vectors class_vecvec(list(letters, rnorm(10))) # Fully specify a vecvec with locations class_vecvec( x = list(letters, rnorm(10)), i = c(1:3, 27:31, 26:4, 32:36) )# Create a vecvec prototype class_vecvec() # Construct a vecvec from a list of vectors class_vecvec(list(letters, rnorm(10))) # Fully specify a vecvec with locations class_vecvec( x = list(letters, rnorm(10)), i = c(1:3, 27:31, 26:4, 32:36) )
Test if an object is a vecvec
is_vecvec(x)is_vecvec(x)
x |
Object to test. |
TRUE if x inherits from class_vecvec, FALSE otherwise.
vecvec() to create a vecvec object.
vv <- vecvec(1:3, letters) is_vecvec(vv) is_vecvec(1:3)vv <- vecvec(1:3, letters) is_vecvec(vv) is_vecvec(1:3)
var, cov, and cor compute the variance of x and the covariance or
correlation of x and y if these are vectors. If x and y are matrices then
the covariances (or correlations) between the columns of x and the columns
of y are computed.
These functions mask and wrap the stats::var, stats::cov, and
stats::cor functions to add support for vecvec objects. More details
can be found in the documentation for those functions.
var(x, ...) cov(x, ...) cor(x, ...)var(x, ...) cov(x, ...) cor(x, ...)
x |
a numeric vector, matrix or data frame. |
... |
Additional arguments passed to |
stats::var(), stats::cov(), stats::cor()
Flattens a vecvec into a plain R vector by casting all elements to a
common type. This is the inverse of vecvec().
Type resolution follows vctrs coercion rules: when ptype is NULL the
common type is determined automatically from the slots of x via
vctrs::vec_ptype_common(). If no common type can be found (e.g. all slots
are empty), the result falls back to logical().
unvecvec(x, ptype = NULL)unvecvec(x, ptype = NULL)
x |
A |
ptype |
A prototype specifying the desired output type, e.g.
|
A vector of length length(x) and type ptype (or the inferred
common type when ptype = NULL). Positions corresponding to NA indices
in the underlying vecvec structure are filled with NA.
vecvec() to create a vecvec; vctrs::vec_ptype_common() for
the type inference rules; vctrs::vec_cast() for the casting rules.
vv <- vecvec(1:3, c(4.5, 5.5)) # Automatic type inference: integer + double -> double unvecvec(vv) # Force a specific output type unvecvec(vv, ptype = character())vv <- vecvec(1:3, c(4.5, 5.5)) # Automatic type inference: integer + double -> double unvecvec(vv) # Force a specific output type unvecvec(vv, ptype = character())
A vecvec is a vector that holds elements of different types without
coercing them to a common type. Unlike a list of vectors, a vecvec behaves
as a flat vector (hence vector of vectors). This means that you can
operations (such as indexing, arithmetic, and statistics) apply across all
elements of a vecvec as if they were combined into a single vector.
Mixed-type vectors can be useful if you need to store heterogeneous data in a vector-like structure. In most cases, I believe this is bad practice for data analytics, but this could be useful for tidying up messy data. The most valuable use case for vecvec is as a data structure for mixed-type semantic vectors. This package is used by mixtime and distributional to create vectors of time with different chronons and distributions with different shapes.
To convert a vecvec back to a plain typed vector, use unvecvec(), which
casts all elements to a common type via vctrs::vec_cast().
vecvec(...)vecvec(...)
... |
Vectors to combine. Each vector is stored as a separate typed slot; no type coercion is performed. |
A vecvec object whose length equals the total number of elements
across all input vectors.
unvecvec() to coerce a vecvec to a single-typed vector;
is_vecvec() to test whether an object is a vecvec.
# Mixed types are preserved without coercion vv <- vecvec(Sys.Date(), rnorm(3), letters) vv # .[i] Indexing works like a flat vector vv[c(1L, 3L, 7L)] # .[[i]] drops to the original vector type vv[[2L]]# Mixed types are preserved without coercion vv <- vecvec(Sys.Date(), rnorm(3), letters) vv # .[i] Indexing works like a flat vector vv[c(1L, 3L, 7L)] # .[[i]] drops to the original vector type vv[[2L]]
The vecvec_apply() function applies a function .f to each vector in the
vecvec vectors.
vecvec_apply(x, .f, ...)vecvec_apply(x, .f, ...)
x |
A vecvec object |
.f |
A function to apply to each vector |
... |
Additional arguments passed to |
A vecvec data type with the same structure as x but with each
vector transformed by .f.
The vecvec_apply_fn() function is a function factory that creates applies
the function .f to each vector and optionally simplifies the result with
[unvecvec()]. The function matches the forms of the original function
.f and can be used to define methods for generic functions that apply to
vecvec objects. If .f is a primitive function, the resulting function will
have a apply over an argument x and pass through ....
vecvec_apply_fn(.f, ptype = NULL, SIMPLIFY = !is.null(ptype))vecvec_apply_fn(.f, ptype = NULL, SIMPLIFY = !is.null(ptype))
.f |
A function to apply to each vector |
ptype |
A prototype to simplify to. If |
SIMPLIFY |
If |
A function that applies .f to each vector of a vecvec object and
optionally simplifies the result.
Call vecvec_register() inside your package's .onLoad() function to
register the S3 methods that allow a custom
vecvec subclass to participate in the
vctrs vector system.
vecvec_register(x)vecvec_register(x)
x |
An S7 class object that extends class_vecvec. Typically the
class object created by |
Specifically, vecvec_register() registers:
vec_cast.<class>.* methods, so that other types can be cast to your
vecvec subclass.
vec_cast.*.<class> methods, so that your vecvec subclass can be cast
from other types.
NULL, invisibly. Called for its side effects.
## Not run: # In your package, define a vecvec subclass: class_myvec <- S7::new_class( "myvec", parent = vecvec::class_vecvec ) # Then register it in .onLoad(): .onLoad <- function(libname, pkgname) { S7::methods_register() vecvec::vecvec_register(class_myvec) } ## End(Not run)## Not run: # In your package, define a vecvec subclass: class_myvec <- S7::new_class( "myvec", parent = vecvec::class_vecvec ) # Then register it in .onLoad(): .onLoad <- function(libname, pkgname) { S7::methods_register() vecvec::vecvec_register(class_myvec) } ## End(Not run)