你的前两个例子失败的原因不同。要理解这两种失败,首先需要了解代码块是如何由
R标记
.
knitr的通用代码块评估过程
当你打电话的时候
rmarkdown::render()
在您的文件中,每个代码块最终都通过调用
evaluate::evaluate()
evaluate()
其行为几乎与基R函数完全相同
eval()
(其中
evaluate::evaluate()
最不同于
评估()
它如何处理每个计算表达式的输出。如中所述
?evaluate
针织衫
!)
无论如何,最终
评估()
knitr:::block_exec()
,看起来像这样
evaluate::evaluate(code, envir = env, ...)
在你的第一个例子中,
环境
是一个列表,而不是一个环境。在这种情况下,将在函数调用创建的本地环境中执行求值。未解析符号(如两个
?eval
和
)都是在名单上找第一个通过的
环境
然后在由
enclos
因为
评估()
每次对表达式的字符向量操作一个,当
环境
是一个列表,在其中一个表达式中创建的变量将无法在后续表达式中使用。
当
环境
论据
是一个列表,您的代码块最终通过如下调用进行计算:
library(evaluate)
code <- c('x <- "don\'t you ignore me!"',
'print(x)')
env <- list(y = 1:10)
evaluate(code, envir = env)
replay(evaluate(code, envir = env))
:
env <- list(y =1 :10)
eval(quote(x <- "don't you ignore me"), envir = env)
eval(quote(x), envir = env)
envir=
是由返回的环境
as.environment(list())
,则会因不同的原因出现错误。在这种情况下,您的代码块最终会通过如下调用进行计算:
library(evaluate)
code <- c('x <- "don\'t you ignore me!"',
'print(x)')
env <- as.environment(list(y = 1:10))
evaluate(code, envir = env)
replay(evaluate(code, envir = env))
as.environment()
返回其封闭环境为空环境的环境(即
emptyenv()
).
评估()
(就像
评估()
会)寻找符号
<-
在里面
环境
当它在那里找不到它时,就会启动封闭环境链,这里不包含任何匹配项(还记得什么时候
是一个环境,而不是一个列表
参数未使用。)
推荐解决方案
要想做你想做的事,你需要创建一个环境:(1)包含你列表中的所有对象,以及(2) 将调用的父环境作为其封闭环境
render()
(即调用
渲染()
通常进行评估)。最简洁的方法就是使用俏皮的
list2env()
env <- list2env(list(y="hello"), parent.frame())
render('test.Rmd', output_format = "html_document",
output_file = 'test.html',
envir = env)
这样做将导致您的代码块由如下代码进行评估,这是您想要的:
library(evaluate)
code <- c('x <- "don\'t you ignore me!"',
'print(x)')
env <- list2env(list(y = 1:10), envir = parent.frame())
evaluate(code, envir = env)
replay(evaluate(code, envir = env))