Skip to content

Instantly share code, notes, and snippets.

@DASpringate
Last active May 19, 2017 15:24
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save DASpringate/8595464 to your computer and use it in GitHub Desktop.
Save DASpringate/8595464 to your computer and use it in GitHub Desktop.
A simple R implementation of `cond` from Lisp. Allows for arbitrary numbers of conditionals without nested if statements
#' R implementation of `cond` from Lisp
#' allows for arbitrary numbers of conditionals without ugly nested if statements
#' conditionals are entered as pairs of expressions (clauses),
#' first the expression to be evaluated and second the return value if the expression is true
#' @param ... an even number of expressions as pairs (see example)
#' @param true the `else` expression (Taken from the Lisp (T resultN) see http://www.cis.upenn.edu/~matuszek/LispText/lisp-cond.html)
#' @return The paired value of the first true conditional expression or the value of true
#' @examples
#' x <- runif(1)
#' cond(x < 0.2, "lower tail",
#' x < 0.8, "middle",
#' true = "upper tail")
cond <- function(..., true = NULL) {
dots <- eval(substitute(alist(...)), envir=parent.frame())
if(length(dots) %% 2 != 0) stop("Must have an even number of expressions")
for(condition in seq(1, length(dots), by = 2)){
if(eval(dots[[condition]],
envir = parent.frame())) return(eval(dots[[condition + 1]],
envir = parent.frame()))
}
true
}
x <- runif(1)
x
cond(x < 0.025, "lower tail",
x < 0.975, "middle",
true = "upper tail")
nums <- runif(100)
cbind(nums, sapply(nums,
function(x) cond(x < 0.27, "Group_1",
x < 0.33, "Group_2",
x < 0.36, "Group_3",
x < 0.42, "Group_4",
x < 0.44, "Group_5",
x < 0.58, "Group_6",
x < 0.85, "group_7",
true = "Group_8")))
@kcandrews
Copy link

How would I adapt this to work with vectors? I'd love to shelve ifelse.

@alandipert
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment