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.
针织输出:
这是一个data.table
bug或data.table
错误?
编辑
我只是刚刚注意到,那个编码器在echo
代码的时候很奇怪。 看看上面的输出。 在我的源代码中我有DT[, c:=5]
但是knitr
呈现的是
DT[, `:=`(c, 5)]
奇怪的…
编辑2:caching
caching也似乎有一个问题:=
但是这必须是一个不同的原因,所以这里是一个单独的问题: 为什么针对data.table knitrcaching失败`:=`?
2014年10月更新 。 现在在data.table v1.9.5中:
:=
不再在knitr
打印,以便与#505提示处的行为保持一致。 testingknit("knitr.Rmd")
的输出现在在data.table的unit testing中。
和相关:
if (TRUE) DT[,LHS:=RHS]
现在不打印(感谢Jureiss, #869 )。 testing添加。 为了实现这个function,我们不得不忍受一个缺点:如果在函数结束前没有DT[]
的函数内使用a:=
,那么下一次在提示符下键入DT
,什么都不会打印。 一个重复的DT
将打印。 为了避免这种情况:在你的函数中包含最后一个:=
后的DT[]
。 如果这是不可能的(例如,它不是一个function,你可以改变),然后print(DT)
和DT[]
在提示保证打印。 和以前一样,在一个:=
查询的末尾添加一个额外的[]
是更新然后打印的build议成语; 例如> DT[,foo:=3L][]
以前的答案保留后人( global$depthtrigger
业务不再是从data.table v1.9.5,所以这不再是真实的)…
只是为了清楚,我明白:当你不想要的时候, knitr
正在印刷。
尝试在脚本开始时增加data.table:::.global$depthtrigger
。
目前这将是3:
data.table:::.global$depthtrigger [1] 3
我不知道多lesseval深度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]
不可见地返回”。 感谢这里的讨论:
如何在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? 我预计要么没有可见的价值(符合< – ),或消息或返回值包含多less行更新。 数据确实已经被引用更新并不明显。
这已经在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开始)设置一个全局标志,打印方法用来确定是否打印。
该全局标志是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 ie return(suppPrint(x)). }
基本上只是说:如果DT[,x:=y]
在提示符下运行,那么我知道REPL将对我的结果调用print
方法,这是我无法控制的。 好吧,所以给定的print
方法将要运行,我打算通过设置一个标志(因为运行的print
方法(即print.data.table
)是我可以控制的东西)在该print
方法内部禁止它。
在knitr
的情况下,它以一种聪明的方式模拟REPL。 这不是一个真正的脚本,iiuc,否则DT[,x:=y]
不会因为这个原因而打印。 但是因为它是通过eval
模拟REPL,所以从knitr
运行的代码有一个额外的eval
深度级别。 或者类似的东西(我不知道knitr
)。
这就是为什么我想增加depthtrigger
可能会做的伎俩。
Hacky / crufty,我同意。 但是,如果它工作,并让我知道哪个价值的作品,我可以改变data.table
感到knitr
意识,并自动改变depthtrigger
。 或者更好的解决scheme是最受欢迎的。
为什么不使用:
```{r, results='hide'} DT[, c:=5] ```
对于任何在2017年以RMarkdown 1.3和data.table 1.10或类似方式返回的人来说,这个bug的复苏,正如这里确定和logging的
随后在1.4版本中进行修复
用invisible()包围expression式。 这对我有用。
我遇到了同样的问题,我通过重新分配variables来解决这个问题。 在你的情况下:
DT <- DT[, ':=' (c, 5)]
但是有点冗长,特别是如果variables名称很大。