【问题标题】:Function using an object created by a higher level function使用由更高级别函数创建的对象的函数
【发布时间】:2013-03-21 15:58:32
【问题描述】:

我有两个功能,一个内另一个

fun.a <- function (y,smth) { 
    z <- y*3
    sapply(smth,FUN = fun.b) 
}
fun.b <- function(x) {
    return(x+z)
}

如果我跑:

fun.a(2, c(1, 2, 3))

我收到一条错误消息,因为“较低级别”函数 fun.b 中不存在 z。但是在fun.a 中使用sapply 时,我无法传递值z

也许它存在一个允许在函数内部创建一个也存在于外部的对象的函数?如何解决这个问题?

编辑:我不想在fun.a 中复制粘贴fun.b,也不想用for-loop 替换sapply。在这种情况下,解决方案仍然存在吗?

【问题讨论】:

  • zfun.a 的范围内。您必须使用两个参数x and y 定义fun.b。或者在fun.a 中声明fun.b
  • @阿伦。声明 fun.b 在 fun.a 中?我该怎么做?
  • @Arun Aahh 你的意思是在函数 fun.a 中创建函数 fun.b。如果我这样做会起作用吗?因为我不能将两个元素从 fun.a 传递给 fun.b 因为我想使用 sapply 函数
  • 我的意思是剪切fun.b并粘贴到z &lt;- y * 3之后。
  • @Arun 是的,它通过在 fun.a 中创建 fun.b 来工作。但我不得不说,出于实际原因,这对我来说不是一个很好的解决方案。有没有办法告诉我们在函数中创建的对象直接存在于该函数之外或我们从该当前函数调用的任何函数中(不确定我是否清楚!!)?

标签: r function object


【解决方案1】:

这可行,您可以使用 ... 参数将任何附加值传递给 fun.b

fun.a <- function (y,smth) { 
    z <- y*3
    sapply(smth,FUN = fun.b, z = z) 
}
fun.b <- function(x, z) {
    return(x+z)
}
fun.a(2, c(1, 2, 3))

【讨论】:

    【解决方案2】:

    如果不允许修改fun.b(我从 cmets 收集的),那么在fun.a 的主体内,创建fun.b 的副本并为其附加环境:

    fun.a <- function (y,smth) { 
      e <- new.env()
      assign("z", y*3, envir = e)
      fun.b.copy <- fun.b
      environment(fun.b.copy) <- e
      sapply(smth,FUN = fun.b.copy)
    }
    

    如果您可以修改函数获取输入的方式,我仍然更喜欢@Paul 的解决方案。他的回答是推荐的编程方式。

    【讨论】:

    • 如果您不想将对象复制到fun.b,我可以想象这可以正常工作,例如因为对象很大。但可能在大多数情况下,代码可读性的下降是不值得的。此外,在这种情况下,引用类不是一个好主意吗?你可以只传递参考类,使函数的输入很明显,但仍然不能复制对象。
    • @Paul,当您将对象传递给函数时,您不会复制它。只要对象未被修改,R 就会在内部使用引用。所以即使z 很大,我仍然会推荐你的方法。这里我只是回答一个技术难题,假设fun.b 不能被修改并且不能被复制粘贴到fun.a 的正文中。否则我完全同意这不是推荐的编程风格。
    • 有趣的是,我不知道对于未更改的对象,R 不会复制该对象而是仍然指向相同的内存位置。有什么参考吗?
    • 我没有参考资料,但您可以使用tracemem:{z &lt;- 1; print(tracemem(z)); incr &lt;- function(z) {print(tracemem(z)); z &lt;- z+1; print(tracemem(z)); z}; y &lt;- incr(z); print(tracemem(y))} 进行检查。这甚至显示了分配时未复制函数的输出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    相关资源
    最近更新 更多