【问题标题】:How to capture R text+image output into one file (html, doc, pdf etc)?如何将 R 文本+图像输出捕获到一个文件(html、doc、pdf 等)中?
【发布时间】:2012-08-19 00:18:10
【问题描述】:

任务是创建一个文件(word、rtf、pdf、html 或其他),将 R 的输出(例如:不是创建输出的代码)捕获为该格式(包括文本 图像)。

这样做的方式应该尽可能少地改变原始 R 脚本。

如果我只关心文本或图像,那么我会使用 ?sink 或 ?pdf。但我不知道如何以简单的方式将两者组合成一个输出。

我知道有一种方法可以使用export R output using r2wd,但它在我的口味中涉及到在原始代码中的太多奖章(我想对于 sweave 解决方案也是如此,尽管我没有经验可以告诉)

这里是未来示例的示例代码:

START.text.and.image.recording("output.file") # this is the function I am looking for
x <- rnorm(100)
y <- jitter(x)
print(summary(x))
print(head(data.frame(x,y)))
cor(x,y)
plot(x,y)
print(summary(lm(y~x)))
STOP.text.and.image.recording("output.file") # this is the function I am looking for

更新:有人问我不是 Sweave,也不是来自 ReproducibleResearch task view 的其他选项。

原因是:

  1. 我(还)不知道 LaTeX
  2. 即使知道 LaTeX,我也想要一些具有简单默认值的东西,以 简单地 将所有输出按顺序转储在一起。 “简单”意味着 - 尽可能少的额外代码/文件管理开销。

我知道像 sweave 或 brew 这样的东西更具可扩展性,但我想看看是否有针对较小项目/脚本的更“简单”的解决方案。

【问题讨论】:

    标签: r sweave knitr


    【解决方案1】:

    截至 2012 年,knitr 为这个问题提供了完美的解决方案。

    例如,创建一个扩展名为 rmd 的文件。将您的代码包装在几个命令中,如下所示:

    ```{r}
    x <- rnorm(100)
    y <- jitter(x)
    print(summary(x))
    print(head(data.frame(x,y)))
    cor(x,y)
    plot(x,y)
    print(summary(lm(y~x)))
    ```
    

    您可以通过多种方式将其转换为独立的 HTML 文件。在 RStudio 中,您只需按一个按钮 Knit HTML。 这是HTML file produced;要实际查看 HTML 在浏览器中的显示方式,请保存文件并打开它。

    图像代码和输出如您所料交织在一起。

    当然,您可以而且通常会将您的文件分成多个 R 代码块。但重点是,您不必这样做。

    这是我创建的另外几个示例:

    【讨论】:

      【解决方案2】:

      如果您了解 LaTeX,那么 sweave 可能是您最好的选择。 odfWeave 是一种类似的机制,但用于将代码嵌入到 OpenOffice.org 文件中。对于 HTML,有 R2html 包。但是所有这些都可能需要您稍微分解代码以充分利用系统。或者,您的 sweave/odfweave/html 模板可以在单个代码块中获取脚本的数据生成方面,并在需要的地方放置输出显示(print() 语句)。您的图形也可以在脚本中调用以生成要作为单独文件嵌入到文档中的图形,然后您可以手动将其包含在模板中。

      例如(并且这个不是一个完整的.Rnw 文件,用于运行sweave)在一个 sweave 文件中,您可以将类似这样的内容放在模板中将执行分析并生成 R 对象的 R 脚本的主要部分:

      <<run_script, eval=TRUE, echo=FALSE, results=hide>>=
      source("my_script.R")
      @
      

      然后你需要在你想要打印输出的地方插入代码块:

      <<disp_output, eval=TRUE, echo=FALSE, results=verbatim>>=
      ## The results=verbatim is redundant as it is the default, as is eval=TRUE
      print(summary(x)) ## etc
      @
      

      然后你需要块来插入数字。

      将您的分析代码与输出(打印和/或图形)分开可能也是一种很好的做法,尤其是当分析代码在计算方面的成本很高时。您可以运行一次 - 甚至缓存它 - 同时根据需要更新输出/显示代码。

      示例 Sweave 文件

      使用 csgillespie 的示例 sweave 文件,我会像这样进行设置。首先是包含核心分析代码的my_script.R文件:

      x <- rnorm(100)
      y <- jitter(x)
      corXY <- cor(x,y)
      mod.lm <- lm(y~x)
      

      然后是 Sweave 文件

      \documentclass[12pt]{article}
      \usepackage{Sweave}
      \begin{document}
      
      An introduction
      <<run_analysis, eval=TRUE,echo=FALSE, results=hide>>=
      source("my_script.R")
      @
      
      % Later
      Here are the results of the analysis
      <<show_printed_output, echo=FALSE>>=
      summary(x))
      head(data.frame(x,y))
      @
      
      The correlation between \texttt{x} and \texttt{y} is:
      <<print_cor, echo=FALSE>>=
      corXY
      @
      
      Now a plot
      \begin{figure}[h]
          \centering
      <<echo=FALSE, eval=TRUE, fig=TRUE, width=6, height=4>>=
      plot(x,y)
      @ 
      \caption{\textit{A nice plot.}}
      \end{figure}
      
      \end{document}
      

      您似乎想要的东西并不存在;一种将 R 代码和输出组合成文档文件的简单方法。也就是说,如果您不认为 sweave 及其同类简单。您可能需要重新考虑要做什么或如何安排分析、图形和输出代码,但最好查看建议的选项之一(sweave、odfweave、brew、R2html)。

      HTH

      【讨论】:

        【解决方案3】:

        我鼓励您使用 Sweave,但使用 sink() 可以实现不美观的基本功能。

        一个普通的txt文件:

        sink(file = "test.txt", type = "output")
        summary(cars)
        sink()
        

        或添加一些 HTML 标签:

        sink(file = "tal_test.html", type = "output")
        cat("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"", "\n")
        cat("\"http://www.w3.org/TR/html4/strict.dtd\">", "\n")
                cat("<HTML>", "\n")
                cat("<HEAD>", "\n")
                cat("<TITLE>My first HTML document</TITLE>", "\n")
                cat("</HEAD>", "\n")
                cat("<BODY>", "\n")
                summary(cars)
                cat("</BODY>", "\n")
                cat("</HTML>", "\n")
        sink()
        

        【讨论】:

        • 如何自动包含图像?
        • @Jeromy 与数据 uri 方案,请参阅我的答案。
        【解决方案4】:

        大约一年前,我编写了一个名为 Roux 的脚本来执行此操作。我希望能够通过运行 R 脚本(包括任何图像)来创建 HTML 脚本,而无需更改脚本。

        您从命令行调用 Roux,如下所示: 肉酱的例子。R

        而 roux 将:

        • 在 R 中运行脚本(首先自动需要 Roux 包)
        • 语法高亮使用 Pygments 的 .Rout 输出
        • 在正确的位置插入图片

        Roux R 包是一个非常小的 R 包,它修改了 plot() 和其他一些函数以自动写入随机文件名而不是默认的交互式图形设备。

        我已经用过很多次了,它对我来说非常好用,虽然我敢肯定,如果更多的人将它与新软件包一起使用,那么就会出现一些小问题,很可能你会有一个不同的函数来生成图形和 Roux 不会知道它应该为您打开一个 PNG 设备。

        自从与 Tal 谈及此事后,我已经更新和改进了代码,现在在这里: http://bitbucket.org/ananelson/roux/src

        因此,如果您遇到任何问题,请将其报告给 Bitbucket 上的问题跟踪器。

        我添加了对 LaTeX 脚本的支持,因此您可以轻松创建包含 R 脚本脚本(包括图像)的 PDF。 (如果您查看示例输出目录,您可以看到一个示例,找到“原始”链接以下载它。)

        您确实需要安装 Python 和 Pygments python 库。如果您有旧版本的 Python 并遇到任何问题,请告诉我。

        我在我的博客上写了关于 Roux 的文章,但没有过多地宣传它,因为我的工作重点是一个名为 Dexy 的新项目,该项目旨在替代 Sweave。如果您想要更多的灵活性和控制力或对文字文档感兴趣,那么您可能也想查看 Dexy。

        【讨论】:

          【解决方案5】:

          您在问题中提到了sweave,但并不是真的为什么它不适合。您的问题似乎非常适合 Sweave。事实上,您的示例代码可能来自第二个 Sweave example

          Sweave 文件示例

          如果您了解 Latex,那么 Sweave 并不难。这是您作为 Sweave 文件的示例文件:

          \documentclass[12pt,BCOR3mm,DIV16]{scrreprt}
          \usepackage{Sweave}
          \begin{document}
          
          An introduction
          <<eval=TRUE,echo=TRUE>>=
          x <- rnorm(100)
          y <- jitter(x)
          print(summary(x))
          print(head(data.frame(x,y)))
          cor(x,y)
          @ 
          Now a plot
          \setkeys{Gin}{width=0.5\textwidth}
          \begin{figure}[h]
              \centering
          <<echo=FALSE, eval=TRUE, fig=TRUE, width=6, height=4>>=
          plot(x,y)
          @ 
          \caption{\textit{A nice plot.}}
          \end{figure}
          
          \end{document}
          

          在linux下,只需将文件保存为tmp.Rnw即可。那么

          R CMD Sweave tmp.Rnw
          pdflatex tmp.tex
          

          【讨论】:

          • 嗨 csgillespie,您提供的示例代码在代码 (stat.uni-muenchen.de/~leisch/Sweave/example-2.Snw) 中添加了很多“之前和之后”,包括我需要学习(一些)latex+编织。这是一天要做的事情,但我正在寻找是否有更简单的替代方案。
          • @Tal 我将添加到@csgillespie odfSweavebrew(可能不太灵活)。另请查看 Sweave 和 LaTeXj.mp/dah7Hr
          • @Tal 我想你总是可以编写一些代码(Python、Ruby 或其他)来将 R 输出存储在临时文件中,以及图像,以 BATCH 模式调用 R,然后编译所有这些插入临时文件后在 tex 文件中。实际上,这就是在 ConTeXt 文件中嵌入 R 代码所做的。
          • @Tal Huh,我浏览了您的 r2wd 示例:这太糟糕了(好吧,我从不使用 Micro$oft 工具,我的欣赏肯定是有偏见的)!我敢肯定有更好的方法来处理 Python 脚本和 tex/html 导出...只是呼吁其他响应...
          • 嗨,chl,我似乎已经找到了一个解决方案,可以按照您的描述进行操作!请看一下我刚刚发布的答案。最好的,塔尔
          【解决方案6】:

          还有 LyX,它有一个 Sweave 接口。 R / LyX / Sweave 接口代码位于 CRAN 上 http://cran.fhcrc.org/contrib/extra/lyx/。 LyX 本身存在于大多数 Linux 发行版中。所有这些魔法都可以在 Windows 上运行,但这绝对不是微不足道的。在 Windows 上,我建议使用 Blue Reference 中的 Inference for R 进行读写 R 编程。

          【讨论】:

            【解决方案7】:

            好吧,我只是提醒一下,我使用Asciidoc 进行简短报道或编辑网页。现在有一个R plugin(CRAN 上的ascii),它允许将 R 代码嵌入到 asciidoc 文档中。语法与 Markdown 或 Textile 非常相似,因此您将很快学会它。

            通过最后两个后端之一输出 (X)HTML、Docbook、LaTeX,当然还有 PDF。

            不幸的是,我认为您不能将所有代码包装到一个语句中。但是,它支持大量的 R 对象,见下文。

            > methods(ascii)
             [1] ascii.anova*              ascii.aov*                ascii.aovlist*            ascii.cast_df*           
             [5] ascii.character*          ascii.coxph*              ascii.CrossTable*         ascii.data.frame*        
             [9] ascii.default*            ascii.density*            ascii.describe*           ascii.describe.single*   
            [13] ascii.factor*             ascii.freqtable*          ascii.ftable*             ascii.glm*               
            [17] ascii.htest*              ascii.integer*            ascii.list*               ascii.lm*                
            [21] ascii.matrix*             ascii.meanscomp*          ascii.numeric*            ascii.packageDescription*
            [25] ascii.prcomp*             ascii.sessionInfo*        ascii.simple.list*        ascii.smooth.spline*     
            [29] ascii.summary.aov*        ascii.summary.aovlist*    ascii.summary.glm*        ascii.summary.lm*        
            [33] ascii.summary.prcomp*     ascii.summary.survfit*    ascii.summary.table*      ascii.survdiff*          
            [37] ascii.survfit*            ascii.table*              ascii.ts*                 ascii.zoo*               
            
               Non-visible functions are asterisked
            

            【讨论】:

              【解决方案8】:

              这是根据 romunov 的回答,但仍然如此。您可以编写自己的打印,以某种 HTML 格式包装输出并将输出嵌入到 HTML 文件中。对于带有Data URI scheme 的图片也可以这样做,例如使用base64 R 包中的img 函数。

              【讨论】:

              • 你好 mbq,你的意思是包装每一行代码,还是包装整个部分?
              • @Tal 而是一个自定义的printplot 格式化并重定向它们的输出到报告文件。 R 没有任何输出处理程序可以挂钩:-(
              • @mbq 这不是很接近R2HTML 实际所做的(或多或少)吗?
              • @chl 转换是一回事,捕捉输出(尤其是图像)是另一回事。 @Tal 再次 - 你不会找到它, print 和 plot 不能以任何足够低级的方式挂钩。
              • @mbq (+1) 是的,我同意。这就是为什么我最初建议依靠外部脚本语言以批处理模式调用 R 的原因;现在,如果我们寻找更简单的解决方案,我不知道该怎么做。
              【解决方案9】:

              您可以使用R2HTML 包将会话输出到 html,TeachingDemos 包中有一些类似的功能(请参阅txtStart)用于输出到增强的文本和单词(通过R2wd)。非图形命令将自动包含在文件中,并且可以通过单个命令插入当前绘图。

              【讨论】:

                【解决方案10】:

                通过 twitter 的奇迹,有人伸出手给我发了一个链接到this page,关于一个名为“roux”的包。它是在一年前创建的,我从未听说过它(显然你们大多数人都没有)。

                这个包似乎完全符合我在我的问题中寻找的东西,尽管安装似乎并不简单。

                我希望尝试这个解决方案,也希望看看其他 R 成员是否可能会加入这个项目以更好地增强 R。

                【讨论】:

                • 哦,我好像记得前段时间浏览过这个网站,但最终忘记了。它让我想起了 bm2.genes.nig.ac.jp 用于显示完整 R 输出的技术。让我们知道您是否可以设法只显示输出(文本+img)而不是 R 命令...
                • 嗨,chl,我已经联系了该插件的作者。我希望这可以实现(实际上更多)。更多(我希望)来...
                • 嗨,chl,关于您提供的链接,我忘记了。有趣的是,它并没有解决问题,因为他有所有的 ?sink 输出,然后是所有的 ?png 输出(我不确定他是否是这样实现的,但这就是结果)。这确实是升级此类网站的好主意。
                【解决方案11】:

                @znmeb 提出的尝试 Lyx 的好建议 - 一个更像单词的 LaTeX 前端,正如文档所指出的,this edition of R news 的第 2 页上有一篇关于它与 Sweave 一起使用的好文章

                这就是我在 Ubuntu 10.04 中按照lyx sweave repository 中的指导方针做的:

                sudo apt-get install lyx cd ~./lyx wget http://cran.fhcrc.org/contrib/extra/lyx/preferences 光盘布局 wget http://cran.fhcrc.org/contrib/extra/lyx/literate* wget http://cran.fhcrc.org/contrib/extra/lyx/literate-article.layout wget http://cran.fhcrc.org/contrib/extra/lyx/literate-book.layout wget http://cran.fhcrc.org/contrib/extra/lyx/literate-report.layout wget http://cran.fhcrc.org/contrib/extra/lyx/literate-scrap.inc cd ~/texmf/tex wget http://www.biostat.jhsph.edu/~rpeng/ENAR2009/Sweave.sty
                1. 启动 Lyx
                2. 首选项 -> 重新配置
                3. 重启 Lyx
                4. 文件 -> 新建
                5. 文档->设置->文档类->文章(Sweave noweb)

                有用的链接:

                【讨论】:

                  最近更新 更多