Skip to content

Instantly share code, notes, and snippets.

@lionel-
Last active August 29, 2015 14:12
Show Gist options
  • Save lionel-/12350ba7e583e9c10163 to your computer and use it in GitHub Desktop.
Save lionel-/12350ba7e583e9c10163 to your computer and use it in GitHub Desktop.
Preserving version of lowliner's map()
remap <- function(.x, .f, ...) {
.f <- lowliner:::as_function(.f)
if (inherits(.f, "fseq")) {
# Handle magrittr's functional sequences
f_env <- environment(.f)
f_env$`_function_list` <- map(f_env$`_function_list`, ~ {
env <- new.env(parent = environment(.))
environment(.) <- env
.
})
envs <- map(f_env$`_function_list`, environment)
args <- rep_len(".", length(envs))
} else {
env <- new.env(parent = environment(.f))
environment(.f) <- env
envs <- list(env)
args <- names(formals(.f))[1]
}
# This active binding ensures that `..` contains the mapped
# argument. We look it up in the last frame so that we handle
# functions that evaluate code in special environments like
# lowliner::when()
map2(envs, args, function(env, arg) {
makeActiveBinding("..", function() {
arg <- get(arg, envir = sys.frame(-1))
env$`_dotdot`[[1]] <- arg
env$`_dotdot`
}, env)
})
out <- vector("list", length(.x))
for (i in seq_along(.x)) {
each(envs, function(env) {
env$`_dotdot` <- .x[i]
})
res <- .f(.x[[i]], ...)
stopifnot(is.list(.x) && is.vector(.x))
out[[i]] <- res
}
flatten(out)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment