如何生成R标记文件,如“source(';myfile.R';)”?

如何生成R标记文件,如“source(';myfile.R';)”?,r,markdown,knitr,R,Markdown,Knitr,我通常有一个主R标记文件或knitr LaTeX文件,其中我源代码一些其他R文件(例如,用于数据处理)。然而,我认为,在某些情况下,将这些源文件作为其自身的可复制文件(例如,R标记文件,不仅包括数据处理命令,而且还生成解释数据处理决策的可复制文件)是有益的 因此,我希望在我的主R标记文件中有一个类似于source('myfile.rmd')的命令。这将从myfile.rmd的R代码块中提取并获取所有R代码。当然,这会导致错误 以下命令起作用: ```{r message=FALSE, resul

我通常有一个主R标记文件或knitr LaTeX文件,其中我
源代码
一些其他R文件(例如,用于数据处理)。然而,我认为,在某些情况下,将这些源文件作为其自身的可复制文件(例如,R标记文件,不仅包括数据处理命令,而且还生成解释数据处理决策的可复制文件)是有益的

因此,我希望在我的主R标记文件中有一个类似于
source('myfile.rmd')
的命令。这将从
myfile.rmd
的R代码块中提取并获取所有R代码。当然,这会导致错误

以下命令起作用:

```{r message=FALSE, results='hide'}
knit('myfile.rmd', tangle=TRUE)
source('myfile.R')
```
其中,如果需要输出,可以省略
results='hide'
。即,knitr将R代码从
myfile.rmd
输出到
myfile.R

然而,它似乎并不完美:

  • 它会导致创建一个额外的文件
  • 如果需要控制显示,则它需要显示在自己的代码块中
  • 它不像简单的
    源代码(…)
    那么优雅
因此,我的问题是:
有没有更优雅的方法来获取R标记文件的R代码?

如果您正在寻找代码,我认为以下几点应该可以:

  • 使用
    readLines

  • 使用
    grep
    查找代码块,搜索以
    开头的行。您似乎在寻找一行。把这个放到你的
    .r文件中怎么样

    ksource <- function(x, ...) {
      library(knitr)
      source(purl(x, output = tempfile()), ...)
    }
    

    ksource将公共代码分解成一个单独的R文件,然后将该R文件的源代码分解成您想要的每个Rmd文件

    比如说,我需要做两份报告,流感爆发和枪支与黄油的对比分析。当然,我会创建两个Rmd文档并完成它

    现在假设老板来了,想看看流感爆发与黄油价格的变化(控制9毫米弹药)

    • 复制并粘贴代码以分析报告到新报告中对于代码重用等来说是一个坏主意
    • 我希望它看起来漂亮
    我的解决方案是将项目分解成以下文件:

    • 流感
      • 流感数据导入.R
    • 枪炮
      • 枪\u数据\u导入.R
      • 黄油\u数据\u导入.R
    在每个Rmd文件中,我有如下内容:

    ```{r include=FALSE}
    source('flu_data_import.R')
    ```
    
    这里的问题是我们失去了再现性。我的解决方案是创建一个公共子文档,将其包含到每个Rmd文件中。因此,在我创建的每个Rmd文件的末尾,我添加了以下内容:

    ```{r autodoc, child='autodoc.Rmd', eval=TRUE}
    ``` 
    
    当然,还有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>
    
    源数据和代码
    ----------------------------
    ```{r sourcedata,echo=FALSE,results=asis',warnings=FALSE}
    如果(!存在(autodoc.skip.df)){
    autodoc.skip.df html工作流。如果使用latex或其他任何东西,这将是一个难看的混乱。此Rmd文档在全局环境中查找所有源()'编辑文件,并在文档末尾包含其来源。它包括jquery ui、tablesorter,并将文档设置为使用手风琴样式来显示/隐藏源文件。这是一项正在进行的工作,但可以根据自己的用途随意调整


    我知道,这不是一句台词。希望它至少能给你一些想法:)

    也许你应该开始改变想法。我的问题如下: 在.R文件的.Rmd块中编写您通常拥有的所有代码。 对于用于编织的Rmd文档,即html,您只剩下

    ```{R Chunkname, Chunkoptions}  
    source(file.R)  
    ```
    
    这样,您可能会创建一堆.R文件,并且失去了使用ctrl+alt+n(或+c,但通常不起作用)处理所有代码“一块接一块”的优势。 但是,我读了Gandrud先生关于可复制研究的书,意识到他肯定只使用knitr和.Rmd文件来创建html文件。主要分析本身就是一个.R文件。
    我认为,如果您开始在内部进行整个分析,.Rmd文档会迅速变大。

    我建议将主要的分析和计算代码保存在.R文件中,并根据需要在.Rmd文件中导入块。我已经解释了该过程。

    以下黑客技术对我来说效果很好:

    library(readr)
    library(stringr)
    source_rmd <- function(file_path) {
      stopifnot(is.character(file_path) && length(file_path) == 1)
      .tmpfile <- tempfile(fileext = ".R")
      .con <- file(.tmpfile) 
      on.exit(close(.con))
      full_rmd <- read_file(file_path)
      codes <- str_match_all(string = full_rmd, pattern = "```(?s)\\{r[^{}]*\\}\\s*\\n(.*?)```")
      stopifnot(length(codes) == 1 && ncol(codes[[1]]) == 2)
      codes <- paste(codes[[1]][, 2], collapse = "\n")
      writeLines(codes, .con)
      flush(.con)
      cat(sprintf("R code extracted to tempfile: %s\nSourcing tempfile...", .tmpfile))
      source(.tmpfile)
    }
    
    库(readr)
    图书馆(stringr)
    
    source_rmd我使用以下自定义函数

    source_rmd <- function(rmd_file){
      knitr::knit(rmd_file, output = tempfile())
    }
    
    source_rmd("munge_script.Rmd")
    

    source\u rmd尝试knitr的purl函数:

    source(knitr::purl(“myfile.rmd”,quiet=TRUE))
    这对我来说很有效

    source("myfile.r", echo = TRUE, keep.source = TRUE)
    
    sys.source(“./your_script_file_name.R”,envir=knitr::knit_global())

    在调用your_script_文件_name.R中包含的函数之前,请执行此命令

    如果您已经创建了一个项目,则在脚本文件名称之前添加“/”以显示文件的方向

    您可以查看此链接了解更多详细信息:

    我使用此单行程序:

    ```{r optional_chunklabel_for_yourfile_rmd, child = 'yourfile.Rmd'}
    ```
    
    见:

    我实际上很难理解你的问题(我读了好几遍)。你可以很容易地将其他R脚本源代码编入
    Rmd
    文件。但是你也希望将其他
    标记文件源代码编入正在编制的文件中?我想在R标记文件(即,*.Rmd)中的R代码块中编写R代码?我对这个问题做了一点编辑,以使问题更清楚。类似于在latex中包含
    的内容。如果markdown支持包含其他markdown文档,那么创建这样的函数应该相对容易。@PaulHiemstra我想能够获取文本和R代码块也会很有用。我是sp具体地说,考虑只在R降价文档中寻找代码。谢谢,我想这会起作用。然而,前四点听起来像Stangle已经以可靠的方式为Swave做了什么,以及knitr('myfile.rmd',tangle=TRUE)
    在knitr中做了什么。我想我正在寻找的是一种既能纠结又能纠结的内衬