Working with knitr
has introduced a new problem -- many of my R
scripts include picture generating code, and the plotting code slows things down when i source the code.
My idea is to move plotting code into a group that only runs if the code is being executed at the upper level, and not run when the code is sourced by another R-script, via the source()
idiom. Is this possible?
I found this old SO question, however interactive()
will always be TRUE
in my case, so the accepted answer does not work.
My case is as follows: I have a file, myKnit.rnw
, and run it by sending it from vim
to R
, using the vim-r-plugin
. Thus, interactive()
is always going to be TRUE
, and length(sys.frames())
will be non-zero -- as the vim-r-plugin
basically works via applying base::source(...)
to a temporary file.
The solution i am looking for is an R
equivalent to the python
idiom if __name__ == __main__
.
Thus when myKnit.rnw
runs and sources myscript.r
via source("~/R/myscript.r")
, the if
evaluates to FALSE
and the plotting code in myscript.r
does not run.
In python terms, __name__
(or whatever we call it) would not be __main__
when myKnit.rnw
sources myscript.r
, but would be true when i send myscript.r
to the console from vim
.
example knitr
code:
\documentclass{beamer}
\begin{document}
\title{A Minimal Example}
\author{ricardo}
\maketitle
\begin{frame}[fragile]
source the code and then use the plot
<<source_plotScript, include=FALSE>>=
source("~/rwd/plotScript.r")
@
a histogram!
<<histy, fig.width=7, fig.height=5, messages=FALSE, warnings=FALSE>>=
print(pp)
@
\end{frame}
\end{document}
and here's the plot script that's sourced:
require(ggplot2)
set.seed(1)
x <- rnorm(100)
pp <- qplot(x, geom = 'histogram')
pdf("seed1Hist.pdf")
print(pp)
dev.off()
Solution with system specific flags, reflecting Yihui's comment
fromSource <- function()
{
knitSysSwitch <- function()
{
switch(Sys.info()[['sysname']],
Windows = 'source',
Darwin = 'base::source')
}
length(sys.frame()) >= 4 && sys.call(1)[[1]] == knitSysSwitch()
}
I guess you are looking for something like this:
if (length(sys.frames()) >= 4 && sys.call(1)[[1]] == quote(base::source)) {
# plot them
}
When the code is evaluated via source()
, there are at least four frames in the stack. sys.call()[[1]]
extracts the function symbol in the call, which I think is similar to __name__
in Python.
BTW, perhaps you are aware of this: when you are working in knitr
, you can turn on the cache using the chunk option cache=TRUE
to speed up the time-consuming plotting code.