拥有以下内容的Rmd文件:
```{r}
data.frame(a=1)
str(.Last.value)
```
它呈现data.frame但呈现str(.Last.value)
会产生## NULL
是否有任何针织选项或技巧可以使其按预期工作?
第二次预期输出
## 'data.frame': 1 obs. of 1 variable:
## $ a: num 1
答案 0 :(得分:5)
因为所有代码块都是通过 knitr 中的eval()
进行评估的,所以代码块的最后一个表达式不是顶级 R表达式,{ {1}}不适用于 knitr 。
为了更清楚地说明这一点:
.Last.value
相比之下,x = 1
x # a top-level expression if typed in the R console
不再是x
中的顶级表达式:
eval()
答案 1 :(得分:4)
实际上,有一种方法可以使.Last.value
起作用。
```{r setup, include=FALSE}
knitr::opts_chunk$set(render = function(x, ...){
unlockBinding(".Last.value", .BaseNamespaceEnv)
assign(".Last.value", x, .BaseNamespaceEnv)
lockBinding(".Last.value", .BaseNamespaceEnv)
knitr::knit_print(x, ...)
})
```
这段代码定义了一个自定义渲染函数,它将输出绑定到.Last.value
。
虽然,上述修复并不完美。该行为与控制台略有不同。例如,在R控制台
中> x <- 2
> .Last.value
[1] 2
即使上一个命令不可见,.Last.value也会返回最后一个值。另一方面,knitr
的上述hack要求打印结果。
```{r}
x <- 2
x
.Last.value
```
更新
要完全使.Last.value
像在R控制台中一样工作,您可以考虑以下高风险黑客,它会覆盖knitr
内部函数。
```{r setup, include=FALSE}
unlockBinding("knit_handlers", getNamespace("knitr"))
evalq(
assign(
"knit_handlers",
function(fun, options) {
if (!is.function(fun)) fun = knit_print
if (length(formals(fun)) < 2)
stop("the chunk option 'render' must be a function of the form ",
"function(x, options) or function(x, ...)")
merge_list(default_handlers, list(value = function(x, visible) {
unlockBinding(".Last.value", .BaseNamespaceEnv)
assign(".Last.value", x, .BaseNamespaceEnv)
lockBinding(".Last.value", .BaseNamespaceEnv)
if (visible) fun(x, options = options)
}))
}
),
getNamespace("knitr")
)
lockBinding("knit_handlers", getNamespace("knitr"))
```
这会覆盖knitr
内部函数knit_handlers
,因此可以随时中断。