我正在开发一个R包.它基于仅使用Makefile的项目.大部分内容都很容易转换为R CMD build工作流程.然而,我需要创建的pdfs有点复杂,除非我修补,否则我没有把它们弄好 - 到目前为止,我想到了如何使用Makefile.
在R包文档中,我找到了使用Makefile作为源代码甚至是vignet的参考.
我不明白应该如何应用这些.从这些文档中我得到的印象Makefiles将在进程中被调用,R CMD build但是当我将Makefile放在所描述的目录中时,它们将被忽略.然而,R CMD check识别它们并输出通过测试.
我也看到了一些R CMD build内部调用的Makefile - 但我一直想知道这些在我使用时会如何执行install.packages.这似乎不对 - 我的意思是为什么R CMD check这些如果它不关心.R包中还有关于添加的这个页面SystemRequiremens: GNU make - 为什么这个文件你不使用?
那么现在最好的做法是什么?我可以看一下野外的例子吗?
更新
正如我被问到一个例子
我想构建一个与"编写包装晕影"中描述的相似的小插图.有一个主Latex文件,其中包含几个Rnw文件.具体的困境是:
到目前为止我用Makefile做了,一般模式是这样的:
tmp/test.pdf: tmp/test.tex tmp/rnw1.tex tmp/rnw2.tex
latexmk -outdir=$(@D) $<
tmp/%.tex: r/%.rnw
Rscript -e "knitr::knit('$<', output='$@')"
tmp/rnw1.tex tmp/rnw2.tex: tmp/slowdata.Rdata
tmp/slowdata.Rdata: r/ireallytakeforever.R
Rscript $<
Run Code Online (Sandbox Code Playgroud)
Bdecaf,
好的,回答版本2.0 - 轻笑.
您提到" 问题是Makefile和包构建工作流程应该如何结合在一起 ".在这种情况下,我建议您查看一组示例R包makefile:
该knitr包makefile(在我看来)提供了如何构建护身符一个很好的例子.您需要查看makefile和目录结构,这将是我建议您查看和使用的模板.
我还建议你看看制造商,一个用于R包开发的Makefile.最重要的是,我将从Karl Broman指南开始- (这是我自己用作源参考的一段时间,现在已经被Hadley关于包装的书黯然失色但仍然有用(在我看来).
另一个建议是阅读Rob Hynman之前提到过的文章
在他们之间,你应该能够做你要求的.除此之外,您还可以参考基础R包手册.
我希望以上有所帮助.
T.
我认为,可重复研究最重要的工具不是Sweave或knitr,而是GNU make.
例如,考虑与手稿相关的所有文件.在最简单的情况下,我会为每个图形添加一个R脚本,并为主文本添加一个LaTeX文件.然后是参考文件的BibTeX文件.
编译最终的PDF有点工作:
并且R脚本需要在latex之前运行,并且只有在它们已经改变时才运行.
GNU make使这很容易.在您的手稿目录中,您将创建一个名为Makefile的文本文件,其外观如下所示(此处使用pdflatex).
mypaper.pdf: mypaper.bib mypaper.tex Figs/fig1.pdf Figs/fig2.pdf
pdflatex mypaper
bibtex mypaper
pdflatex mypaper
pdflatex mypaper
Figs/fig1.pdf: R/fig1.R
cd R;R CMD BATCH fig1.R
Figs/fig2.pdf: R/fig2.R
cd R;R CMD BATCH fig2.R
Run Code Online (Sandbox Code Playgroud)
每批行指示要创建的文件(目标),它依赖的文件(先决条件),然后是从依赖文件构造目标所需的一组命令.请注意,带有命令的行必须以制表符(而不是空格)开头.
另一个很棒的特性:在上面的例子中,当fig1.R改变时你只构建fig1.pdf.请注意,依赖关系会传播.如果你改变fig1.R,那么fig1.pdf将会改变,所以mypaper.pdf将被重建.
一个奇怪的是:如果您需要更改目录以运行命令,请在与相关命令相同的行上执行cd.以下不起作用:
### this doesn't work ###
Figs/fig1.pdf: R/fig1.R
cd R
R CMD BATCH fig1.R
You can, however, use \ for a continuation line, line so:
### this works ###
Figs/fig1.pdf: R/fig1.R
cd R;\
R CMD BATCH fig1.R
Run Code Online (Sandbox Code Playgroud)
请注意,您仍然需要使用分号(;).
您可能已经在计算机上安装了GNU make.在终端/ shell中输入make --version来查看.(在Windows上,转到此处下载make.)
要使用make:
您可以使用上述简单的make文件,指定目标文件,它们的依赖项以及创建它们的命令.但是你可以添加许多装饰,以节省一些打字.
以下是我使用的一些选项.(有关详细信息,请参阅make文档.)
如果您要多次重复同一段代码,则可能需要定义一个变量.
例如,您可能希望使用标志--vanilla运行R. 然后,您可以定义变量R_OPTS:
R_OPTS = - vanilla你将这个变量称为$(R_OPTS)(或$ {R_OPTS};允许使用括号或花括号),所以在R命令中你会使用像
cd R; R CMD BATCH $(R_OPTS)fig1.R这样做的一个优点是你只需要输入你想要的选项; 如果你改变主意想要使用的R选项,你只需要在一个地方更改它们.
例如,我实际上喜欢使用以下内容:
R_OPTS = - no-save --no-restore --no-init-file --no-site-file这就像--vanilla但没有--no-environ(我需要它,因为我使用.Renviron文件定义R_LIBS,说我在另一个目录中定义了R包).
有一堆自动变量可以用来节省大量的输入.这是我最常用的:
$@ the file name of the target
$< the name of the first prerequisite (i.e., dependency)
$^ the names of all prerequisites (i.e., dependencies)
$(@D) the directory part of the target
$(@F) the file part of the target
$(<D) the directory part of the first prerequisite (i.e., dependency)
$(<F) the file part of the first prerequisite (i.e., dependency)
Run Code Online (Sandbox Code Playgroud)
例如,在我们的简单示例中,我们可以简化线条
Figs/fig1.pdf: R/fig1.R
cd R;R CMD BATCH fig1.R
Run Code Online (Sandbox Code Playgroud)
我们可以改写
Figs/fig1.pdf: R/fig1.R
cd $(<D);R CMD BATCH $(<F)
Run Code Online (Sandbox Code Playgroud)
$(<D)在这种情况下,自动变量将采用第一个先决条件R的目录值.在这种情况下$(<F),将获取第一个先决条件的文件部分的值fig1.R.
好的,这不是真正的简化.这似乎没有多大优势,除非该目录可能是一个令人讨厌的长字符串,我们想避免必须输入两次.主要优势在于下一节.
如果要以相同的方式构建多个文件,则可能需要使用模式规则.关键的想法是你可以使用符号%作为通配符,扩展为任何文本字符串.
例如,我们的两个数字基本上以相同的方式构建.我们可以通过包含一系列覆盖fig1.pdf和fig2.pdf的行来简化示例:
Figs/%.pdf: R/%.R
cd $(<D);R CMD BATCH $(<F)
Run Code Online (Sandbox Code Playgroud)
这样可以节省输入并使文件更易于维护和扩展.如果要添加第三个数字,只需将其添加为mypaper.pdf的另一个依赖项(即先决条件).
我们的例子,有褶边
将所有这些添加到一起,这就是我们的示例Makefile的样子.
R_OPTS=--vanilla
mypaper.pdf: mypaper.bib mypaper.tex Figs/fig1.pdf Figs/fig2.pdf
pdflatex mypaper
bibtex mypaper
pdflatex mypaper
pdflatex mypaper
Figs/%.pdf: R/%.R
cd $(<D);R CMD BATCH $(R_OPTS) $(<F)
Run Code Online (Sandbox Code Playgroud)
增加的装饰的优点是:减少打字,并且更容易扩展以包括额外的数字.缺点:对于不熟悉GNU Make的其他人来说,更难理解它正在做什么.
更复杂的例子
整个地方都有复杂的Makefile.捅github并研究它们.
以下是我自己的一些例子:
以下是Mike Bostock的一些例子:
同样令人感兴趣的是制造商,一个用于R包开发的Makefile.
R包是分发R代码和文档的最佳方式,尽管官方手册(Writing R Extensions)可能给出的印象,但它们的创建起来非常简单.
即使对于您不打算分发的代码,您也应该创建一个R包.如果它们在一个包中,你会发现更容易跟踪你自己的个人R功能.写文档很好,即使它只是为了你未来的自我.
Hadley Wickham写 了一本关于R包的书(免费在线;也可以从亚马逊以纸质形式获得 ).你可能会直接跳到那里.
希拉里·帕克写了一篇关于编写R包的 简短明了的教程.如果你想要一个速成课程,你应该从那里开始.很多人已经从她的指令中成功构建了R包.
但是拥有多样化的资源是有价值的,所以我想我会继续编写自己的最小教程.以下主题列表看起来令人生畏,但每个主题都简短明了(希望很清楚).如果你被主题列表所拖延,并且你还没有放弃我支持 Hadley的书,那你为什么不读 Hilary的教程呢?
如果有人还在我身边,以下几页介绍了制作R套餐的要点.
以下是重要但不重要的.
以下包含指向其他资源的链接:
如果这里的任何内容令人困惑(或错误!),或者如果我错过了重要的细节,请 提交一个问题,或者(甚至更好)为此网站分叉GitHub存储库,进行修改并提交拉取请求.
本教程的源代码在github上.
另请参阅我在git/github上的 教程, GNU make, knitr, 使用GitHub页面制作网站, 数据组织和可重复的研究.