|
| 1 | +#' Hold or Toss |
| 2 | +#' |
| 3 | +#' @param x A vector of values |
| 4 | +#' @param i An indication of which subset values to action. This can be a |
| 5 | +#' logical vector, an integer vector, or a function that takes `x` as an |
| 6 | +#' argument and returns a logical or integer vector |
| 7 | +#' @param na How to handle `NA` values in when `p` is a logical vector, or a |
| 8 | +#' function that returns a logical vector. [fuj::hold()] defaults to dropping |
| 9 | +#' `NA` values, while [fuj::toss()] defaults to keeping `NA` values. When `p` |
| 10 | +#' is an integer vector, `NA` values are always dropped. |
| 11 | +#' @name hot |
| 12 | +#' @examples |
| 13 | +#' x <- c(1, NA, 3, 4, Inf, 6) |
| 14 | +#' twos <- function(x) x %% 2 == 0 |
| 15 | +#' hold(x, twos) # 4, 6 |
| 16 | +#' toss(x, twos) # 1, 3, NA, Inf |
| 17 | +#' |
| 18 | +#' hold(x, twos, na = "keep") # NA, 4, Inf, 6 |
| 19 | +#' toss(x, twos, na = "drop") # 1, 3 |
| 20 | +#' |
| 21 | +#' i <- c(1:3, NA) |
| 22 | +#' x <- letters[1:5] |
| 23 | +#' hold(x, i) |
| 24 | +#' toss(x, i) |
| 25 | +#' |
| 26 | +#' @returns |
| 27 | +#' - [fuj::hold()] **retains** values in `x` matched against `i` |
| 28 | +#' - [fuj::toss()] **removes** values in `x` matched against `i` |
| 29 | +NULL |
| 30 | + |
| 31 | +#' @rdname hot |
| 32 | +#' @export |
| 33 | +hold <- function(x, i, na = c("drop", "keep")) { |
| 34 | + na <- match.arg(na, c("drop", "keep")) |
| 35 | + |
| 36 | + if (inherits(i, "logical")) { |
| 37 | + i[is.na(i)] <- na == "keep" |
| 38 | + return(x[i]) |
| 39 | + } |
| 40 | + |
| 41 | + if (integerish(i)) { |
| 42 | + return(x[i[!is.na(i)]]) |
| 43 | + } |
| 44 | + |
| 45 | + if (is.function(i)) { |
| 46 | + return(hold(x, vap_vec(x, i), na = na)) |
| 47 | + } |
| 48 | + |
| 49 | + stop(hot_input_error()) |
| 50 | +} |
| 51 | + |
| 52 | + |
| 53 | +#' @rdname hot |
| 54 | +#' @export |
| 55 | +toss <- function(x, i, na = c("keep", "drop")) { |
| 56 | + na <- match.arg(na, c("keep", "drop")) |
| 57 | + |
| 58 | + if (is.logical(i)) { |
| 59 | + i[is.na(i)] <- na == "drop" |
| 60 | + return(x[!i]) |
| 61 | + } |
| 62 | + |
| 63 | + if (integerish(i)) { |
| 64 | + return(x[-i[!is.na(i)]]) |
| 65 | + } |
| 66 | + |
| 67 | + if (is.function(i)) { |
| 68 | + return(toss(x, vap_vec(x, i), na = na)) |
| 69 | + } |
| 70 | + |
| 71 | + stop(hot_input_error()) |
| 72 | +} |
| 73 | + |
| 74 | +hot_input_error <- function() { |
| 75 | + input_error( |
| 76 | + "i must be logical, integer, integer-like numeric, or function which", |
| 77 | + " returns a logical, integer, or integer-like numeric" |
| 78 | + ) |
| 79 | +} |
0 commit comments