我经常有一个主R Markdown文件或knitr LaTeX文件,其中我source有一些其他R文件(例如,用于数据处理).但是,我认为在某些情况下,将这些源文件作为自己的可再现文档(例如,R Markdown文件不仅包括用于数据处理的命令,而且还生成可重复的文档来解释数据处理将是有益的.决定).
因此,我想source('myfile.rmd')在我的主R Markdown文件中有一个命令.这将提取和源代码的R代码块内的所有R代码myfile.rmd.当然,这会引起错误.
以下命令有效:
```{r message=FALSE, results='hide'}
knit('myfile.rmd', tangle=TRUE)
source('myfile.R')
```
Run Code Online (Sandbox Code Playgroud)
results='hide'如果需要输出,可以省略.即,从knitr输出的R代码myfile.rmd成myfile.R.
但是,它似乎并不完美:
source(...).因此我的问题是: 是否有更优雅的方式来获取R Markdown文件的R代码?
Yih*_*Xie 30
看来你正在寻找单线.怎么样把它放在你的.Rprofile?
ksource <- function(x, ...) {
library(knitr)
source(purl(x, output = tempfile()), ...)
}
Run Code Online (Sandbox Code Playgroud)
但是,我不明白为什么你想要source()Rmd文件本身的代码.我的意思是knit()将运行本文档中的所有代码,如果您提取代码并在一个块中运行它,所有代码将在knit()您运行此文档时运行两次(您自己运行).这两项任务应该是分开的.
如果你真的想要运行所有的代码,RStudio已经让这个变得相当简单:Ctrl + Shift + R.它基本上调用purl()和source()幕后.
Kei*_*ley 18
将公共代码分解为单独的R文件,然后将该R文件导入到您希望的每个Rmd文件中.
例如,假设我需要制作两份报告,流感爆发和枪支与黄油分析.当然,我会创建两个Rmd文档并完成它.
现在假设老板出现并希望看到流感爆发与黄油价格的变化(控制9毫米弹药).
我的解决方案是将项目纳入这些文件:
在每个Rmd文件中,我有类似的东西:
```{r include=FALSE}
source('flu_data_import.R')
```
Run Code Online (Sandbox Code Playgroud)
这里的问题是我们失去了可重复性.我的解决方案是创建一个包含在每个Rmd文件中的公共子文档.所以在我创建的每个Rmd文件的末尾,我添加了这个:
```{r autodoc, child='autodoc.Rmd', eval=TRUE}
```
Run Code Online (Sandbox Code Playgroud)
当然,还有autodoc.Rmd:
Source Data & Code
----------------------------
<div id="accordion-start"></div>
```{r sourcedata, echo=FALSE, results='asis', warnings=FALSE}
if(!exists(autodoc.skip.df)) {
autodoc.skip.df <- list()
}
#Generate the following table:
for (i in ls(.GlobalEnv)) {
if(!i %in% autodoc.skip.df) {
itm <- tryCatch(get(i), error=function(e) NA )
if(typeof(itm)=="list") {
if(is.data.frame(itm)) {
cat(sprintf("### %s\n", i))
print(xtable(itm), type="html", include.rownames=FALSE, html.table.attributes=sprintf("class='exportable' id='%s'", i))
}
}
}
}
```
### Source Code
```{r allsource, echo=FALSE, results='asis', warning=FALSE, cache=FALSE}
fns <- unique(c(compact(llply(.data=llply(.data=ls(all.names=TRUE), .fun=function(x) {a<-get(x); c(normalizePath(getSrcDirectory(a)),getSrcFilename(a))}), .fun=function(x) { if(length(x)>0) { x } } )), llply(names(sourced), function(x) c(normalizePath(dirname(x)), basename(x)))))
for (itm in fns) {
cat(sprintf("#### %s\n", itm[2]))
cat("\n```{r eval=FALSE}\n")
cat(paste(tryCatch(readLines(file.path(itm[1], itm[2])), error=function(e) sprintf("Could not read source file named %s", file.path(itm[1], itm[2]))), sep="\n", collapse="\n"))
cat("\n```\n")
}
```
<div id="accordion-stop"></div>
<script type="text/javascript">
```{r jqueryinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(url("http://code.jquery.com/jquery-1.9.1.min.js")), sep="\n")
```
</script>
<script type="text/javascript">
```{r tablesorterinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(url("http://tablesorter.com/__jquery.tablesorter.js")), sep="\n")
```
</script>
<script type="text/javascript">
```{r jqueryuiinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(url("http://code.jquery.com/ui/1.10.2/jquery-ui.min.js")), sep="\n")
```
</script>
<script type="text/javascript">
```{r table2csvinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(file.path(jspath, "table2csv.js")), sep="\n")
```
</script>
<script type="text/javascript">
$(document).ready(function() {
$('tr').has('th').wrap('<thead></thead>');
$('table').each(function() { $('thead', this).prependTo(this); } );
$('table').addClass('tablesorter');$('table').tablesorter();});
//need to put this before the accordion stuff because the panels being hidden makes table2csv return null data
$('table.exportable').each(function() {$(this).after('<a download="' + $(this).attr('id') + '.csv" href="data:application/csv;charset=utf-8,'+encodeURIComponent($(this).table2CSV({delivery:'value'}))+'">Download '+$(this).attr('id')+'</a>')});
$('#accordion-start').nextUntil('#accordion-stop').wrapAll("<div id='accordion'></div>");
$('#accordion > h3').each(function() { $(this).nextUntil('h3').wrapAll("<div>"); });
$( '#accordion' ).accordion({ heightStyle: "content", collapsible: true, active: false });
</script>
Run Code Online (Sandbox Code Playgroud)
NB,这是专为Rmd - > html工作流程设计的.如果你选择乳胶或其他任何东西,这将是一个丑陋的混乱.此Rmd文档在全局环境中查找所有source()'ed文件,并在文档末尾包含它们的源.它包括jquery ui,tablesorter,并设置文档以使用手风琴样式来显示/隐藏源文件.这是一项正在进行的工作,但可以根据自己的用途进行调整.
我知道,不是单行.希望它至少给你一些想法:)