12

I'm experimenting with gWidgetsWWW and encountered a strange error. I created a button with a handler to knit2html a report which used the data.table assignment operator ":=". The report came back with this error:

Error: := is defined for use in j only, and (currently) only once; i.e., DT[i,col:=1L] and DT[,newcol:=sum(colB),by=colA] are ok, but not DT[i,col]:=1L, not DT[i]$col:=1L and not DT[,{newcol1:=1L;newcol2:=2L}]. Please see help(":="). Check is.data.table(DT) is TRUE.

The report generates as expected using knit2html directly and also through RStudio's "Knit HTML" button, so I'm unsure why it fails when knit2html is called by the handler.

Here is a gWidgetsWWW window "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

Here is an example R Markdown Doc which produces the error:

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

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

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

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

```

Not sure why, but when I call localServerOpen("test_gui.R") and click the button, I get the error...

Any ideas?

Zach Waite
  • 347
  • 1
  • 2
  • 7
  • This works on my machine. What version of `data.table` are you using? – Andrie Oct 28 '12 at 05:19
  • `data.table(df)[,State:=tolower(State)]` is non standard usage. I think it would be safer to do `df <- as.data.table(df)` then `df[,State:=tolower(State)]` otherwise you are assigning by reference into an object I would not know how to reference., – mnel Oct 28 '12 at 06:05
  • @Andrie Anonymous := (on an unnamed object) should be fine. I do that quite a lot. Can't think what's wrong since it works for you, and Zach has 1.8.2 ... – Matt Dowle Oct 28 '12 at 07:55
  • The line `localServerOpen("test_report.html")` should likely be `browseURL("test_report.html")`. You might also want to use gWidgetsWWW2 (on github). It has fewer issues than gWidgetsWWW and some more features. – jverzani Oct 28 '12 at 19:15
  • Thanks, I will look at using gWidgetsWWW2 and switching over to browseURL() in place of localServerOpen() in those types of situations. – Zach Waite Oct 29 '12 at 13:31
  • Hi. Quick reminder to accept an answer please. It's fixed in data.table. v1.8.6 now on CRAN. – Matt Dowle Nov 23 '12 at 14:32

2 Answers2

7

Thanks to Zach and Yihui, this is now fixed in data.table v1.8.3 on R-Forge.

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.

The full assignInNamespace command is :

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

If you're not sure of the exact namespace name, set options(datatable.verbose=TRUE), run the offending line again and an output message should tell you which namespace name was decided not to be data.table aware.

Asof the time of this edit, the packages on data.table's whitelist (v1.9.3) are :

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

They tend to be packages which take user code as input and run that in their own environment.

Matt Dowle
  • 58,872
  • 22
  • 166
  • 224
4

This seems to be an environment issue. That is probably a problem between data.table and gWidgetsWWW. On knitr's side, there is at least one solution, which is to specify the environment for knitr to be the global environment, e.g.

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

Edit:

To illustrate this issue is irrelevant to knitr, try this:

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

Save it as test_gui.R, and

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

Click the button and you will also see the error.

Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
  • Thanks Yihui, this does seem to address the problem. – Zach Waite Oct 29 '12 at 13:28
  • That's interesting! See [this answer about cedta](http://stackoverflow.com/a/10529888/403310) for background. I can see that `data.table` needs to be `knitr`-aware. On the other hand, I thought `knitr` mimicked exactly as if the R code was pasted at the console? I'm more than happy to make a change to `data.table`. – Matt Dowle Oct 29 '12 at 17:52
  • @MatthewDowle just figured out it is not a `knitr` issue; it seems to be related to `gWidgetsWWW` (I guess it is because of the environment in which `handler` is run; not completely sure); anyway, you can talk to @jverzani – Yihui Xie Oct 29 '12 at 19:30
  • Thanks a lot. It's looking like a `data.table` issue then, I'll take a look. Filed as [bug#2340](https://r-forge.r-project.org/tracker/index.php?func=detail&aid=2340&group_id=240&atid=975). – Matt Dowle Oct 29 '12 at 21:13