从 knitr Rnw 构建 TeX 文件作为更大的父 TeX 文件的子文件以使用 R 对象和输出

从 knitr Rnw 构建 TeX 文件作为更大的父 TeX 文件的子文件以使用 R 对象和输出

这是我的常见问题:我正在使用 LaTeX 模板撰写论文(http://www.latextemplates.com/template/masters-doctoral-thesis)。模板是一个父文件,其中包含多个子章节。对于某些章节,我希望包含来自 R 的对象和输出,而对于其他章节(例如简介),我不想使用 R。对于没有 R 的章节,我创建了 .TeX 文件作为模板的一部分。

这是我的具体问题:现在我正在使用 knitr 创建带有 R 对象和输出的 .TeX 文件。如果其他选项(例如 sweave)更适合我想要做的事情,我愿意使用它们。我有一些来自论文模板的没有 R 对象的 .TeX 文件,我想将它们与带有 R 对象的 .Rnw(或其他)文件相结合。我希望将 .Rnw 文件创建为较大父 .TeX 文件的子 .TeX 文件。父子结构适用于我的 .TeX 文件,作为使用 \input{} 的模板的一部分。但是,我无法将从 .Rnw 文件创建的 .TeX 文件作为子 .TeX 文件包含在内。我已经看到了将 .Rnw 文件合并为较大父 .Rnw 文件的子文件的资源(这里),但它们似乎只合并了 .Rnw 文件,而不是 .Rnw 文件(带有 R)和 .TeX 文件(不带有 R)。

因为我的模板结构有一个父文件,所以我在其中指定了 documentclass、begin document 等。因此,子 .TeX 文件没有标题。因此,我首先尝试创建一个没有 documentclass 和 begin document 标题的 .Rnw 文件,但是当我将 .Rnw 文件编织成 .TeX 并从所有 .TeX 文件构建 LaTeX 文件时,我收到以下错误:

! LaTeX Error: Environment knitrout undefined.

但是,如果我在 .Rnw 文件中包括带有 documentclass 和 begin document 的标题,我会收到以下错误:

! LaTeX Error: Can be used only in preamble.

下面是我正在使用的 .Rnw 文件(带有标题):

\documentclass{文章}

\开始{文档}

这是一个代码块。

>=
1+1
字母
chartr('xie', 'XIE', c('xie yihui', 'Yihui Xie'))
par(mar=c(4, 4, .2, .2)); 图(rnorm(100))
@

您还可以编写内联表达式,例如 $\pi=\Sexpr{pi}$,其中 \Sexpr{1.598673e8} 是一个大数字。

\结束{文档}

以下是从.Rnw 文件生成的.TeX 文件:

\documentclass{文章}\usepackage[]{graphicx}\usepackage[]{color}
%% maxwidth 如果小于 linewidth 则为原始宽度
%% 否则使用线宽(以确保图形不超过边距)
\制作字母
\def\maxwidth{ %
  \ifdim\Gin@nat@width>\linewidth
    \行宽
  \别的
    \Gin@nat@width
  \fi
}
\makeatother

\definecolor{fgcolor}{rgb}{0.345, 0.345, 0.345}
\newcommand{\hlnum}[1]{\textcolor[rgb]{0.686,0.059,0.569}{#1}}%
\newcommand{\hlstr}[1]{\textcolor[rgb]{0.192,0.494,0.8}{#1}}%
\newcommand{\hlcom}[1]{\textcolor[rgb]{0.678,0.584,0.686}{\textit{#1}}}%
\newcommand{\hlopt}[1]{\textcolor[rgb]{0,0,0}{#1}}%
\newcommand{\hlstd}[1]{\textcolor[rgb]{0.345,0.345,0.345}{#1}}%
\newcommand{\hlkwa}[1]{\textcolor[rgb]{0.161,0.373,0.58}{\textbf{#1}}}%
\newcommand{\hlkwb}[1]{\textcolor[rgb]{0.69,0.353,0.396}{#1}}%
\newcommand{\hlkwc}[1]{\textcolor[rgb]{0.333,0.667,0.333}{#1}}%
\newcommand{\hlkwd}[1]{\textcolor[rgb]{0.737,0.353,0.396}{\textbf{#1}}}%

\usepackage{框架}
\制作字母
\newenvironment{kframe}{%
 \def\at@end@of@kframe{}%
 \ifinner\ifhmode%
  \def\at@end@of@kframe{\end{minipage}}%
  \开始{minipage}{\columnwidth}%
 \fi\fi%
 \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep
 \colorbox{shadecolor}{##1}\hskip-\fboxsep
     % 没有 \\@totalrightmargin,因此:
     \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
 \MakeFramed {\advance\hsize-\width
   \@totalleftmargin\z@ \linewidth\hsize
   \@setminipage}}%
 {\par\unskip\endMakeFramed%
 \在@end@of@kframe}
\makeatother

\definecolor{阴影颜色}{rgb}{.97, .97, .97}
\definecolor{消息颜色}{rgb}{0, 0, 0}
\definecolor{警告颜色}{rgb}{1, 0, 1}
\definecolor{错误颜色}{rgb}{1, 0, 0}
\newenvironment{knitrout}{}{} % 要在 TeX 中重新定义的空环境

\usepackage{alltt}
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}

\开始{文档}

这是一个代码块。

\开始{针织}
\definecolor{阴影颜色}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{kframe}
\开始{全部}
\hlnum{1} \hlopt{+} \hlnum{1}
\结束{alltt}
\开始{逐字}
## [1] 2
\结束{逐字}
\开始{全部}
\hlstd{字母}
\结束{alltt}
\开始{逐字}
## [1] “a” “b” “c” “d” “e” “f” “g” “h” “i” “j” “k” “l” “m” “n” “o” “p” “q”
## [18] “r” “s” “t” “u” “v” “w” “x” “y” “z”
\结束{逐字}
\开始{全部}
\hlkwd{chartr}\hlstd{(}\hlstr{"xie"}\hlstd{,} \hlstr{"谢"}\hlstd{,} \hlkwd{c}\hlstd{(}\hlstr{"谢义辉"}\hlstd{,} \hlstr{"谢义辉"}\hlstd{))}
\结束{alltt}
\开始{逐字}
## [1] “谢以虎” “谢以虎”
\结束{逐字}
\开始{全部}
\hlkwd{par}\hlstd{(}\hlkwc{mar} \hlstd{=} \hlkwd{c}\hlstd{(}\hlnum{4}\hlstd{,} \hlnum{4}\hlstd{,} \hlnum{0.2}\hlstd{,} \hlnum{0.2}\hlstd{))}
\hlkwd{图}\hlstd{(}\hlkwd{rnorm}\hlstd{(}\hlnum{100}\hlstd{))}
\结束{alltt}
\结束{kframe}
\includegraphics[width=\maxwidth]{figure/foo}

\结束{针织}


您还可以编写内联表达式,例如 $\pi=3.1416$,并且 \ensuremath{1.5987\times 10^{8}} 是一个大数字。

\结束{文档}

仅供参考,我对 LaTeX 和针织/编织还很陌生。

答案1

knitr有一些处理这个问题的相当简单的方法

选项 1:使用knit_child()内联 R 代码

假设您的设置如下。在同一目录中,您有:

graph.R

## ---- graph
library(ggplot2)
CarPlot <- ggplot() +
    stat_summary(data= mtcars,
                 aes(x = factor(gear),
                     y = mpg
                 ),
                 fun.y = "mean",
                 geom = "bar"
                 )
CarPlot

chapter1.Rnw

Hey, look, a graph (Figure~\ref{fig:graph})!

<<graph, echo=FALSE, message=FALSE, fig.lp='fig:', out.width='.5\\linewidth', fig.align='center', fig.cap="A graph", fig.pos='h!'>>=
@

main.Rnw

\documentclass{article}

\begin{document}

<<external-code, echo=FALSE, cache=FALSE>>=
read_chunk('./graph.R')
@

\Sexpr{knit_child('chapter1.Rnw')}

\end{document}

然后,您可以使用 或 来访问该knit文件main.Rnw并编译生成的文件。.texpdflatexxelatex

输出为:

在此处输入图片描述

.R请注意,您还可以从子文件中读取外部文件.Rnw

因此,下面的做法同样有效。

chapter1-mod.Rnw

<<external-code, echo=FALSE, cache=FALSE>>=
read_chunk('./graph.R')
@

Hey, look, a graph (Figure~\ref{fig:graph})!

<<graph, echo=FALSE, message=FALSE, fig.lp='fig:', out.width='.5\\linewidth', fig.align='center', fig.cap="A graph", fig.pos='h!'>>=
@

main-mod.Rnw

\documentclass{article}

\begin{document}

\Sexpr{knit_child('chapter1-mod.Rnw')}

\end{document}

选项 2:使用块选项child

假设您有graph.R并且chapter1.Rnw来自上面的同一个目录,那么您的main.Rnw应该是:

\documentclass{article}

\begin{document}

<<external-code, echo=FALSE, cache=FALSE>>=
read_chunk('./graph.R')
@

<<child-demo, child='chapter1.Rnw'>>=
@

\end{document}

.R请注意,在这种情况下,您也可以从子文档中读取外部文件。

因此,假设您在同一目录中有上面的graph.R文件,那么您的文件应该是:chapter1-mod.Rnwmain-mod.Rnw

\documentclass{article}

\begin{document}

<<child-demo, child='chapter1-mod.Rnw'>>=
@

\end{document}

答案2

您可以将 knitr 文件中的序言放入您的文件中。或者放入另一个名为 preamb.tex 的文件中,例如通过 \input{preamb} 调用。

----preamb.tex----%% 
maxwidth is the original width if it is less than linewidth
%% otherwise use linewidth (to make sure the graphics do not exceed the margin)
\makeatletter
\def\maxwidth{ %
  \ifdim\Gin@nat@width>\linewidth
    \linewidth
  \else
    \Gin@nat@width
  \fi
}
\makeatother

\definecolor{fgcolor}{rgb}{0.345, 0.345, 0.345}
\newcommand{\hlnum}[1]{\textcolor[rgb]{0.686,0.059,0.569}{#1}}%
\newcommand{\hlstr}[1]{\textcolor[rgb]{0.192,0.494,0.8}{#1}}%
\newcommand{\hlcom}[1]{\textcolor[rgb]{0.678,0.584,0.686}{\textit{#1}}}%
\newcommand{\hlopt}[1]{\textcolor[rgb]{0,0,0}{#1}}%
\newcommand{\hlstd}[1]{\textcolor[rgb]{0.345,0.345,0.345}{#1}}%
\newcommand{\hlkwa}[1]{\textcolor[rgb]{0.161,0.373,0.58}{\textbf{#1}}}%
\newcommand{\hlkwb}[1]{\textcolor[rgb]{0.69,0.353,0.396}{#1}}%
\newcommand{\hlkwc}[1]{\textcolor[rgb]{0.333,0.667,0.333}{#1}}%
\newcommand{\hlkwd}[1]{\textcolor[rgb]{0.737,0.353,0.396}{\textbf{#1}}}%

\usepackage{framed}
\makeatletter
\newenvironment{kframe}{%
 \def\at@end@of@kframe{}%
 \ifinner\ifhmode%
  \def\at@end@of@kframe{\end{minipage}}%
  \begin{minipage}{\columnwidth}%
 \fi\fi%
 \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep
 \colorbox{shadecolor}{##1}\hskip-\fboxsep
     % There is no \\@totalrightmargin, so:
     \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
 \MakeFramed {\advance\hsize-\width
   \@totalleftmargin\z@ \linewidth\hsize
   \@setminipage}}%
 {\par\unskip\endMakeFramed%
 \at@end@of@kframe}
\makeatother

\definecolor{shadecolor}{rgb}{.97, .97, .97}
\definecolor{messagecolor}{rgb}{0, 0, 0}
\definecolor{warningcolor}{rgb}{1, 0, 1}
\definecolor{errorcolor}{rgb}{1, 0, 0}
\newenvironment{knitrout}{}{} % an empty environment to be redefined in TeX

\usepackage{alltt}
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}

相关内容