r - 在函数内访问函数中的变量

标签 r function parameter-passing

在 R 中运行一个函数时,我在其中运行另一个函数。 我有这样的代码:

f_a <- function(b, c){
    return(b + c)
}

f_e <- function(){
    b = 2
    c = 2 
    d = f_a(b, c)
    print(d)
}

这很好用。我想要做的是不将变量 b, c 传递给函数f_a。我想做这样的事情(这会引发错误)

f_a <- function(){
    return(b + c)
}

f_e <- function(){
    b = 2
    c = 2
    d = f_a()
    print(d)
}

有没有办法使用环境或搜索路径或任何其他方式来做到这一点?

最佳答案

我鼓励您阅读 lexical scoping , 但我认为避免编写大量变量的一个好方法可能是:

get_args_for <- function(fun, env = parent.frame(), inherits = FALSE, ..., dots) {
    potential <- names(formals(fun))

    if ("..." %in% potential) {
        if (missing(dots)) {
            # return everything from parent frame
            return(as.list(env))
        }
        else if (!is.list(dots)) {
            stop("If provided, 'dots' should be a list.")
        }

        potential <- setdiff(potential, "...")
    }

    # get all formal arguments that can be found in parent frame
    args <- mget(potential, env, ..., ifnotfound = list(NULL), inherits = inherits)
    # remove not found
    args <- args[sapply(args, Negate(is.null))]
    # return found args and dots
    c(args, dots)
}

f_a <- function(b, c = 0, ..., d = 1) {
    b <- b + 1
    c(b = b, c = c, d = d, ...)
}

f_e <- function() {
    b <- 2
    c <- 2
    arg_list <- get_args_for(f_a, dots = list(5))
    do.call(f_a, arg_list)
}

> f_e()
b c d   
3 2 1 5 

默认设置inherits = FALSE可确保我们仅从指定环境获取变量。 我们还可以在调用 get_args_for 时设置dots = NULL,这样我们就不会传递所有变量, 但将省略号留空。

尽管如此,它并不完全可靠, 因为 dots 只是简单地附加在末尾, 如果某些参数没有被命名, 他们最终可能会按职位匹配。 另外,如果调用中某些值应为 NULL, 检测它并不容易。

<小时/>

I would strongly advise against using these below inside an R package. Not only will it be rather ugly, you'll get a bunch of notes from R's CMD check regarding undefined global variables.

其他选项。

f_a <- function() {
    return(b + c)
}

f_e <- function() {
    b <- 2
    c <- 2
    # replace f_a's enclosing environment with the current evaluation's environment
    environment(f_a) <- environment()
    d <- f_a()
    d
}

> f_e()
[1] 4

像上面这样的东西可能在 R 包中不起作用, 因为我认为包的函数已锁定其封闭环境。

或者:

f_a <- function() {
    with(parent.frame(), {
        b + c
    })
}

f_e <- function() {
    b <- 2
    c <- 2
    f_a()
}

> f_e()
[1] 4

这样您就不会永久修改其他函数的封闭环境。 然而,这两个功能将共享一个环境, 所以可能会发生这样的事情:

f_a <- function() {
    with(parent.frame(), {
        b <- b + 1
        b + c
    })
}

f_e <- function() {
    b <- 2
    c <- 2
    d <- f_a()
    c(b,d)
}

> f_e()
[1] 3 5

调用内部函数会修改外部环境中的值。

还有一个更灵活的选择, 因为它只是通过使用 eval 临时修改封闭环境。 然而,有一些R函数可以通过“daRk magic”来检测它们当前的执行环境, 并且不会被eval愚弄; 请参阅this discussion .

f_a <- function() {
    b <- b + 1
    b + c
}

f_e <- function() {
    b <- 2
    c <- 2
    # use current environment as enclosing environment for f_a's evaluation
    d <- eval(body(f_a), list(), enclos=environment())
    c(b=b, d=d)
}

> f_e()
b d 
2 5 

关于r - 在函数内访问函数中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51002811/

相关文章:

php - 在 HTML/PHP 中传递变量的推荐方法?

r - 模型使用 glm 但不是 bigglm

r - ggplot2:每层单独的图例

c++ - 具有可变参数模板的函数对象

python将参数传递给函数

jsp include,转发请求参数

regex - 不区分大小写地匹配正则表达式,用特定的大小写替换

r - 不要转义 Rmarkdown 文件中的特殊字符

在 C 中调用以字符串变量命名的函数

javascript - 使用 javascript 更改 onClick 属性