with() 块中的返回函数

Chu*_*iao 5 r

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")
}
Run Code Online (Sandbox Code Playgroud)
  • 该函数在 之后继续运行return(1)
df <- data.frame(x = 11)
y <- 11
test_func(df, y)  ## result is 2
Run Code Online (Sandbox Code Playgroud)

输出

Inside step 1
After step 1
In side step 2
[1] 2
Run Code Online (Sandbox Code Playgroud)
  • return(1)不返回test_func()而不是离开with()
Inside step 1
After step 1
In side step 2
[1] 2
Run Code Online (Sandbox Code Playgroud)

输出

Inside step 1
After step 1
After step 2
Run Code Online (Sandbox Code Playgroud)

MrF*_*ick 3

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

return("hello")
# Error: no function to return from, jumping to top level
Run Code Online (Sandbox Code Playgroud)

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

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

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

f <- function(x) eval(substitute(x))
f(return("hello"))
# [1] "hello"
Run Code Online (Sandbox Code Playgroud)

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

with(NULL, return("hello"))
# [1] "hello"
Run Code Online (Sandbox Code Playgroud)

这与类似的东西不同

print(return("hello"))
# no function to return from, jumping to top level
Run Code Online (Sandbox Code Playgroud)

其中直接评估参数。因此,在这种情况下,“确实”的不同含义return()是非标准评估的副作用。

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

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