如何从全局环境中创建的 R 中的单独函数访问变量

问题描述 投票:0回答:2

如何才能在

x
中使用
f2()

f1 <- function(){
  
  x <- 5
  f2()  
}

f2 <- function(){

  x
}

f1()
#> Error in f2() : object 'x' not found
r rlang
2个回答
0
投票

正如评论中提到的,通常通过参数将对象从一个函数传递到另一个函数,但如果由于某种原因在这种情况下不希望这样做,那么这里有一些选项。

1) 在 f1 中定义 f2。

f1 <- function(){
  f2 <- function() x
  x <- 5
  f2()  
}
f1()
## [1] 5

2) 或者创建 f2 的本地副本并将其环境重置为 f1 的执行环境。下面的 f1 的第一行同时执行这两项操作。这会修改 f1 的源,但不会修改 f2

f2 <- function() x
f1 <- function() {
  environment(f2) <- environment()
  x <- 5
  f2()
}
f1()
## [1] 5

3)宏 将f2变成宏。这会修改 f2 的源,但不会修改 f1。从概念上讲,当 f2 运行时,将 f2 的主体注入到 f1 中。

f2 <- function() eval.parent(substitute({
   x
})
f1 <- function() {
  x <- 5
  f2()
}
f1()
## [1] 5

4) defmacro gtools 包中有 defmacro,它基本上与 (3) 做同样的事情。

library(gtools)

f2 <- defmacro(junk, expr = {  # need at least one arg for ...
  x
})

f1 <- function() {
  x <- 5
  f2()
}
f1()
## [1] 5

0
投票

这个问题的一般答案是:

通过将

x
传递到
f2()
:

f1 <- function () {
  x <- 5
  f2(x)  
}

f2 <- function (x) {
  x
}

f1()
# [1] 5

参数传递是编程中非常常见的模式,当您需要在函数内提供值时,99% 的情况下,参数传递都是正确的答案。 不要试图避免仅仅“为了方便”而将参数传递给函数。

在一些非常具体的场景中,R 的非标准评估功能(在另一个答案中展示)是合适的解决方案。但“为了方便”并不是一个有效的理由,因为它使代码更难理解、重用和错误检查。

© www.soinside.com 2019 - 2024. All rights reserved.