table教學 - knitr被data.table`:=`賦值




rmarkdown title (4)

似乎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 bug還是data.table錯誤?

編輯

我剛剛注意到, knitr器在echo顯代碼時很奇怪。 看看上面的輸出。 在我的源代碼中,我有DT[, c:=5]但是knitr呈現的是什麼

DT[, `:=`(c, 5)]

奇怪的...

編輯2:緩存

緩存似乎也有問題:=但這必然是一個不同的原因,所以這裡有一個單獨的問題: 為什麼knitr緩存失敗的data.table`:=`?


2014年10月更新 。 現在在data.table v1.9.5中:

:=不再在knitr打印,以便與提示符時的行為保持一致, #505 。 測試knit("knitr.Rmd")的輸出現在在data.table的單元測試中。

和相關的:

if (TRUE) DT[,LHS:=RHS]現在不打印(感謝Jureiss, #869 )。 測試補充。 為了實現這一點,我們不得不忍受一個缺點:如果a := :在函數結束前沒有DT[]的函數內使用,那麼下次在提示符下輸入DT時,什麼都不會打印。 將打印重複的DT 。 為避免這種情況:在函數中包括最後一個:=後的DT[] 。 如果這是不可能的(例如,它不是你可以改變的功能)那麼print(DT)DT[]在提示保證打印。 和以前一樣,在:= query的末尾添加一個額外的[]是一個推薦的更新然後再打印的習慣用法; 例如> DT[,foo:=3L][]

以前的答案是為後代保留的( global$depthtrigger業務不再是從data.table v1.9.5完成的,所以這不再是真的)......

為了清楚knitr我明白了:當你不想要它時, 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]無形地返回”。 感謝此處的討論:
在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://.com/a/13606880/403310
    # All appropriate returns following this point are
    # wrapped i.e. return(suppPrint(x)).
}

必要的只是說:如果DT[,x:=y]在提示符下運行,那麼我知道REPL將在我的結果上調用print方法,超出我的控制範圍。 好的,所以給定print方法將要運行,我將通過設置一個標誌來抑制它在該print方法中(因為運行的print方法(即print.data.table )是我可以控制的)。

knitr的情況下,它以聰明的方式模擬REPL。 這不是一個真正的腳本,iiuc,否則DT[,x:=y]無論如何都不會打印出來。 但是因為它通過eval模擬REPL,所以從knitr運行的代碼有一個額外的eval深度。 或類似的東西(我不知道knitr )。

這就是為什麼我認為增加depthtrigger可能會成功。

Hacky / crufty,我同意。 但如果它有效,並且你讓我知道哪個值有效,我可以更改data.tabledata.table knitr並自動更改depthtrigger 。 或者歡迎任何更好的解決方案。



為什麼不使用:

```{r, results='hide'}
DT[, c:=5]
```

用invisible()包圍表達式。 這適合我。





knitr