【发布时间】:2021-12-06 07:46:41
【问题描述】:
代码包含在两个文件中:
caller.R:
a <- 1
source("s1.R", encoding = "UTF-8")
b <- fa()
s1.R:
fa <- function() {
a*2
}
当caller.R 在 RStudio IDE 中作为源 (Crtl+Shift+S) 时,此代码运行顺利,提供正确的预期结果 b=2。
但是,当caller.R 通过“Source as Local Job...”获取源时,它会引发错误(葡萄牙语),这意味着执行被中断,因为它无法找到对象 'a':
Error in fa() : objeto 'a' n�o encontrado
Calls: sourceWithProgress -> eval -> eval -> fa
Execu��o interrompida
我已经尝试了所有可能的“源作为本地作业...”选项组合(“使用全局环境的副本运行作业等),但均未成功。
我必须做些什么才能将 caller.R 作为本地作业运行?
【问题讨论】:
-
根据您运行 Windows 的 Unicode 垃圾。请注意
source(…, encoding = 'utf-8')is broken on Windows!请改用eval(parse(…, encoding = 'utf-8'))。 -
而且,正如下面的答案所述,最好重写您的
s1.R,使其不再依赖外部状态。看看‘box’ modules ,了解一种稍微不同且(恕我直言,虽然我有偏见)非常优越的方法。 -
在 RStudio 中,““本地作业”是在单独的专用 R 会话中运行的 R 脚本” (ref)。一个 R 会话中的变量在另一个 R 会话中不可用;这不是 R 独有的,它是流程管理(以及安全性和封装等等)的工作方式。这是一个新进程,而不是一个新线程(它可能支持你想要的,尽管 R 和线程仍然不是很好)。我赞同 Konrad 的评论:编写你的函数,使其不会影响范围违规。
-
因此,我认为这是两件事:(1)不理解“作为本地作业的源”在一个全新的、未受污染的、未准备好的 R 会话中运行脚本,因此脚本文件需要初始化所需的一切(数据、包、函数等);这通过 (2)
function的反模式突出显示,它破坏了可重复性并且不遵守 函数式编程 基础。修复#2,症状消失;理解 #1 并内化 #2,你的编程就会变得更加健壮/有弹性:-) -
@r2evans 我认为您误解了错误描述:两个脚本都在 same R 进程中执行。是的,将脚本作为本地作业启动时有一个新流程;但该过程运行
caller.R,而后者又来自s1.R。都在同一个过程中。