Использование Rscript с файлом .Rnw И commandArgs ()

У меня есть файл .Rnw, содержащий фрагменты кода R и команды LaTeX. До сих пор я занимался разработкой и тестированием этого кода в Rstudio: нажав «Скомпилировать PDF», я получил несколько выходных файлов и сгенерированный файл PDF.

Теперь я хотел бы использовать commandArgs (), чтобы иметь возможность передать моему .Rnw единственный аргумент: файл YAML. Этот файл содержит всевозможные параметры, которые необходимы сценарию.

Чтобы дать некоторый контекст:

  • Мой .Rnw скрипт - это конвейерный скрипт, который был разработан, чтобы быть как можно более «универсальным».

  • Мой .Rnw скрипт требует каждый раз ряд параметров - это будут параметры, которые различаются для каждого проекта. Чтобы предоставить эти параметры, я в настоящее время (уже) использую файл конфигурации YAML. Это означает, что первое, что делает мой сценарий .Rnw, - это импортирует файл YAML, а затем он начинает что-то делать.

Моя проблема: могу ли я использовать «Rscript», «commandArgs ()» и knitr все вместе. Я надеялся, что, добавив некоторые commandArgs () в мой .Rnw скрипт, я смогу запустить все (т.е. дать аргумент в командной строке для предоставления файла YAML и компиляции PDF) следующим образом:

Rscript script.Rnw params.yaml

Однако я получаю эту ошибку по поводу "\", которая, как я сильно подозреваю, как-то связана с тем фактом, что я использую файл .Rnw (и самое первое в нем - команду LaTeX). Затем я увидел потенциальное решение в других сообщениях, таких как:

 Rscript -e "library(knitr); knit('script.Rnw')"
 pdflatex script.tex

Однако это также не удается - неудивительно, потому что я не предоставил ему свой файл конфигурации YAML.

Я понимаю, что мой дизайн, вероятно, ошибочен: используя commandAgrs () и knitr вместе, я усложняю вещи. Я также понимаю, что knitr, возможно, не был действительно предназначен для создания отчетов для скриптов, которые используются в качестве конвейеров (по крайней мере, это мое впечатление). Причина, по которой я хочу его использовать, заключается в том, чтобы для каждого проекта можно было быстро создать PDF-файл со всеми результатами.

Буду признателен за любой совет. Вот образец моего кода:

\documentclass[12pt, a4paper]{article}

\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\hypersetup{
colorlinks   = true, %Colours links instead of ugly boxes
urlcolor     = blue, %Colour for external hyperlinks
linkcolor    = blue, %Colour of internal links
citecolor   = blue %Colour of citations
 }
\usepackage{caption}
\setlength{\parindent}{0pt}
\usepackage{authblk}
\usepackage[nomarkers, nolists]{endfloat} %Positions figures at the end of the document and add no list of names (requires that chunk have fig.cap option)
\usepackage{soul} % Allows underline lines to be broken (use \ul{} instead of \underline{})

\usepackage{helvet} %Set up Arial as font
\renewcommand{\familydefault}{\sfdefault}

\newcommand{\Rfunction}[1]{{\texttt{#1}}}
\newcommand{\Rpackage}[1]{{\textit{#1}}}

\title{\textbf{Report}}
\author{Author}
\date{\today}



\begin{document}

\maketitle

\begingroup
\hypersetup{linkcolor=black} % force independent link colours in table of contents
\tableofcontents
\endgroup

\begingroup
\hypersetup{linkcolor=black} % force independent link colours in list of figures
\listoffigures
\endgroup



\newpage
\section{Introduction} 
This report blah blah blah

\newpage
\section{Results}

<<importing-lib, echo=FALSE, message=FALSE, cache=TRUE>>=

###################################################
# Obtain command-line YAML file and set directory #
###################################################

#!/usr/bin/env Rscript
args= commandArgs(trailingOnly=TRUE)

if (length(args) == 0) {
 stop("this script requires a configuration file (.yaml) as input")

 } else if (length(args) > 1) {
  stop("this script requires only one input: a configuration file (.yaml)")

}

params <-  yaml.load_file(args[1])

setwd(params$workdir)

if (dir.exists(file.path(params$workdir, "results")) == FALSE) {
  dir.create(file.path(params$workdir, "results","edgeR"), recursive = TRUE)
  dir.create(file.path(params$workdir, "results", "gsea", "input_files"), recursive = TRUE)
}

print("Hello!")
@

\end{document}

person mf94    schedule 30.05.2019    source источник
comment
Вы на правильном пути, но вам нужно отделить сценарий конфигурации от файла .Rnw, т.е. вы должны взять код из своего importing-lib чанка и поместить его в отдельный файл .R, добавить команды knitr в этот файл , и вызовите его с помощью Rscript.   -  person Alexis    schedule 30.05.2019
comment
@Alexis спасибо, я сделал то, что вы предложили. Я дал ответ двумя методами, которые, как я обнаружил, работают. Не уверен на 100%, какой из них лучше, но я думаю, что метод, который вы предложили, лучше.   -  person mf94    schedule 31.05.2019


Ответы (1)


Итак, я нашел 2 способа, которыми это работает:

Способ 1. Использование командной строки knitr () и pdflatex

В этом случае все остается одним скриптом (называемым script.Rnw), но выглядит он так:

\documentclass[12pt, a4paper]{article}

\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\hypersetup{
colorlinks   = true, %Colours links instead of ugly boxes
urlcolor     = blue, %Colour for external hyperlinks
linkcolor    = blue, %Colour of internal links
citecolor   = blue %Colour of citations
 }
\usepackage{caption}
\setlength{\parindent}{0pt}
\usepackage{authblk}
\usepackage[nomarkers, nolists]{endfloat} %Positions figures at the end of the document and add no list of names (requires that chunk have fig.cap option)
\usepackage{soul} % Allows underline lines to be broken (use \ul{} instead of \underline{})

\usepackage{helvet} %Set up Arial as font
\renewcommand{\familydefault}{\sfdefault}

\newcommand{\Rfunction}[1]{{\texttt{#1}}}
\newcommand{\Rpackage}[1]{{\textit{#1}}}

\title{\textbf{Test report}}
\date{\today}



\begin{document}

\maketitle

\begingroup
\hypersetup{linkcolor=black} % force independent link colours in table of contents
\tableofcontents
\endgroup

\begingroup
\hypersetup{linkcolor=black} % force independent link colours in list of figures
\listoffigures
\endgroup



\newpage
\section{Introduction} 
This is the introduction.

\newpage
\section{Results}

This is the results.

<<importing-lib, echo=FALSE, message=FALSE>>=

###################################################
# Obtain command-line YAML file and set directory #
###################################################

#!/usr/bin/env Rscript
args= commandArgs(trailingOnly=TRUE)

if (length(args) == 0) {
  stop("this script requires a configuration file (.yaml) as input")

  # } else if (length(args) > 1) {
  # stop("this script requires only one input: a configuration file (.yaml)")

}

library(yaml)
params <- yaml.load_file(args[1])

dir <- getwd()

if (dir.exists(file.path(dir, "results")) == FALSE) {
  dir.create(file.path(dir, "results","part1"), recursive = TRUE)
  dir.create(file.path(dir, "results", "part2", "input_files"), recursive = TRUE)
}

print("Hello!")
print(params$project)
@



\newpage
\section{End}

This is the end!

\end{document}

Чтобы запустить конвейер:

Rscript -e "library(knitr); knit('script.Rnw')" params.yaml && pdflatex script.tex

Метод 2: разделение кода на файл .Rnw и файл запуска .R

Script.Rnw выглядит так:

\documentclass[12pt, a4paper]{article}

\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\hypersetup{
colorlinks   = true, %Colours links instead of ugly boxes
urlcolor     = blue, %Colour for external hyperlinks
linkcolor    = blue, %Colour of internal links
citecolor   = blue %Colour of citations
 }
\usepackage{caption}
\setlength{\parindent}{0pt}
\usepackage{authblk}
\usepackage[nomarkers, nolists]{endfloat} %Positions figures at the end of the document and add no list of names (requires that chunk have fig.cap option)
\usepackage{soul} % Allows underline lines to be broken (use \ul{} instead of \underline{})

\usepackage{helvet} %Set up Arial as font
\renewcommand{\familydefault}{\sfdefault}

\newcommand{\Rfunction}[1]{{\texttt{#1}}}
\newcommand{\Rpackage}[1]{{\textit{#1}}}

\title{\textbf{Test report}}
\date{\today}



\begin{document}

\maketitle

\begingroup
\hypersetup{linkcolor=black} % force independent link colours in table of contents
\tableofcontents
\endgroup

\begingroup
\hypersetup{linkcolor=black} % force independent link colours in list of figures
\listoffigures
\endgroup



\newpage
\section{Introduction} 
This is the introduction.

\newpage
\section{Results}

This is the results.

<<first-chunk, echo=FALSE, message=FALSE>>=

print("Hello!")
print(params$project)
@



\newpage
\section{End}

This is the end!

\end{document}

Скрипт launch.R выглядит так:

#!/usr/bin/env Rscript

library(yaml)
library(knitr)

args= commandArgs(trailingOnly=TRUE)

if (length(args) == 0) {
  stop("this script requires a configuration file (.yaml) as input")

  # } else if (length(args) > 1) {
  # stop("this script requires only one input: a configuration file (.yaml)")

}

params <- yaml.load_file(args[1])

dir <- getwd()

if (dir.exists(file.path(dir, "results")) == FALSE) {
  dir.create(file.path(dir, "results","edgeR"), recursive = TRUE)
  dir.create(file.path(dir, "results", "gsea", "input_files"), recursive = TRUE)
}

knit2pdf('script.Rnw')

Чтобы запустить скрипт:

Rscript launch.R params.yaml

Одно различие между методами: метод 1 генерирует больше файлов (* tex, * toc, * out, * log, * aux), предположительно потому, что технически это 2 команды. Метод 2 создает только файлы .tex и .pdf.

person mf94    schedule 31.05.2019