knitr被data.table`:=`赋值

Cor*_*one 39 r knitr data.table

似乎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.
Run Code Online (Sandbox Code Playgroud)

针织输出:

在此输入图像描述

这是一个knitrbug还是一个data.tablebug?

编辑

我刚才注意到,在编写代码knitr时这很奇怪echo.看看上面的输出.在我的源代码中我有,DT[, c:=5]knitr呈现的是什么

DT[, `:=`(c, 5)]
Run Code Online (Sandbox Code Playgroud)

奇怪的...

编辑2:缓存

缓存似乎也有问题,:=但这必然是一个不同的原因,所以这里有一个单独的问题:为什么knitr缓存失败的data.table`:=`?

Mat*_*wle 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
Run Code Online (Sandbox Code Playgroud)

我不知道eval深度knitr增加了多少堆栈.但是首先尝试将触发器更改为4; 即

assign("depthtrigger", 4, data.table:::.global)
Run Code Online (Sandbox Code Playgroud)

并且在knitr脚本结束时确保将其设置为3.如果4不起作用,请尝试5,然后6.如果你到10放弃,我会再次思考.;-P

为什么这可行?

请参阅v1.8.4中的新闻:

DT[,LHS:=RHS,...]不再打印DT.这实现了#2128"再次尝试DT[i,j:=value]无形地返回".感谢这里的讨论:
如何在v1.8.3之前的R {data.table}中使用`:=`时抑制输出?
http://r.789695.n4.nabble.com/Avoiding-print-when-using-tp4643076.html
常见问题解答2.21和2.22已更新.

FAQ 2.21为什么DT [i,col:= value]返回整个DT?我希望没有可见值(与< - 一致),或者包含更新行数的消息或返回值.数据确实已通过参考更新并不明显.
这在v1.8.3中发生了变化,以满足您的期望.请升级.返回整个DT(现在是不可见的),以便复合语法可以工作; 例如,DT [i,done:= TRUE] [,sum(done)].更新的行数是在详细程度打开时返回的,可以是基于每个查询,也可以是全局使用选项(datatable.verbose = TRUE).

FAQ 2.22好的,谢谢.DT [i,col:= value]的结果难以置信地返回了什么?
R内部强制[.FunTab的eval列(参见src/main/names.c)的值为[0表示强制R_Visible开启(参见R-Internals第1.6节).因此,当我们尝试invisible()或直接将R_Visible设置为0时,src/main/eval.c中的eval将再次强制它.要解决这个问题,关键是在:=后停止尝试停止运行打印方法.相反,在里面:=我们现在(从v1.8.3开始)设置一个全局标志,print方法用它来知道是否实际打印.

那个全球旗帜是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)).
}
Run Code Online (Sandbox Code Playgroud)

必要的只是说:如果DT[,x:=y]在提示符下运行,那么我知道REPL会print在我的结果上调用方法,超出我的控制范围.好的,所以给定的print方法将要运行,我将print通过设置一个标志来抑制它在该方法内(因为print运行的方法(即print.data.table)是我可以控制的).

knitr这种情况下,它以聪明的方式模拟REPL.这不是一个真正的脚本,iiuc,否则DT[,x:=y]不会因此而打印.但是因为它通过一个模拟REPL来实现代码运行eval的额外eval深度knitr.或类似的东西(我不知道knitr).

这就是为什么我在想增加depthtrigger可能性的伎俩.

Hacky/crufty,我同意.但如果它有效,并且你让我知道哪个值有效,我可以改变data.tableknitr了解并depthtrigger自动更改.或者欢迎任何更好的解决方案.

  • @Spacedman有时你要打破一些鸡蛋做一个煎蛋,即使有一些贝壳掉进去了. (8认同)
  • v1.9.5中引入的更新似乎不再适用于v1.9.6(或截至今天的1.9.7).knitr仍然打印data.table后:=赋值. (4认同)

Mat*_*ock 7

为什么不使用:

```{r, results='hide'}
DT[, c:=5]
```
Run Code Online (Sandbox Code Playgroud)


Dav*_*RGP 5

对于2017年使用RMarkdown 1.3和data.table 1.10或类似版本返回此处的任何人,此错误已经重新出现,如此处所标识和记录

随后在RMarkdown 1.4中修复了这个问题