【问题标题】:Force evaluation with deparse in R在 R 中使用 deparse 进行强制评估
【发布时间】:2020-09-27 09:32:58
【问题描述】:

我有一个产生函数的函数:

fun1 <- function (x)
    return (function() x)

到一个函数产生的时候,x的值已经基本是一个常数了:

fun2 <- fun1 ("a")

但是,当我打印fun2 时,它不会显示实际值,它只显示"x",即使它现在已经过时了:

> fun2
function() x
<environment: 0x55a9f94f9fc8>

如何强制评估x 以便fun2 打印为

function() "a"

或者它是怎么产生的?

【问题讨论】:

    标签: r lazy-evaluation first-class-functions


    【解决方案1】:

    这里无需求助deparse。您可以将 x 的评估值写入新创建的函数的主体中:

    fun1 <- function (x){
      f <- function() x
      body(f) <- x
      f
    }
    

    这样:

    fun1("a")
    #> function () 
    #> "a"
    #> <environment: 0x00000146d0449dd8>
    

    和

    f <- fun1("a")
    f()
    #> [1] "a"
    

    编辑

    如果你想让f 提出论点,你可以这样做:

    fun1 <- function (x){
      f <- function(y) y + x
      body(f)[[3]] <- x
      f
    }
    

    这样

    fun1(3)
    #> function (y) 
    #> y + 3
    #> <environment: 0x00000146d4b702a0>
    

    【讨论】:

    • 谢谢,但我的最小示例似乎太小了。我希望f 接受一个论点,并且我希望能够在f 的正文中使用该论点。我只能通过将f 的主体封装在expression 中来做到这一点,但随后我又回到了第一方。假设我希望 f 成为 function(y) y+x,然后将 fun1(1) 打印为 function(y) y+1。
    • 太好了,非常感谢!如果你很迂腐,y 在 f 的声明中会出现在 fun1 中。
    • @KamilS。我我很迂腐。现在修好了。谢谢!
    【解决方案2】:

    这将替换fun 正文中的所有x 实例。在示例中,fun1 有一个参数,但它将继续与 fun 中使用的多个 fun1 参数一起使用,将它们全部替换为 fun。我们还将fun 的环境设置为fun1 的调用者中的环境,允许调用者在需要时通过指定envir 来更改它。

    fun1 <- function (x, envir = parent.frame()) {
        fun <- function() x
        body(fun) <- do.call("substitute", list(body(fun)))
        environment(fun) <- envir
        fun
    }
    
    fun2 <- fun1("a")
    fun2
    ## function () 
    ## "a"
    
    environment(fun2)
    ## <environment: R_GlobalEnv>
    

    【讨论】:

    • 谢谢。这本来会更有用,因为它更通用,但是当我在fun 中使用tmp[1] 之类的东西时,这会将整个tmp 放入fun 并在最后添加[1]。但是不要麻烦自己,我只有两个元素要替换,所以像艾伦的解决方案一样,手动一个一个地做是没有问题的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多