当编织到html时,库(printr)与data.table的“:=”交互?

moc*_*ave 1 r knitr r-markdown data.table

我有一个在 rstudio 控制台中运行的 markdown 文件,但是当我尝试将其编织成 html 时,它会花费很长时间。我花了很长时间的尝试和错误才确定似乎包含“printr”库会触发 data.table 的 := 分配,通过尝试打印整个表(在我的情况下非常大)来挂起编织)。这是演示这一点的代码。这是 printr 的已知“功能”吗?值得指出的是,即使代码块是results='hide'orinclude=FALSE并且表格没有在 html 中显示,包含 printr 的代码仍然会运行得很慢。

library(data.table)
library(bit64)
library(printr) # printr will make data.table := to print out the data in knit?
#test_n = 4000000 # with 4000000 and printr included it will take forever
test_n = 4000

print("slow chunk start:")
print(Sys.time())
DT = data.table(a = as.integer(1:test_n),
                b = as.integer64(1:test_n),
                c = as.integer(1:test_n))
DT[, seq:=1:.N] # whole table will print if printr is included
print(DT[1:10])
print("slow chunk end:")
print(Sys.time())
Run Code Online (Sandbox Code Playgroud)

use*_*330 7

问题是该data.table包定义了printdata.tables 的方法,但没有定义knit_print方法,因此knitr使用knit_print.data.frame中定义的方法printr,并打印整个内容。

有几个简单的解决方案。@r2evans 建议使用invisible(),例如invisible(DT[, seq:=1:.N])。这会起作用,因为knitr如果你要求它不打印,它就不会尝试打印东西。

另一个简单的解决方案是提供您自己的knit_print不打印任何内容的方法,例如

knit_print.data.table <- function(x, ...) NULL
Run Code Online (Sandbox Code Playgroud)

将其尽早放入文档中,您将永远不会打印 data.tables。如果您有时希望打印它们,您可以设置一个选项,例如

knit_print.data.table <- function(x, ...) {
  if (getOption("print.data.tables", FALSE)) # default to FALSE
    NextMethod()
}
 
Run Code Online (Sandbox Code Playgroud)

默认情况下不会打印,但如果您希望打印,请运行

options(print.data.tables = TRUE)
Run Code Online (Sandbox Code Playgroud)

事先(如果您只想发生一次,则随后将其设置为 FALSE)。

另一种未记录的方法是将方法设置为

knit_print.data.table <- function(x, ...) {
  if (data.table::shouldPrint(x)) 
    NextMethod()
}
Run Code Online (Sandbox Code Playgroud)

的文档shouldPrint表明这是正确的解决方案,但他们确实警告不要使用它。