R: Chopping

vec_chop {vctrs} | R Documentation

## Chopping

### Description

- `vec_chop()` provides an efficient method to repeatedly slice a vector. It captures the pattern of `map(indices, vec_slice, x = x)`. When no indices are supplied, it is generally equivalent to `as.list()`.

- `vec_unchop()` combines a list of vectors into a single vector, placing elements in the output according to the locations specified by `indices`. It is similar to `vec_c()`, but gives greater control over how the elements are combined. When no indices are supplied, it is identical to `vec_c()`.

If `indices` selects every value in `x` exactly once, in any order, then `vec_unchop()` is the inverse of `vec_chop()` and the following invariant holds:

    vec_unchop(vec_chop(x, indices), indices) == x

### Usage

    vec_chop(x, indices = NULL)

    vec_unchop(
      x,
      indices = NULL,
      ptype = NULL,
      name_spec = NULL,
      name_repair = c("minimal", "unique", "check_unique", "universal")
    )

### Arguments

`x` | A vector
`indices` | For `vec_chop()`, a list of positive integer vectors to slice `x` with, or `NULL`. If `NULL`, `x` is split into its individual elements, equivalent to using an `indices` of `as.list(vec_seq_along(x))`. For `vec_unchop()`, a list of positive integer vectors specifying the locations to place elements of `x` in. Each element of `x` is recycled to the size of the corresponding index vector. The size of `indices` must match the size of `x`. If `NULL`, `x` is combined in the order it is provided in, which is equivalent to using `vec_c()`.
`ptype` | If `NULL`, the default, the output type is determined by computing the common type across all elements of `x`. Alternatively, you can supply `ptype` to give the output a known type.
`name_spec` | A name specification for combining inner and outer names. This is relevant for inputs passed with a name, when these inputs are themselves named, like `outer = c(inner = 1)`, or when they have length greater than 1: `outer = 1:2`. By default, these cases trigger an error. You can resolve the error by providing a specification that describes how to combine the names or the indices of the inner vector with the name of the input. This specification can be: A function of two arguments. The outer name is passed as a string to the first argument, and the inner names or positions are passed as second argument. An anonymous function as a purrr-style formula. A glue specification of the form `"{outer}_{inner}"`. An `rlang::zap()` object, in which case both outer and inner names are ignored and the result is unnamed. See the name specification topic.
`name_repair` | How to repair names, see `repair` options in `vec_as_names()`.

### Value

- `vec_chop()`: A list of size `vec_size(indices)` or, if `indices == NULL`, `vec_size(x)`.

- `vec_unchop()`: A vector of type `vec_ptype_common(!!!x)`, or `ptype`, if specified. The size is computed as `vec_size_common(!!!indices)` unless the indices are `NULL`, in which case the size is `vec_size_common(!!!x)`.

### Dependencies of `vec_chop()`

- `vec_slice()`

### Dependencies of `vec_unchop()`

- `vec_c()`

### Examples

    vec_chop(1:5)
    vec_chop(1:5, list(1, 1:2))
    vec_chop(mtcars, list(1:3, 4:6))

    # If `indices` selects every value in `x` exactly once,
    # in any order, then `vec_unchop()` inverts `vec_chop()`
    x <- c("a", "b", "c", "d")
    indices <- list(2, c(3, 1), 4)
    vec_chop(x, indices)
    vec_unchop(vec_chop(x, indices), indices)

    # When unchopping, size 1 elements of `x` are recycled
    # to the size of the corresponding index
    vec_unchop(list(1, 2:3), list(c(1, 3, 5), c(2, 4)))

    # Names are retained, and outer names can be combined with inner
    # names through the use of a `name_spec`
    lst <- list(x = c(a = 1, b = 2), y = 1)
    vec_unchop(lst, list(c(3, 2), c(1, 4)), name_spec = "{outer}_{inner}")

    # An alternative implementation of `ave()` can be constructed using
    # `vec_chop()` and `vec_unchop()` in combination with `vec_group_loc()`
    ave2 <- function(.x, .by, .f, ...) {
      indices <- vec_group_loc(.by)$loc
      chopped <- vec_chop(.x, indices)
      out <- lapply(chopped, .f, ...)
      vec_unchop(out, indices)
    }

    breaks <- warpbreaks$breaks
    wool <- warpbreaks$wool

    ave2(breaks, wool, mean)

    identical(
      ave2(breaks, wool, mean),
      ave(breaks, wool, FUN = mean)
    )

[Package vctrs version 0.3.2 Index]