5

我想知道是否有一种简单的方法可以在knitr. 我知道的唯一方法是:(从https://github.com/yihui/knitr-examples/blob/master/075-knit-expand.Rnw简化)。但是将输出收集到src然后在循环之后打印它是一个拖累,因为我想编写一个函数来从任意数据集产生这样的循环。

\documentclass{article}
\title{Using knit\_expand() for templates}
\author{Yihui Xie}
\begin{document}

\maketitle
\tableofcontents

<<lm-mtcars, tidy.opts=list(width.cutoff=55)>>=
# the template
tpl = c("\\subsection{Regression on {{xvar}}}",
        "<<lm-{{xvar}}>>=",
        "lm(mpg~{{xvar}}, data=mtcars)",
        "@")
# expand to knitr source and pass to knit()
src = lapply(names(mtcars)[-1], function(xvar) {knit_expand(text = tpl)})
@

\Sexpr{knit(text = unlist(src))}

\end{document}

所以我希望能够做的是这样的事情:

\documentclass{article}
\title{Using knit\_expand() for templates}
\author{Yihui Xie}
\begin{document}

\maketitle
\tableofcontents

<<lm, tidy.opts=list(width.cutoff=55)>>=
    myLfFun=function(dataset){
... some function definition which produces say an lm for each variable in dataset ...
}
@

\Sexpr{myLfFun(Titanic}
...
\Sexpr{myLfFun(mtcars}
... etc
\end{document}

...如果我在其上运行 brew() 会产生...

\documentclass{article}
\title{Brew + knitR}
\author{Ramnath Vaidyanathan}
\begin{document}

\maketitle
\tableofcontents



<<lm-cyl >>=
lm(mpg ~ cyl, data = mtcars)
@

<<lm-disp >>=
lm(mpg ~ disp, data = mtcars)
@

<<lm-hp >>=
lm(mpg ~ hp, data = mtcars)
@

<<lm-drat >>=
lm(mpg ~ drat, data = mtcars)
@

<<lm-wt >>=
lm(mpg ~ wt, data = mtcars)
@

<<lm-qsec >>=
lm(mpg ~ qsec, data = mtcars)
@

<<lm-vs >>=
lm(mpg ~ vs, data = mtcars)
@

<<lm-am >>=
lm(mpg ~ am, data = mtcars)
@

<<lm-gear >>=
lm(mpg ~ gear, data = mtcars)
@

<<lm-carb >>=
lm(mpg ~ carb, data = mtcars)
@

((... same for Titanic database ...))

\end{document}

...然后我可以 knit2pdf() 的输出。所以如果模板被称为 tmpl.Rnw,我会运行 brew('tmpl.Rnw','doc.Rnw');knit2pdf('doc.Rnw)

4

3 回答 3

3

我不明白为什么你需要knit_expand老好人sprintf可以做同样的事情。这是输出:http ://www.anst.uu.se/chrba104/stackoverflow/output.pdf 。

尽管我的模板也是为数据集定制的mtcars,但我看不出如何在不失去灵活性的情况下使其更简单。

\documentclass{article}
\title{Not using knit\_expand() for templates}
\author{Yihui Xie}
\begin{document}

\maketitle
\tableofcontents

<<lm-mtcars, tidy.opts=list(width.cutoff=55)>>=
vars <- setdiff(names(mtcars), 'mpg')
src <- sprintf(
    paste('\\subsection{Regression on %s}',
          '<<lm-%s>>=',
          'lm(mpg ~ %s, data=mtcars)',
          '@', sep='\n'),
    vars, vars, vars)
@
\Sexpr{knit(text = src)}

\end{document}
于 2013-01-14T11:10:13.207 回答
3

我更喜欢使用专门的模板库whiskerbrew实现您所寻求的,因为尝试使用 R 函数恕我直言编写乳胶代码是非常难看的。模板文件如下所示,命名为tpl.Rnw. 您可以通过运行以下命令将其转换为 pdf。您可以轻松编写一个函数来封装使用 knitr 将 brew 模板转换为 pdf 的逻辑。

brew('tpl.Rnw', 'doc.Rnw') 
knit2pdf('doc.Rnw')        

模板文件tpl.Rnw

\documentclass{article}
\title{Brew + knitR}
\author{Ramnath Vaidyanathan}
\begin{document}

\maketitle
\tableofcontents


<% for (xvar in names(mtcars)[-1]) { %>

\subsection{Regression on <%= xvar %>}

<<lm-<%= xvar %> >>=
lm(mpg ~ <%= xvar %>, data = mtcars)
@

<% } %>

\end{document}
于 2013-01-15T16:31:45.730 回答
0

我发现了为什么我不能把这\Sexpr{knit(text = unlist(src))}条线放在前面的普通代码块中。我需要在文档的开头设置并为块opts_knit$set(progress = F, verbose = F)设置至少一些。comment=NA, warning=FALSE,message=FALSE,echo=FALSE这个简单的动作使得粘贴行就像knit(text = unlist(src))我想要的任何地方一样,并且我想要在一个块中多次粘贴。这消除了对专用功能的需要。

于 2013-01-30T19:49:16.220 回答