Skip to content

Instantly share code, notes, and snippets.

@gshotwell
Created October 26, 2019 13:44
Show Gist options
  • Save gshotwell/5b1c84e441e40675581c6d3e75ea0d0b to your computer and use it in GitHub Desktop.
Save gshotwell/5b1c84e441e40675581c6d3e75ea0d0b to your computer and use it in GitHub Desktop.
call <- substitute(ifelse(v == 1,
"banana",
ifelse(v == 2,
2,
NA))
)
parse_ifelse <- function(call) {
if (deparse(call[[3]][[1]]) == "ifelse") {
top_call <- deparse(call[[2]])
return(
paste0(top_call, " & ",
parse_ifelse(call[[3]]))
)
}
top_call <- paste0(deparse(call[[2]]), " ~ ", deparse(call[[3]]))
if (deparse(call[[4]][[1]]) == "ifelse") {
return(c(top_call,
parse_ifelse(call[[4]])))
}
return(paste0(deparse(call[[2]]), " ~ ", deparse(call[[3]])))
}
getTerminalCase <- function(call) {
if (deparse(call[[4]][[1]]) == "ifelse") {
return(getTerminalCase(call[[4]]))
} else {
return(paste0( "TRUE ~ ", deparse(call[[4]])))
}
}
makeCaseWhen <- function(call) {
cases <- c(
parse_ifelse(call),
getTerminalCase(call)
)
out <- c(
"dplyr::case_when(",
paste0(cases, collapse = ",\n"),
")"
)
paste0(out, collapse = "\n")
}
cat(makeCaseWhen(call))
@paleolimbot
Copy link

paleolimbot commented Oct 26, 2019

This was a great Saturday morning coffee challenge! No judgement, just having fun with rlang:

library(rlang)

cases <- function(x) {
  if (is_call(x, "ifelse")) {
    test <- x[[2]]
    if_true <- x[[3]]
    if_false <- x[[4]]
    
    c(
      call2("~", test, if_true),
      cases(if_false)
    )
  } else {
    list(call2("~", TRUE, x))
  }
}

x <- expr(ifelse(a == 12, "twelve", ifelse(a == 13, "thirteen", "not twelve or 13")))
call2("case_when", !!!cases(x))
#> case_when(a == 12 ~ "twelve", a == 13 ~ "thirteen", TRUE ~ "not twelve or 13")

Created on 2019-10-26 by the reprex package (v0.2.1)

@gshotwell
Copy link
Author

gshotwell commented Oct 26, 2019 via email

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