Nothing
#' Recode and replace using logical conditions
#'
#' @description
#'
#' - `vec_case_when()` constructs an entirely new vector by recoding the `TRUE`
#' `conditions` to their corresponding `values`. If there are locations not
#' matched by `conditions`, then they are recoded to the `default` value.
#'
#' - `vec_replace_when()` updates an existing vector by replacing the values
#' from `x` matched by the `TRUE` `conditions` with their corresponding
#' `values`. In this case, each element of `values` must have the same type as
#' `x` and locations not matched by `conditions` retain their original `x`
#' value.
#'
#' `vec_case_when()` is often thought of as a way to vectorize multiple if-else
#' statements, and is an R equivalent of the SQL "searched" `CASE WHEN`
#' statement.
#'
#' @inheritParams rlang::args_dots_empty
#' @inheritParams rlang::args_error_context
#'
#' @param x A vector.
#'
#' @param conditions A list of logical condition vectors.
#'
#' For `vec_case_when()`, each vector should be the same size.
#'
#' For `vec_replace_when()`, each vector should be the same size as `x`.
#'
#' Where a value in `conditions` is `TRUE`, the corresponding value in
#' `values` will be assigned to the result.
#'
#' @param values A list of vectors.
#'
#' For `vec_case_when()`, each vector should be size 1 or the size implied by
#' `conditions`. The common type of `values` and `default` determine the
#' output type, unless overridden by `ptype`.
#'
#' For `vec_replace_when()`, each vector should be size 1 or the same size
#' as `x`. Each vector will be cast to the type of `x`.
#'
#' @param default Default value to use when `conditions` does not match every
#' location in the output.
#'
#' By default, a missing value is used as the default value.
#'
#' If supplied, `default` must be size 1 or the size implied by `conditions`.
#'
#' Can only be set when `unmatched = "default"`.
#'
#' @param unmatched Handling of unmatched locations.
#'
#' One of:
#'
#' - `"default"` to use `default` in unmatched locations.
#'
#' - `"error"` to error when there are unmatched locations.
#'
#' @param ptype An optional override for the output type, which is usually
#' computed as the common type of `values` and `default`.
#'
#' @param size An optional override for the output size, which is usually
#' computed as the size of the first element of `conditions`.
#'
#' Only useful for requiring a fixed size when `conditions` is an empty list.
#'
#' @param x_arg,conditions_arg,values_arg,default_arg Argument names used in
#' error messages.
#'
#' @returns
#' A vector.
#'
#' - For `vec_case_when()`, the type of the output is computed as the common
#' type of `values` and `default`, unless overridden by `ptype`. The names of
#' the output come from the names of `values` and `default`. The size of the
#' output comes from the implied size from `conditions`, unless overridden by
#' `size`.
#'
#' - For `vec_replace_when()`, the type of the output will have the same type as
#' `x`. The names of the output will be the same as the names of `x`. The size
#' of the output will be the same size as `x`.
#'
#' @name vec-case-and-replace
#'
#' @examples
#' # Note how the first `TRUE` is used in the output.
#' # Also note how the `NA` falls through to `default`.
#' x <- seq(-2L, 2L, by = 1L)
#' x <- c(x, NA)
#' conditions <- list(
#' x < 0,
#' x < 1
#' )
#' values <- list(
#' "<0",
#' "<1"
#' )
#' vec_case_when(
#' conditions,
#' values,
#' default = "other"
#' )
#'
#' # Missing values need to be handled with their own case
#' # if you want them to have a special value
#' conditions <- list(
#' x < 0,
#' x < 1,
#' is.na(x)
#' )
#' values <- list(
#' "<0",
#' "<1",
#' NA
#' )
#' vec_case_when(
#' conditions,
#' values,
#' default = "other"
#' )
#'
#' # Both `values` and `default` are vectorized
#' values <- list(
#' x * 5,
#' x * 10,
#' NA
#' )
#' vec_case_when(
#' conditions,
#' values,
#' default = x * 100
#' )
#'
#' # Use `vec_replace_when()` if you need to update `x`, retaining
#' # all previous values in locations that you don't match
#' conditions <- list(
#' x < 0,
#' x < 1
#' )
#' values <- list(
#' 0,
#' 1
#' )
#' out <- vec_replace_when(
#' x,
#' conditions,
#' values
#' )
#' out
#'
#' # Note how `vec_replace_when()` is type stable on `x`, we retain the
#' # integer type here even though `values` contained doubles
#' typeof(out)
#'
#' # `vec_case_when()` creates a new vector, so names come from `values`
#' # and `default`. `vec_replace_when()` modifies an existing vector, so
#' # names come from `x` no matter what, just like `[<-` and `base::replace()`
#' x <- c(a = 1, b = 2, c = 3)
#' conditions <- list(x == 1, x == 2)
#' values <- list(c(x = 0), c(y = -1))
#' vec_case_when(conditions, values)
#' vec_replace_when(x, conditions, values)
#'
#' # If you want to enforce that you've covered all of the locations in your
#' # `conditions`, use `unmatched = "error"` rather than providing a `default`
#' x <- c(0, 1, 2)
#' conditions <- list(x == 1, x == 2)
#' values <- list("a", "b")
#' try(vec_case_when(conditions, values, unmatched = "error"))
NULL
#' @rdname vec-case-and-replace
#' @export
vec_case_when <- function(
conditions,
values,
...,
default = NULL,
unmatched = "default",
ptype = NULL,
size = NULL,
conditions_arg = "conditions",
values_arg = "values",
default_arg = "default",
error_call = current_env()
) {
check_dots_empty0(...)
.Call(
ffi_vec_case_when,
conditions,
values,
default,
unmatched,
ptype,
size,
environment()
)
}
#' @rdname vec-case-and-replace
#' @export
vec_replace_when <- function(
x,
conditions,
values,
...,
x_arg = "x",
conditions_arg = "conditions",
values_arg = "values",
error_call = current_env()
) {
check_dots_empty0(...)
.Call(
ffi_vec_replace_when,
x,
conditions,
values,
environment()
)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.