This provides a common interface to extracting and modifying observations
for all vector types, regardless of dimensionality. It is an analog to [
that matches vec_size() instead of length().
vec_slice(x, i, ..., error_call = current_env())
vec_slice(x, i) <- value
vec_assign(x, i, value, ..., x_arg = "", value_arg = "")A vector
An integer, character or logical vector specifying the
locations or names of the observations to get/set. Specify
TRUE to index all elements (as in x[]), or NULL, FALSE or
integer() to index none (as in x[NULL]).
These dots are for future extensions and must be empty.
The execution environment of a currently
running function, e.g. caller_env(). The function will be
mentioned in error messages as the source of the error. See the
call argument of abort() for more information.
Replacement values. value is cast to the type of
x, but only if they have a common type. See below for examples
of this rule.
Argument names for x and value. These are used
in error messages to inform the user about the locations of
incompatible types and sizes (see stop_incompatible_type() and
stop_incompatible_size()).
A vector of the same type as x.
Support for S3 objects depends on whether the object implements a
vec_proxy() method.
When a vec_proxy() method exists, the proxy is sliced and
vec_restore() is called on the result.
Otherwise vec_slice() falls back to the base generic [.
Note that S3 lists are treated as scalars by default, and will
cause an error if they don't implement a vec_proxy() method.
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.
If a non-data-frame vector class doesn't have a vec_proxy()
method, the vector is sliced with [ instead.
x <- sample(10)
x
#> [1] 6 3 1 4 10 8 7 2 5 9
vec_slice(x, 1:3)
#> [1] 6 3 1
# You can assign with the infix variant:
vec_slice(x, 2) <- 100
x
#> [1] 6 100 1 4 10 8 7 2 5 9
# Or with the regular variant that doesn't modify the original input:
y <- vec_assign(x, 3, 500)
y
#> [1] 6 100 500 4 10 8 7 2 5 9
x
#> [1] 6 100 1 4 10 8 7 2 5 9
# Slicing objects of higher dimension:
vec_slice(mtcars, 1:3)
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#> Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#> Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
# 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)
#> integer(0)
# Compare to `[<-`:
x[2] <- 20.0
vec_ptype(x)
#> numeric(0)
# 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())
#> [1] 1
# But not fractional doubles:
try(vec_cast(1.5, integer()))
#> Error in eval(expr, envir) :
#> Can't convert from `1.5` <double> to <integer> due to loss of precision.
#> • Locations: 1
# For this reason you can't assign fractional values in an integer
# vector:
x <- 1:3
try(vec_slice(x, 2) <- 1.5)
#> Error in `vec_slice<-`(`*tmp*`, 2, value = 1.5) :
#> Can't convert from `1.5` <double> to <integer> due to loss of precision.
#> • Locations: 1