问题 通过knitr,gWidgetsWWW使用时出现data.table错误


我正在尝试使用gWidgetsWWW并遇到一个奇怪的错误。我创建了一个带有处理程序的按钮,用于knit2html报告,该报告使用了data.table赋值运算符“:=”。报告回来时出现了这个错误:

错误:: =定义仅用于j,并且(当前)仅用于一次;即,   DT [i,col:= 1L]和DT [,newcol:= sum(colB),by = colA]都可以,但不是   DT [i,col]:= 1L,而不是DT [i] $ col:= 1L而不是DT [,{newcol1:= 1L; newcol2:= 2L}]。   请参阅帮助(“:=”)。检查is.data.table(DT)是否为TRUE。

该报告直接使用knit2html生成,也通过RStudio的“Knit HTML”按钮生成,所以我不确定为什么它会在处理程序调用knit2html时失败。

这是一个gWidgetsWWW窗口“test_gui.R”:

library(gWidgetsWWW)
library(knitr)

w<-gwindow("Test Window")
g<-ggroup(horizontal=F,cont=w)
b<-gbutton("Report Button",cont=g,handler=function(h,...){
    knit2html("test_report.Rmd")
    localServerOpen("test_report.html")
})

visible(w)<-T

这是一个示例R Markdown Doc,它产生错误:

Test Report
===========

```{r test_chunk}
library(data.table)

df<-data.frame(State=rownames(USArrests),USArrests)

data.table(df)[,State:=tolower(State)]

```

不知道为什么,但是当我调用localServerOpen(“test_gui.R”)并单击按钮时,我收到错误...

有任何想法吗?


12907
2017-10-28 02:55


起源

这适用于我的机器。什么版本的 data.table 你正在用吗? - Andrie
data.table(df)[,State:=tolower(State)] 是非标准用法。我认为做起来会更安全 df <- as.data.table(df) 然后 df[,State:=tolower(State)] 否则你将通过引用分配到一个我不知道如何引用的对象。 - mnel
我正在使用data.table 1.82 - Zach Waite
@Andrie Anonymous:=(在一个未命名的对象上)应该没问题。我做了很多。不能想到什么是错的,因为它适合你,而Zach有1.8.2 ...... - Matt Dowle
这条线 localServerOpen("test_report.html") 应该是 browseURL("test_report.html")。您可能还想使用gWidgetsWWW2(在github上)。它比gWidgetsWWW和更多功能更少的问题。 - jverzani


答案:


这似乎是一个环境问题。这可能是一个问题 data.table 和 gWidgetsWWW。上 knitr一方面,至少有一个解决方案,即指定环境 knitr 成为全球环境,例如

knit2html("test_report.Rmd", envir = globalenv())

编辑:

说明这个问题与此无关 knitr, 尝试这个:

library(gWidgetsWWW)

w<-gwindow("Test Window")
g<-ggroup(horizontal=F,cont=w)
b<-gbutton("Report Button",cont=g,handler=function(h,...){
  library(data.table)
  df<-data.frame(State=rownames(USArrests),USArrests)
  print(data.table(df)[,State:=tolower(State)])
})

visible(w)<-TRUE

保存为 test_gui.R,和

library(gWidgetsWWW)
localServerOpen('test_gui.R')

单击按钮,您还将看到错误。


4
2017-10-28 21:25



谢谢一惠,这似乎解决了这个问题。 - Zach Waite
那很有意思!看到 这个答案关于雪松 为背景。我理解了 data.table 需要是 knitr-知道的。另一方面,我想 knitr 模仿完全好像R代码粘贴在控制台上?我很乐意改变 data.table。 - Matt Dowle
@MatthewDowle刚想通了它不是一个 knitr 问题;它似乎与...有关 gWidgetsWWW(我想这是因为环境所在 handler 运行;不完全确定);无论如何,你可以和@jverzani交谈 - Yihui Xie
非常感谢。它看起来像一个 data.table 那么问题,我来看看。归档为 错误#2340。 - Matt Dowle
现在修好了。谢谢你的好榜样。 - Matt Dowle


感谢Zach和Yihui,现在修复了R-Forge上的data.table v1.8.3。

o  gWidgetsWWW wasn't known as data.table aware, even though it mimics
   executing code in .GlobalEnv, #2340. data.table is now gWidgetsWWW aware.  
   Further packages can be added if required by changing a new variable
      data.table:::cedta.override
   by using assignInNamespace(). Thanks to Zach Waite and Yihui Xie for
   investigating and providing reproducible examples.

完整的assignInNamespace命令是:

assignInNamespace("cedta.override",
                  c(data.table:::cedta.override,"<nsname>"),
                  "data.table")

如果您不确定确切的命名空间名称,请设置 options(datatable.verbose=TRUE),再次运行违规行,输出消息应该告诉你哪个命名空间名称决定不是data.table。

在编辑时,data.table的白名单(v1.9.3)上的包是:

> data.table:::cedta.override
[1] "gWidgetsWWW" "statET"      "FastRWeb"    "slidify"     "rmarkdown"  

它们往往是将用户代码作为输入并在自己的环境中运行的包。


7
2017-10-30 00:22



看起来像 slidify + data.table 显示与OP问题相同的问题。需要添加一个 assignInNamespace("cedta.override","slidify","data.table") 声明。 - mbask
@mbask当时错过了你的评论,抱歉。 slidify 现在补充说。谢谢。 - Matt Dowle
我有问题 slidify。它现在应该工作吗? - Stéphane Laurent
好吧现在有效。我不得不补充一下 poirot 在命名空间中。 - Stéphane Laurent
只是为了可见性我实际上必须使用“cedta.pkgEvalsUserCode”而不是“cedta.override” assignInNamespace 打电话来 ezknitr package是data.table意识到的。 - Matt Mills