R/onezero.R

Defines functions onezero

Documented in onezero

#' Converts a vector to all 1/0s
#'
#' Converts a vector into ones and zeroes, any values which fall outside of what
#' is set by the arguments gets converted to missing. Option to retain missing
#' values if nothing is passed to `zero`.
#'
#' @seealso [onezero::is_onezero()]
#'
#' @return A numeric vector of ones and zeros.
#'
#' @param x A vector.
#' @param one_values Vector of values in `x` to receive values of 1. Cannot be used in
#' combination with `one_threshold`.
#' @param zero_values Vector of values in `x` to receive values of 0. Values not specified in
#' this argument will be turned into missing. If this argument is left empty, all remaining
#' values assumed to receive value of 0. Cannot be used in combination with `one_threshold`.
#' @param one_threshold Character string describing threshold for determining 1/0. Must follow
#' a logical-operator-then-value format, using <, <=, >, >=, ==, or !=. Cannot be used in combination
#' with `one_values` or `zero_values`.
#' @param keep.na Only needed if `one_values` is specified and `zero_values` is not, whether or not
#' to retain missing values during conversion, default `TRUE`.
#'
#' @importFrom
#' stringr str_split str_trim
#'
#' @examples
#'
#' x <- c("one", "zero", "foo", NA)
#' y <- 1:4
#'
#' onezero(x, one_values = "one")
#' onezero(x, one_values = "one", keep.na = FALSE)
#' onezero(x, one_values = "one", zero_values = "zero")
#' onezero(x, one_values = "one", zero_values = c("zero", "foo"))
#' onezero(x, one_values = "bar")
#' onezero(x, one_values = "bar", keep.na = FALSE)
#' onezero(x, one_values = "bar", zero_values = "baz")
#' onezero(y, one_threshold = "<= 2")
#'
#' @export
onezero <- function(x, one_values, zero_values, one_threshold, keep.na = TRUE) {

    # error check
    if (missing(x)) {
        stop("Must provide an input to `x`.")
    }

    if (missing(one_values) && missing(one_threshold)) {
        stop("Must provide an input to `one_values` or `one_threshold`.")
    }

    if (!missing(one_values) && !missing(one_threshold)) {
        stop("Must provide an input to only one of `one_values` or `one_threshold`.")
    }

    if (!missing(one_threshold)) {
        if (!is.numeric(x)) {
            stop("Must provide numeric input for `x` when using `one_threshold`.")
        }

        thresh.check <- str_trim(str_split(one_threshold, pattern = "\\d", simplify = TRUE))

        ops.allowed <- c(">", ">=", "<", "<=", "==", "!=")

        if (length(thresh.check) <= 1 || !thresh.check[1] %in% ops.allowed) {
            stop("Must provide a valid `one_threshold` string with an allowed logical operator.")
        }

        find.ones <- eval(parse(text=paste0("x", one_threshold)))
    } else {
        # find where the "ones" are
        find.ones <- x %in% one_values
    }

    # set ones and zeros
    x2 <- as.numeric(find.ones)

    if (!missing(zero_values) && missing(one_threshold)) {

        if (any(one_values %in% zero_values)) {
            warning("One or more values assigned to `one_values` have also been assigned to `zero_values`, these duplicates will be coded as 0.")
        }

        # find where the "zeros" are
        find.zeros <- x %in% zero_values

        x2[find.zeros] <- 0

        x2[!x %in% c(one_values, zero_values)] <- NA

    } else {

        if (keep.na) {

            find.na <- is.na(x)
            x2[find.na] <- NA

        }

    }

    x2

}
ttrodrigz/onezero documentation built on May 9, 2023, 2:59 p.m.