【问题标题】:R: Scoping error when calling function from scriptR:从脚本调用函数时范围错误
【发布时间】:2021-03-09 15:51:10
【问题描述】:

我正在 R 中构建一个大型代码库,该代码库通过许多嵌套的用户定义函数使用矢量化。这些辅助功能大体上是用它们自己的 R 脚本编写的,用于调试和维护目的。我想在特定环境中获取其中一些脚本,而不将这些函数调用到全局环境中。

我正在努力使 main.R 文件尽可能干净和易于理解,以便有脚本在幕后完成肮脏的工作

在下面的示例中,全局环境将填充有f_foobar(这是正确的),但一旦我调用函数f_foobar,也会填充f_foof_bar

有没有一种优雅的方式在临时环境中容纳这些辅助功能(例如f_foof_bar)?

例如在file_foo.R中:

f_foo <- function() {
  return('a')
}

在file_bar.R中:

f_bar <- function() {
  return('b')
}

在 file_foobar.R 中:

f_foobar <- function() {
  source('file_foo.R')
  source('file_bar.R')
  
  value_foo <- f_foo()
  value_bar <- f_bar()
  
  c(value_foo, value_bar) %>% return
}

在 main.R 中:

source('file_foobar.R')

main_result <-f_foobar()

【问题讨论】:

  • "有没有优雅的方法..." 是的,创建一个包。
  • +1 为包裹。但我建议你阅读?source,特别是:local: ... 'FALSE' (the default) corresponds to the user's workspace (the global environment) and 'TRUE' to the environment from which 'source' is called. 使用source("file_foo.R", local=TRUE),你的范围应该被解决。 (但真的……package。)

标签: r function environment scoping


【解决方案1】:

底线:使用source(..., local=TRUE)。来自?source

   local: 'TRUE', 'FALSE' or an environment, determining where the
          parsed expressions are evaluated.  'FALSE' (the default)
          corresponds to the user's workspace (the global environment)
          and 'TRUE' to the environment from which 'source' is called.

之前

ls()
# character(0)
source('file_foobar.R')
main_result <- f_foobar()
main_result
# [1] "a" "b"
ls()
# [1] "f_bar"       "f_foo"       "f_foobar"    "main_result"

之后

ls()
# character(0)
source('file_foobar.R')
main_result <- f_foobar()
main_result
# [1] "a" "b"
ls()
# [1] "f_foobar"    "main_result"

(但实际上,当您谈论 “在特定环境中” 时,这确实与使用 R 包有关。这样做有很多好处,即使您从来没有打算推送到 CRAN。我在工作中维护了大约两打包,而不是 CRAN,虽然我可能能够在不成为包的情况下单独确定它们的范围,但当您考虑使用来自的一个项目时另一个,它变得不必要的复杂。包几乎总是能解决这个问题。)

【讨论】:

    猜你喜欢
    • 2021-05-26
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多