Last active
June 12, 2017 17:39
-
-
Save alandipert/6ca9f895fa0a4527deaa78292a0488c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' Chained Conditional Element Selection | |
#' | |
#' \code{cond} takes even number of arguments representing a series of | |
#' \code{test}/\code{value} pairs, and returns a value with the same shape as | |
#' every \code{test}. The returned element is filled with the elements selected | |
#' from every \code{value} depending on whether its corresponding \code{test} is | |
#' \code{TRUE} or \code{FALSE}. | |
#' | |
#' @param ... An even number of \code{test}/\code{value} pairs. Every \code{test} | |
#' is coerced to logical mode. \code{test} arguments should be the same shape. | |
#' @param default Atomic value to use if no \code{test} was satisfied, or \code{NA} if not specified. | |
#' @examples | |
#' chars <- letters[1:5] | |
#' cond(chars %in% c("a", "c"), | |
#' as.character(1:5), | |
#' chars == "e", | |
#' "X", | |
#' default = chars) | |
#' @seealso \code{\link{ifelse}} | |
cond <- function(..., default = NA, env = parent.frame()) { | |
args <- eval(substitute(alist(...))) | |
if (length(args) == 0) { | |
return(default) | |
} else if (length(args) %% 2 != 0) { | |
stop("cond requires an even number of arguments") | |
} | |
test <- as.logical(eval(args[[1]], envir = env)) | |
ans <- test | |
ok <- !(nas <- is.na(test)) | |
if (any(test[ok])) | |
ans[test & ok] <- rep(eval(args[[2]], envir = env), | |
length.out = length(ans))[test & ok] | |
if (any(!test[ok])) | |
ans[!test & ok] <- do.call(cond, c(args[-1:-2], list(default = default, env = env)))[!test & ok] | |
ans[nas] <- NA | |
ans | |
} |
Cool stuff. I used it in my work. Also I just learned that dplyr
has the same (?) functionality with dplyr::case_when()
https://www.rdocumentation.org/packages/dplyr/versions/0.5.0/topics/case_when
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: a control-flow
cond
can be found here: https://gist.github.com/DASpringate/8595464