3

I wrote a function for package optiRum called generatePDF that wrapsknitr:::knit2pdf to allow the addition of date components and some other bits and pieces.

Generally this works fine, but I've found an odd case where data.table functionality errors.

Example file:

\documentclass{article}

\begin{document}
\tableofcontents
<<>>=
library("data.table")
df<-data.table(expand.grid(seq(10000,200000,1000),seq(10000,200000,2000),seq(100000,400000,5000)))
setnames(df,c("Var1","Var2","Var3"),c("ad","fm","value"))
df<-df[ad+fm<value*.9&ad+fm>=value*.6]
df<-df[,`P Value`:=paste0(round(value/1000,2),"k")]
df<-df[,`ad Amount`:=paste0(round(ad/1000,2),"k")]
df<-df[,ratio:=(ad+fm)/value]
@

<<>>=
ggplot(df[value %in% seq(100000,400000,50000)&fm==50000],aes(x=ratio,y=ad,group=value,colour=`P Value`))+
  geom_line()
@
\end{document}

When I use optiRum:::generatePDF e.g.

install.packages("optiRum")
library("optiRum")
generatePDF( srcname="sample" ,destname="sample")

I get the following sorts of errors:

# Error: object 'ad' not found

knit2pdf on it's own works fine. If I take the generatePDF code and make it a global function and re-execute then it also works fine. I'm not doing anything odd in terms of scope as far as I know.

Does anyone have any tips on how to resolve?


generatePDF <- function (srcpath = getwd(), srcname, destpath = getwd(), destname, 
    DATED = FALSE, CLEANUP = TRUE, ...) 
{
    require("knitr")
    stopifnot(is.character(srcpath), is.character(srcname), is.character(destpath), 
        is.character(destname), is.logical(DATED), is.logical(CLEANUP), 
        file.exists(file.path(srcpath, paste0(srcname, ".Rnw"))))
    knit2pdf(input = file.path(srcpath, paste0(srcname, ".Rnw")), 
        output = file.path(destpath, paste0(destname, ifelse(DATED, 
            format(Sys.Date(), "%Y%m%d"), ""), ".tex")), compiler = "pdflatex")
    if (CLEANUP) 
        file.remove(dir(path = destpath, pattern = "*aux|*out|*toc", 
            full.names = TRUE))
}

Update

Changing the assignment methodology in above sample code yields different errors:

## Error: := and `:=`(...) are defined for use in j, once only and
in particular ways. See help(":="). Check is.data.table(DT) is TRUE.

In case it's relevant - tested on linux and windows

> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C         LC_TIME=C            LC_COLLATE=C         LC_MONETARY=C       
 [6] LC_MESSAGES=C        LC_PAPER=C           LC_NAME=C            LC_ADDRESS=C         LC_TELEPHONE=C      
[11] LC_MEASUREMENT=C     LC_IDENTIFICATION=C 

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] optiRum_0.30      scales_0.2.3      ggthemes_1.6.0    AUC_0.3.0         ggplot2_0.9.3.1   data.table_1.8.10
[7] knitr_1.5         testthat_0.8.1    devtools_1.4.1   

loaded via a namespace (and not attached):
 [1] MASS_7.3-29        RColorBrewer_1.0-5 RCurl_1.95-4.1     colorspace_1.2-4   dichromat_2.0-0    digest_0.6.4      
 [7] evaluate_0.5.1     formatR_0.10       grid_3.0.2         gtable_0.1.2       highr_0.3          httr_0.2          
[13] labeling_0.2       memoise_0.1        munsell_0.4.2      parallel_3.0.2     plyr_1.8           proto_0.3-10      
[19] reshape2_1.2.2     stringr_0.6.2      tools_3.0.2        whisker_0.3-2   

> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United Kingdom.1252  LC_CTYPE=English_United Kingdom.1252    LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C                            LC_TIME=English_United Kingdom.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] data.table_1.8.10 knitr_1.5         optiRum_0.21     

loaded via a namespace (and not attached):
[1] evaluate_0.5.1 formatR_0.10   highr_0.3      stringr_0.6.2  tools_3.0.2 
Steph Locke
  • 5,951
  • 4
  • 39
  • 77
  • I'm installing latex to try your code... in the meantime you may want to review your data.table usage. This `df$`P Value`<-df[,paste0(round(value/1000,2),"k")]` does not benefit from the main feature of the package, change by reference without copy the whole table. – Michele Feb 26 '14 at 12:13
  • I have an issue with latex to pdf convertion (it seems fancyvrd.sty is missing or something) but I do have the above script in `.tex` the execution of the R script was fine – Michele Feb 26 '14 at 12:33
  • Cheers for the swift response. The variety of usage was to see if it was one or all sorts of access methods, plus the `:=` method of assignment when used in a `results='as-is'` chunks tend to output stuff to the .tex (and then pdf) file. In the .tex file do you have this string present `\color{errorcolor}` ? – Steph Locke Feb 26 '14 at 13:13
  • 1
    @Michele the issue is that the errors are printed in the `.tex`. Changing all of the `data.table` stuff to `:=` works for me. @StephLocke you can do `df <- df[, x := ...]` to prevent printing or `invisible(df[, x:= ...])`. This might help http://stackoverflow.com/questions/15267018/knitr-gets-tricked-by-data-table-assignment – Jake Burkhead Feb 26 '14 at 13:13
  • @JakeBurkhead - changed the method (thanks for the tip!) but got different error, included in update – Steph Locke Feb 26 '14 at 13:22

1 Answers1

1

Setting the envir in knit2pdf seems to work. I downloaded the source for package:optiRum and changed generatePDF to pass ... to knit2pdf. The docs said thats where they should go, but the original function wasn't actually doing anything with .... So generatePDF becomes:

generatePDF<-function(srcpath = getwd() , srcname ,
                      destpath = getwd() , destname ,
                      DATED = FALSE , CLEANUP = TRUE ,
                      ...){
  require("knitr")
  stopifnot(
    is.character(srcpath),
    is.character(srcname),
    is.character(destpath),
    is.character(destname),
    is.logical(DATED),
    is.logical(CLEANUP),
    file.exists(file.path(srcpath , paste0(srcname ,
                                           ".Rnw")))
    )


  knit2pdf( input  = file.path(srcpath , paste0(srcname ,
                                             ".Rnw")),
            output = file.path(destpath , paste0(destname ,
                                              ifelse(DATED, format(Sys.Date(),"%Y%m%d"),"") ,
                                              ".tex") ) ,
            compiler='pdflatex',
            ...
  )
  if (CLEANUP) file.remove(dir( path=destpath,pattern="*aux|*out|*toc",full.names=TRUE))


}

Then, after installing from source and using the edited .Rnw in the OP, running:

library(optiRum)
optiRum::generatePDF(srcname = "sample", destname = "sample", envir=new.env(parent = .GlobalEnv))

works fine for me. Also on a mac now.. but I think its just the environment.

## R version 3.0.2 (2013-09-25)                                                                                                                                                                                                               
## Platform: x86_64-apple-darwin10.8.0 (64-bit)                                                                                                                                                                                               

## locale:                                                                                                                                                                                                                                    
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8                                                                                                                                                                          

## attached base packages:                                                                                                                                                                                                                    
## [1] stats     graphics  grDevices utils     datasets  methods   base                                                                                                                                                                       

## other attached packages:                                                                                                                                                                                                                   
## [1] data.table_1.8.11 ggplot2_0.9.3.1   knitr_1.4.1       optiRum_0.21                                                                                                                                                                     

## loaded via a namespace (and not attached):                                                                                                                                                                                                 
##  [1] colorspace_1.2-2   compiler_3.0.2     dichromat_2.0-0    digest_0.6.3                                                                                                                                                                 
##  [5] evaluate_0.4.7     formatR_0.9        grid_3.0.2         gtable_0.1.2                                                                                                                                                                 
##  [9] highr_0.2.1        labeling_0.2       MASS_7.3-29        munsell_0.4.2                                                                                                                                                                
## [13] plyr_1.8           proto_0.3-10       RColorBrewer_1.0-5 reshape2_1.2.2                                                                                                                                                               
## [17] scales_0.2.3       stringr_0.6.2      tools_3.0.2 
Steph Locke
  • 5,951
  • 4
  • 39
  • 77
Jake Burkhead
  • 6,435
  • 2
  • 21
  • 32
  • And to confirm, it's working for you from the package as opposed to creating a global function and utilising that? – Steph Locke Feb 26 '14 at 13:31
  • @StephLocke You're right. It doesn't work with the function from the package... I'll delete after you see this – Jake Burkhead Feb 26 '14 at 13:38
  • Hmm, now it works when I call it generally, but it still isn't working correctly inside my testthat suite of tests – Steph Locke Feb 26 '14 at 16:20
  • @StephLocke Which tests are failing? All tests in `test-generatePDF.R` pass for me by running `testthat::test_file("test-generatePDF.R")`. How are you running the tests? Can you post the test failures to pastebin? – Jake Burkhead Feb 26 '14 at 16:45
  • As this was a new issue, I was adding to my unit tests with the above sample. I think I found the issue - the default new.env() is created in the parent.frame. I changed the new.env call to be `envir=new.env(parent = .GlobalEnv) ` which seems to have resolved the issue. – Steph Locke Feb 26 '14 at 16:53