Сценарий основного поведения в 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 ускорить трудоемкий код построения.

Другие вопросы по тегам