| vec_slice {vctrs} | R Documentation |
Get or set observations in a vector
Description
This provides a common interface to extracting and modifying observations
for all vector types, regardless of dimensionality. They are analogs to [
and [<- that match vec_size() instead of length().
Usage
vec_slice(x, i, ..., error_call = current_env())
vec_slice(x, i) <- value
vec_assign(x, i, value, ..., slice_value = FALSE, x_arg = "", value_arg = "")
Arguments
x |
A vector |
i |
An integer, character or logical vector specifying the locations or
names of the observations to get/set. Specify |
... |
These dots are for future extensions and must be empty. |
error_call |
The execution environment of a currently
running function, e.g. |
value |
A vector of replacement values
If If |
slice_value |
A boolean. If |
x_arg, value_arg |
Argument names for |
Value
A vector of the same type as x.
Genericity
Support for S3 objects depends on whether the object implements a
vec_proxy() method.
When a
vec_proxy()method exists, the proxy is sliced or assigned to andvec_restore()is called on the result.Otherwise,
vec_slice()falls back to the base generic[andvec_slice<-()falls back to the base generic[<-.
When vec_slice<-() falls back to [<-, it is expected that the subclass's
[<- method can handle the following subset of cases that base R's [<-
can also handle:
An
ivector of positive integer positions (notably excludingNA).A
valuevector of length 1 or lengthlength(i). If length 1, it should be recycled by the[<-method to the length ofi.
If your [<- method eventually calls base R's native [<- code, then these
cases will be handled for you.
Note that S3 lists are treated as scalars by default, and will
cause an error if they don't implement a vec_proxy() method.
Differences with base R subsetting
-
vec_slice()only slices along one dimension. For two-dimensional types, the first dimension is subsetted. -
vec_slice()preserves attributes by default. -
vec_slice<-()is type-stable and always returns the same type as the LHS.
Dependencies
vctrs dependencies
base dependencies
-
base::`[` -
base::`[<-`
Examples
x <- sample(10)
x
vec_slice(x, 1:3)
# You can assign with the infix variant:
vec_slice(x, 2) <- 100
x
# Or with the regular variant that doesn't modify the original input:
y <- vec_assign(x, 3, 500)
y
x
# Slicing objects of higher dimension:
vec_slice(mtcars, 1:3)
# Type stability --------------------------------------------------
# The assign variant is type stable. It always returns the same
# type as the input.
x <- 1:5
vec_slice(x, 2) <- 20.0
# `x` is still an integer vector because the RHS was cast to the
# type of the LHS:
vec_ptype(x)
# Compare to `[<-`:
x[2] <- 20.0
vec_ptype(x)
# Note that the types must be coercible for the cast to happen.
# For instance, you can cast a double vector of whole numbers to an
# integer vector:
vec_cast(1, integer())
# But not fractional doubles:
try(vec_cast(1.5, integer()))
# For this reason you can't assign fractional values in an integer
# vector:
x <- 1:3
try(vec_slice(x, 2) <- 1.5)
# Slicing `value` -------------------------------------------------
# Sometimes both `x` and `value` start from objects that are the same length,
# and you need to slice `value` by `i` before assigning it to `x`. This comes
# up when thinking about how `base::ifelse()` and `dplyr::case_when()` work.
condition <- c(TRUE, FALSE, TRUE, FALSE)
yes <- 1:4
no <- 5:8
# Create an output container and fill it
out <- vec_init(integer(), 4)
out <- vec_assign(out, condition, vec_slice(yes, condition))
out <- vec_assign(out, !condition, vec_slice(no, !condition))
out
# This is wasteful because you have to materialize the slices of `yes` and
# `no` before they can be assigned, and you also have to validate `condition`
# multiple times. Using `slice_value` internally performs
# `vec_slice(yes, condition)` and `vec_slice(no, !condition)` for you,
# but does so in a way that avoids the materialization.
out <- vec_init(integer(), 4)
out <- vec_assign(out, condition, yes, slice_value = TRUE)
out <- vec_assign(out, !condition, no, slice_value = TRUE)
out