Сценарий основного поведения в R?
Работать с knitr
ввел новую проблему - многие из моих R
Сценарии включают в себя код, генерирующий изображения, а код печати замедляет процесс, когда я пишу код.
Моя идея состоит в том, чтобы переместить код черчения в группу, которая выполняется только в том случае, если код выполняется на верхнем уровне, и не запускается, когда код получен из другого R-скрипта, через source()
идиома. Это возможно?
Я нашел этот старый вопрос SO, однако interactive()
всегда будет TRUE
в моем случае так принятый ответ не работает.
Мой случай таков: у меня есть файл, myKnit.rnw
и запустить его, отправив его из vim
в R
, с использованием vim-r-plugin
, Таким образом, interactive()
всегда будет TRUE
, а также length(sys.frames())
будет отличным от нуля - как vim-r-plugin
в основном работает через приложение base::source(...)
во временный файл.
Решение, которое я ищу, это R
эквивалентно python
идиома if __name__ == __main__
,
Таким образом, когда myKnit.rnw
работает и источники myscript.r
с помощью source("~/R/myscript.r")
, if
оценивает FALSE
и код построения в myscript.r
не работает.
В терминах Python, __name__
(или как мы это называем) не будет __main__
когда myKnit.rnw
источники myscript.r
, но будет правдой, когда я отправлю myscript.r
на консоль от vim
,
пример knitr
код:
\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}
и вот сценарий сюжета, который получен:
require(ggplot2)
set.seed(1)
x <- rnorm(100)
pp <- qplot(x, geom = 'histogram')
pdf("seed1Hist.pdf")
print(pp)
dev.off()
Решение с системными флагами, отражающее комментарий Yihui
fromSource <- function()
{
knitSysSwitch <- function()
{
switch(Sys.info()[['sysname']],
Windows = 'source',
Darwin = 'base::source')
}
length(sys.frame()) >= 4 && sys.call(1)[[1]] == knitSysSwitch()
}
1 ответ
Я думаю, вы ищете что-то вроде этого:
if (length(sys.frames()) >= 4 && sys.call(1)[[1]] == quote(base::source)) {
# plot them
}
Когда код оценивается через source()
в стеке есть как минимум четыре кадра. sys.call()[[1]]
извлекает символ функции в вызове, который, я думаю, похож на __name__
в Python.
Кстати, возможно, вы знаете об этом: когда вы работаете в knitr
вы можете включить кеш используя опцию чанка cache=TRUE
ускорить трудоемкий код построения.