似乎knitr
无法理解DT[, a:=1]
不应导致文档的DT
输出。有没有办法阻止这种行为?
knitr
文档:Data.Table Markdown
========================================================
Suppose we make a `data.table` in **R Markdown**
```{r}
DT = data.table(a = rnorm(10))
```
Notice that it doesn't display the contents until we do a
```{r}
DT
```
style command. However, if we want to use `:=` to create another column
```{r}
DT[, c:=5]
```
It would appear that the absence of a equals sign tricks `knitr` into thinking this
is to be printed.
这是knitr
错误还是data.table
错误?
修改
我刚刚注意到,knitr
在echo
代码时很奇怪。看看上面的输出。在我的源代码中,我有DT[, c:=5]
,但knitr
呈现的是
DT[, `:=`(c, 5)]
...怪异
编辑2:缓存
缓存似乎也存在:=
的问题,但这必须是一个不同的原因,因此这里有一个单独的问题:why does knitr caching fail for data.table `:=`?
答案 0 :(得分:19)
2014年10月更新。现在在data.table v1.9.5:
:=
不再在knitr
中打印,以便与提示时的行为#505保持一致。测试knit("knitr.Rmd")
的输出现在在data.table的单元测试中。
及相关:
if (TRUE) DT[,LHS:=RHS]
现在不打印(感谢Jureiss,#869)。测试补充。为了实现这一点,我们不得不忍受一个缺点:如果在函数结束之前在函数内部使用:=
而没有DT[]
,那么下一次DT
在提示符下键入,不会打印任何内容。将打印重复的DT
。为避免这种情况:请在函数中的最后DT[]
后添加:=
。如果这不可能(例如,它不是您可以更改的功能),则保证在提示时打印print(DT)
和DT[]
。和以前一样,在[]
查询的末尾添加额外的:=
是建议的更新然后打印的习惯用法;例如> DT[,foo:=3L][]
为子孙后代保留了以前的答案(global$depthtrigger
业务不再从data.table v1.9.5完成,所以这不再是真的了......)
为了清楚起见,我明白了:knitr
正在打印,当你不想要它时。
尝试在脚本开头稍微增加data.table:::.global$depthtrigger
。
目前这将是3:
data.table:::.global$depthtrigger
[1] 3
我不知道eval深度knitr
增加了多少。但是首先尝试将触发器更改为4;即。
assign("depthtrigger", 4, data.table:::.global)
并在knitr
脚本的末尾确保将其设置为3.如果4不起作用,请尝试5,然后6.如果你到10放弃,我会再次思考。 ;-P
为什么这可行?
请参阅v1.8.4中的新闻:
DT[,LHS:=RHS,...]
不再打印DT
。这实现了#2128“尝试 再次让DT[i,j:=value]
无形地返回“。感谢此处的讨论:
how to suppress output when using `:=` in R {data.table}, prior to v1.8.3?
http://r.789695.n4.nabble.com/Avoiding-print-when-using-tp4643076.html
常见问题解答2.21和2.22已更新。FAQ 2.21为什么DT [i,col:= value]返回整个DT?我预计要么没有可见值(与&lt ;-)一致,要么是消息或返回 包含更新行数的值。这并不明显 数据确实已经通过引用进行了更新。
这在v1.8.3中有所改变 满足你的期望。请升级。返回整个DT (现在看不见了)这样复合句法可以起作用;例如。, DT [I,完成:= TRUE] [,总和(完成)]。返回更新的行数 当详细程度打开时,基于每个查询或全局使用 选项(datatable.verbose = TRUE)。常见问题2.22好的,谢谢。 DT [i,col:= value]的结果难以置信地返回了什么?
R内部力量 能见度为[。 FunTab的eval列的值(参见 src / main / names.c)for [is 0表示强制R_Visible on(参见 R-Internals第1.6节)。因此,当我们尝试invisible()或 直接将R_Visible设置为0,在src / main / eval.c中设置为eval 会再强迫它。要解决这个问题,关键是要停下来 试图在:=后停止运行打印方法。相反,里面:= 我们现在(从v1.8.3开始)设置打印方法使用的全局标志 知道是否实际打印。
该全球旗帜为data.table:::.global$print
。在data.table:::print.data.table
的顶部,您会看到它正在查看它。那是因为没有已知的方法可以抑制[
的打印(正如FAQ 2.22所解释的那样)。
因此,在:=
内的[.data.table
内部,它会看到此次调用的“深度”:
if (Cstack_info()[["eval_depth"]] <= .global$depthtrigger) {
suppPrint = function(x) { .global$print=FALSE; x }
# Suppress print when returns ok not on error, bug #2376.
# Thanks to: https://stackoverflow.com/a/13606880/403310
# All appropriate returns following this point are
# wrapped i.e. return(suppPrint(x)).
}
基本只是说:如果DT[,x:=y]
在提示符处运行,那么我知道REPL将在我的结果上调用print
方法,超出我的控制范围。好的,所以给定print
方法将要运行,我将通过设置一个标志(因为print
方法运行(即{{1})来在print
方法中禁止它我可以控制的东西。)
在print.data.table
的情况下,它以聪明的方式模拟REPL。这不是一个真正的脚本,iiuc,否则knitr
无论如何都不会打印出来。但是因为它通过DT[,x:=y]
模拟REPL,所以从eval
运行的代码有一个额外的eval
深度级别。或类似的东西(我不知道knitr
)。
这就是为什么我认为增加knitr
可能会成功。
Hacky / crufty,我同意。但如果它有效,并且您让我知道哪个值有效,我可以将depthtrigger
更改为data.table
,并自动更改knitr
。或者,欢迎任何更好的解决方案。
答案 1 :(得分:7)
为什么不使用:
```{r, results='hide'}
DT[, c:=5]
```
答案 2 :(得分:5)
对于2017年使用RMarkdown 1.3和data.table 1.10或类似内容返回此处的人,有一个resurgence of this bug, as identified and documented here
随后在RMarkdown 1.4中修复了
答案 3 :(得分:2)
用invisible()包围表达式。这对我有用。
答案 4 :(得分:1)
我遇到了同样的问题,通过重新分配变量我很容易解决了。在你的情况下:
DT <- DT[, ':=' (c, 5)]
虽然它有点冗长,特别是如果变量名称很大。