Skip to content

Instantly share code, notes, and snippets.

@mikmart
Last active July 20, 2018 08:49
Show Gist options
  • Save mikmart/b98e9d320d72eb582c438e55f695e71f to your computer and use it in GitHub Desktop.
Save mikmart/b98e9d320d72eb582c438e55f695e71f to your computer and use it in GitHub Desktop.
Substitute expression in the call stack
# Substitute a bare expression in all call stack envs
substitute_stack <- function(expr) {
  substitute_stack_q(substitute(expr))
}

# Substitute a quoted expression in all call stack envs
substitute_stack_q <- function(expr) {
  envs <- sys.frames() # call stack
  for (e in rev(envs)) {
    expr <- substitute_q(expr, e)
  }

  env <- as.list(globalenv())  # not in sys.frames()
  substitute_q(expr, env) # list so substitute works
}

# Substitute a quoted expression
substitute_q <- function(expr, env = parent.frame()) {
  eval(substitute(substitute(x, env), list(x = expr)))
}

f <- function() {
  v1 <- "a"
  substitute_stack({
    v1
    v2
    v3
    v4
  })
}

g <- function() {
  v2 <- "e"
  f()
}

h <- function() {
  v3 <- "f"
  g()
}

v2 <- "b"
v3 <- "c"
v4 <- "d"

f()
#> {
#>     "a"
#>     "b"
#>     "c"
#>     "d"
#> }

h()
#> {
#>     "a"
#>     "e"
#>     "f"
#>     "d"
#> }

Created on 2018-07-20 by the reprex package (v0.2.0.9000).

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