首页 > 解决方案 > with() 块内的返回函数

问题描述

return()块中如何with()工作?这是一个测试功能

test_func <- function(df, y) {
  with(df,
       if(x > 10){
         message('Inside step 1')
         return(1)
       }
  )
  message("After step 1")

  if(y > 10){
    message('In side step 2')
    return(2)
  }  
  message("After step 2")
}
df <- data.frame(x = 11)
y <- 11
test_func(df, y)  ## result is 2

输出

Inside step 1
After step 1
In side step 2
[1] 2
df <- data.frame(x = 11)
y <- 5
test_func(df, y) ## no result

输出

Inside step 1
After step 1
After step 2

标签: r

解决方案


我认为这里的重点return()是旨在将当前范围退出到具有特定值的父范围。在跑步的情况下

return("hello")
# Error: no function to return from, jumping to top level

你会得到一个错误,因为我们是从全局环境中调用它并且没有你要跳回的父范围。请注意,由于 R 的惰性求值,传递给函数的参数通常在传递它们的环境中求值。所以在这个例子中

f <- function(x) x
f(return("hello"))
# Error in f(return("hello")) : 
#   no function to return from, jumping to top level

因此,因为我们实际上是return()从全局环境中传入对函数的调用,所以返回值将被评估并返回相同的错误。但请注意,这不是做什么with,而是捕获您传递的命令并在新环境中重新运行它们。它更接近这样的东西

f <- function(x) eval(substitute(x))
f(return("hello"))
# [1] "hello"

eval()创造了一个新的范围,我们可以逃脱,因为我们没有直接评估传递给函数的参数,我们只是在不同的环境中运行这些命令,return不再在全局环境中评估,所以没有错误。所以我们创建的函数和调用基本一样

with(NULL, return("hello"))
# [1] "hello"

这与类似的东西不同

print(return("hello"))
# no function to return from, jumping to top level

其中参数是直接评估的。所以return()在这种情况下,真正的不同含义是非标准评估的副作用。

return()在 a 中使用时with(),您不会从您调用的函数返回with(),而是从为您创建的范围返回with()以运行您的命令。

@IceCreamToucan 留下的评论已经解决了如何解决这个特定问题。您只需要将返回移动到with().


推荐阅读