【问题标题】:R - Define a object in a function which is inside another functionR - 在另一个函数内的函数中定义一个对象
【发布时间】:2018-07-04 23:38:19
【问题描述】:

我在另一个函数中有一个这样的函数:

func2 <- function(x=1) {ko+x+1}
func3= function(l=1){
  ko=2
  func2(2)+l
}
func3(1)

它显示错误:Error in func2(2) : object 'ko' not found。基本上我想在func2 中使用对象ko,在调用func3 之前不会定义它。有什么解决办法吗?

【问题讨论】:

  • 您必须在您的function 中使用ko 作为参数。此外,您必须通过您的func2 发送return 的内容。比如:return(ko+x+1).
  • @patL 你不需要明确的return()(许多风格指南都建议不要这样做)。 R 函数将始终返回最后一个表达式的值。
  • 谢谢@MrFlick。你是对的!

标签: r function parameter-passing


【解决方案1】:

这是学习闭包和使用工厂的好案例。

func3_factory <- function (y) {
  ko <- y
  func2 <- function (x = 1) { ko + x + 1 }
  function (l = 1) { func2(2) + l }
}
ko <- 1
func3_ko_1 <- func3_factory(ko)
ko <- 7
func3_ko_7 <- func3_factory(ko)
# each function stores its own value for ko
func3_ko_1(1) # 5
func3_ko_7(1) # 11
# changing ko in the global scope doesn't affect the internal ko values in the closures
ko <- 100
func3_ko_1(1) # 5
func3_ko_7(1) # 11

func3_factory 返回一个函数时,该新函数与创建它的环境相结合,在这种情况下,它包括一个名为ko 的变量,它保留传递给工厂的任何值和一个名为@ 的函数987654324@ 也可以访问ko 的固定值。函数和定义它的环境的这种组合称为闭包。返回的函数内部发生的任何事情都可以访问这些值,并且即使在闭包之外更改了 ko 变量,它们也保持不变。

【讨论】:

    【解决方案2】:

    您目前并没有真正在另一个“内部”拥有一个函数(您只是在另一个函数中调用一个函数)。如果您确实将一个函数移动到另一个函数中,那么这将起作用

    func3 <- function(l=1) {
      func2 <- function(x=1) {ko+x+1}
      ko <- 2
      func2(2)+l
    }
    func3(1)
    

    函数保留有关定义它们的环境的信息。这称为“词法作用域”,这就是 R 的运作方式。

    但总的来说,我同意@Roland 的观点,即最好编写具有显式参数的函数。

    【讨论】:

      【解决方案3】:

      是的,可以修复:

      func2 <- function(x=1) {ko+x+1}
      func3= function(l=1){
        ko=2
        assign("ko", ko, environment(func2))
        res <- func2(2)+l
        rm("ko", envir = environment(func2))
        res
      }
      func3(1)
      #[1] 6
      

      如您所见,这非常复杂。这通常表明您没有遵循良好的做法。好的做法是将ko 作为参数传递:

      func2 <- function(x=1, ko) {ko+x+1}
      func3= function(l=1){
        ko=2
        func2(2, ko)+l
      }
      func3(1)
      #[1] 6
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-30
        • 2018-02-25
        • 1970-01-01
        • 2014-07-14
        • 1970-01-01
        • 2013-02-09
        相关资源
        最近更新 更多