Switch the values of the vector by another on specific indices.

OX(.f, ..., .then = list(...)[[1]], .else = rev(list(...))[[1]])

XO(.f, ..., .then = list(...)[[1]], .else = rev(list(...))[[1]])

Arguments

.f

(function)
evaluated as .f(...). Must return a vector of indices (logical or integer), which defines which values will be replaced by .else.

...

arguments passed to the .f.

.then

(list, atomic, NULL)
A positive-replacement. NOTE, that if .then is not specified directly by named argument then the first argument from ... will be taken.

.else

(list, atomic, NULL)
A negative-replacement. Should be of length equal to length of .then, or single value or NULL. NOTE, that if .else is not specified directly by named argument then the last argument from ... will be considered as a replacement.

Value

atomic or list. Returned object is a .then object with elements replaced by .else depending on a result of the logical condition.

Details

Figure: uml2.jpg

#' OX evaluates function .f which returns a vector of indices which are then decide which values of .then are replaced by else.

.then[!idx] <- .else[!idx]

Consequence of above is that idx = .f(...) should be a logical vector or integer vector which would be valid indices for .then and .else. This means that .then and .else should be of the same length, but there are two exceptions:

  • when .else is a single value, than this value will replace .then at returned indices .then[!idx] <- .else

  • when .else is NULL

To invert the switch one can use XO which is equivalent of OX(Negate(.f), ..., .then, .else).

Examples

# switch values of the vector when condition is true
OX(is.na, c(1, NA, 3), .else = c(2, 2, 2))
#> [1]  2 NA  2

# use OX to invert negate the condition
XO(is.na, c(1, NA, 3), .else = c(2, 2, 2))
#> [1] 1 2 3