Can knit2pdf use the global environment? - r

In this answer, #Yihui said that knitr uses the global environment. This confused me--my experience had been that it doesn't. I never really use knit though, I usually go straight to PDF.
In a little experiment, it seems that knit does use the global environment (or whatever environment you specify using the envir argument), but that knit2pdf doesn't.
Minimal example: global_test.Rnw file
\documentclass{article}
\begin{document}
<<>>=
print(x)
#
\end{document}
R Script:
x <- "Hello World"
knit(input="global_test.Rnw")
# Works as expected, could now call tools::texi2pdf to generate pdf.
knit2pdf(input="global_test.Rnw")
# Doesn't
The latter generates PDF file that won't display and gives a warning:
running command '"C:\PROGRA~2\MIKTEX~1.9\miktex\bin\texi2dvi.exe" --quiet --pdf
"global.pdf" -I "C:/PROGRA~1/R/R-215~1.3/share/texmf/tex/latex" -I
"C:/PROGRA~1/R/R-215~1.3/share/texmf/bibtex/bst"' had status 1
I tried passing an environment to knit2pdf (envir = globalenv()) hoping it would be ... passed on, I just get an unused argument error.
Generally, I know that referencing the global environment is poor form, but is there a way to do it with knit2pdf, or to pass an environment explicitly, or am I better off using brew and sprintf as in #Ramnath's answer to the same question above?
In my use case, I don't think tools::texi2pdf is useful because I need to compile with XeLaTeX, which knit2pdf handles effortlessly.

The problems with the examples in the question seem to have nothing to do with environments. Everything will compile correctly and without warnings if the output argument is left off of knit2pdf.
For reference, I was using knitr 1.1 on R 2.15.3 on Windows 7. I'll let Yihui know as it appears to be a bug in knit2pdf (which calls tools::texi2pdf, which doesn't accept an output file path).
UPDATE: The problem has been fixed in the development version of knitr, available here.
It's also worth noting that the Compile PDF button in RStudio does not use your current environment, so if you want to have access to global variables and you are using RStudio, make an explicit call to the appropriate knit function rather than relying on the shortcut. In fact, it doesn't use knit2pdf directly, rather it calls rmarkdown::render.

Related

RStudio environment pane does not show knitr variables

I have a very simple knitr Rnw script. When I run it in RStudio, the Environment Pane shows that the global environment is empty although the script compiles into pdf correctly, and the variable is evaluated correctly.
\documentclass{article}
\begin{document}
<<settings, echo=FALSE>>=
library(knitr)
a<-1+10
#
The outcome is equal to \Sexpr{a}.
\end{document}
This worked fine always until recently. I wonder whether this has to do with some RStudio settings or knitr options. Variables in a regular R script show up fine in the environment pane. For more complex knitr projects, being able to look at the variables can make work much much easier.
Normally when you knit a document by clicking knit in RStudio, it is run in a separate R process, and the variables are deleted when done. Your code chunks won't be able to see variables in your environment, and those variables won't get modified.
There are ways to run in your current process: run each chunk as code, or run rmarkdown::render("somefilename.Rmd") in your main process. Then your document can see your current workspace and make modifications there.
For debugging, the 2nd approach is convenient, but for reproducibility of the final result, you should run the separate R process.
In the end, this is what worked for me. Instead of clicking on "Compile pdf" button in RStudio, I ran the following in the console:
knitr::knit2pdf("file.Rnw", envir = globalenv())
This had been recommended here:
knitr: why does nothing appear in the "environment" panel when I compile my .Rnw file

Don't print the name of the directory to stdout when using here::set_here('path')

I'm using the R package 'here' to define my working directory using the following command at the start of my script:
here::set_here(path='/path/to/my_directory/', verbose = F)
Every time I run the script it prints this to the console:
here() starts at /path/to/my_directory
Is there a way to suppress this output? I tried using the invisible() function but that didn't work...
The message you’re seeing is printed when you’re attaching the ‹here› package. Simply don’t do that (it’s unnecessary anyway) to prevent it.
Otherwise, load it as follows:
suppressPackageStartupMessages(library(here))
… yeah, not exactly elegant.

Execution of Rcpp chunks in RStudio

The knitr language engines makes it possible to include an Rcpp chunk in your R Markdown document. This works perfectly when knitting the entire document.
However, it doesn't seem to be possible to execute (that is, compile) the Rcpp chunk interactively in RStudio (v. 1.1.364), or am I missing something?
I could keep the C++ code in a separate file and use sourceCpp in a chunk, which also works fine. However, for small examples I use in teaching it's more convenient to have everything in one document. I could then use cppFunction, but that doesn't give proper syntax highlighting.
I'm either looking for an answer that shows that I, indeed, missed how to interactively compile Rcpp chunks in RStudio, or answers that suggest good practices for i) having all code in one file, and ii) being able to execute chunks interactively.

ESS & Knitr/Sweave: How to source the Rnw file into an interactive session?

This is a terribly simple request, and I can't believe I haven't found the solution to this yet, but I've been searching for it far and wide without luck.
I have an .Rnw file loaded up in Emacs, I use M-n s to compile it.
Everything works well, and it even opens an R buffer. Great. But that buffer
is entirely useless: it doesn't contain the objects that I just sourced!
Example minimal .Rnw file:
\documentclass{article}
\begin{document}
<<>>=
foo <- "bar"
#
\end{document}
Using M-n s, I now have a new R-buffer with a session loaded up, but:
> foo
Error: object 'foo' not found
That is disappointing. I would like to play around with the data interactively.
How do I achieve that? I don't want to be sourcing the file line-by-line, or
region-by-region with C-c C-c or something similar every time I change my code.
Ideally, it should be just like RStudio's source function, that leaves me with
a fully prepared R session.
I haven't tried this with sweave yet, only with knitr.
EDIT: the eval=TRUE chunk option does not seem to result in the correct behaviour.
This behaviour was recently changed in ESS. Now sweave and knitr are executed directly in the global environment, as if when you write it yourself at command line. So wait for a couple of more weeks till ESSv13.09 is out or use the development version.
Alternatively, you can also set ess-swv-processing-command to "%s(%s)" and you will get the same result, except automatic library loading.
For the record, knitr (in contrast to sweave) evaluates everything in it's own environment unless you instruct it otherwise.
[edit: Something went wrong. I don't see the correct .ess_weave any more. Probably some git commit messup again. So it is not fixed in 13.09. Fixing it now. Sorry.]
Open an interactive R session, and then call Sweave directly, I believe like this (untested though). knitr works in the same way, though you need to load the knitr library first.
> Sweave("yourfile.Rnw")
There is some potential for peril here, though. If you call Sweave in a session after doing other things, your code can use things previously in the workspace, thus making your results unreproducible.

workflow between Latex and R screwed

Trying to write my second Latex file
\documentclass{article}
\title{simple Sweave script}
\usepackage{/Users/Brenden/Documents/R/R-2.15.1/share/texmf/tex/latex/Sweave}
\begin{document}
\maketitle
This is a simple script to demonstrate Sweave. Let's
begin by generating some results
<<>>=
x=rnorm(30)
y=rnorm(30)
mean(x)
cor(x,y)
#
and follow that up with some random text
\end{document}
File saved with .Rnw as extension. I could then use Sweave under R to convert the file to tex. I then run pdflatex under cmd to get my .pdf file. R is stored under /Users/Brenden/Documents. MiKTex is stored under /Users/Brenden/Desktop.
It is said that usually the line of "usepackage" is not needed, as when I run Sweave under R, a line of "usepackage{Sweave}" will be added to the tex file which is stored under /Users/Brenden/Documents. However, if I don't put in userpackage line, when I run pdflatex under cmd (either under /Documents or /Desktop), I got a messsage that says "Sweave.sty not found". So I have been through this trouble by always adding a line of usepackage with a detailed path to help circumvent the problem. Although the "Sweave.sty not found" problem is circumvented, I do notice that when I run pdflatex under cmd, I got the response
LaTeX Warning: You have requested package '/Users/Brenden/Documents/R/R-
2.15.1/share/texmf/tex/latex/Sweave', but the package provides "Sweave'.
Then it runs through several files with .sty under MiKTex
(C:\Users\Brenden\Desktop\MiKTex\tex\latex\base\ifthen.sty)
(C:\Users\Brenden\Desktop\MiKTex\tex\latex\graphics\graphicx.sty)
(C:\Users\Brenden\Desktop\MiKTex\tex\latex\graphics\keyval.sty)
(C:\Users\Brenden\Desktop\MiKTex\tex\latex\graphics\graphics.sty)
(C:\Users\Brenden\Desktop\MiKTex\tex\latex\graphics\trig.sty)
...
to eventually create a .pdf
From another post on Stackoverflow, it is said, "That path is set automatically when you install LaTeX; it's your personal texmf tree and you can put any style or class files you want LaTeX to find there. The directory names don't matter, it searches recursively in them for Sweave.sty". To me, however, clearly my MiKTex could not find the Sweave.sty unless I specify the path. And even with the path specification, LaTex still gives me a warning. Could someone explain to me where I screwed up (during installing MiKTex, perhaps? ) so that I could help MiKtex find its way to Sweave without my specifying the path?
Thank you.
In the MiKTeX Settings program, there is a tab called "Roots". It is there that you can specify where additional .sty files can be found. In your case, I believe that you will want to add C:\Users\Brenden\Documents\R\R-2.15.1\share\texmf as an additional root. Doing this, any of the TeX programs will be able to find Sweave.sty whether run from inside R or from the command line.
It is annoying to be always distracted by little devils like this (new concept texmf tree, endless environment variables TEXINPUTS, SWEAVE_STYLEPATH_DEFAULT, ...). You will never worry about LaTeX packages if you use knitr, and if you like the Sweave style, you can simply put render_sweave() in the document like:
\documentclass{article}
\title{simple Sweave script}
<<setup, include=FALSE>>=
render_sweave()
#
\begin{document}
\maketitle
This is a simple script to demonstrate Sweave. Let's
begin by generating some results
<<>>=
x=rnorm(30)
y=rnorm(30)
mean(x)
cor(x,y)
#
and follow that up with some random text
\end{document}
Save it as, say, test.Rnw and compile it with
library(knitr); knit('test.Rnw') # or knit2pdf('test.Rnw')
And I guess you are probably better off without render_sweave() (i.e. use the default LaTeX style in knitr).
I suspect the path referred to in the other post is the path to your personal texmf tree, which is not where Sweave puts it. One option is to move it to your personal texmf tree, but the usual method nowadays, I believe, is to run pdflatex from within R, like this:
texi2dvi("foo.tex", pdf = TRUE)
I think you can also have Sweave add the full path automatically by adding
export SWEAVE_STYLEPATH_DEFAULT="TRUE"
to your .bashrc file, or whatever the equivalent would be on your system.
At the command line, R CMD sets up the environment with variables appropriate for running R, for instance on Windows
C:\Users\mtmorgan> "c:\Program Files\R\R-2.15.1\bin\R" CMD set
includes (this is not found if one types set at the command line)
TEXINPUTS=.;c:/PROGRA~1/R/R-215~1/.1/share/texmf/tex/latex;
and so
C:\Users\mtmorgan> "c:\Program Files\R\R-2.15.1\bin\R" CMD pdflatex myfile.tex
will find Sweave.sty. Also, tools::texi2dvi can be invoked from within R.
I eventually end up with the following solution:
install.packages("tinytex")
require("tinytex")}
install_tinytex(force = TRUE)
Sweave( "Report.Rnw" , encoding = "utf8" )
xelatex('Report.tex')
This code install TinyTex, then you can compile with pdflatex(), xelatex() or lualatex().

Resources