用R markdown & bookdown生成深度分析报告

Jean

刚翻译好<a href="http://jeanye.cn/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《精通Shiny》</a>一书(<a href="https://mastering-shiny.org/index.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>在线英文版</a>),它是用<a href="https://cran.r-project.org/web/packages/bookdown/index.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>bookdown</a>包写的,这是对<a href="https://cran.r-project.org/web/packages/rmarkdown/index.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>rmarkdown</a>包的扩展。作者<a href="https://bookdown.org/yihui/rmarkdown/yihui-xie.html#yihui-xie" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>谢益辉</a>是Rstudio的工程师,主要的研究方向是统计计算与交互式统计图,与J. J. Allaire及Garrett Grolemund合著有<a href="https://www.routledge.com/R-Markdown-The-Definitive-Guide/Xie-Allaire-Grolemund/p/book/9781138359338" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《R Markdown: The Definitive Guide》</a>一书(<a href="https://bookdown.org/yihui/rmarkdown/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>开源在线版</a>,中文版<a href="https://github.com/cosname/rmarkdown-guide" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《R Markdown 权威指南》</a>正在写作之中,预计于2023年出版)。之前已经介绍过J. J. Allaire与François Chollet合著的书<a href="https://www.manning.com/books/deep-learning-with-r-second-edition" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《Deep Learning with R》</a>,J. J. Allaire是<a href="https://www.rstudio.com/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>Rstudio</a>的创始人与CEO,<a href="https://yihui.org/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>谢益辉</a>则创建了网站<a href="https://cosx.org/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>统计之都</a>并在中国推广R语言平台的相关技术和活动。<div>因为<a href="https://www.oreilly.com/library/view/mastering-shiny/9781492047377/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《Mastering Shiny》</a>的作者<a href="https://github.com/hadley" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>Hadley Wickham</a>(Rstudio首席科学家)询问能否把译本转换为R markdown脚本,以便把译本转换为网站与网页,尝试了解一下R markdown。这是一种编著语言系统,提供了动态的格式报告:给定参数,运行程序,根据模板生成word、pdf、html等固定格式的报告(<a href="https://mastering-shiny.org/action-transfer.html#downloading-reports" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>简单例子</a>)。同时也通过<a href="https://cran.r-project.org/web/packages/knitr/index.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>knitr</a>包支持<a href="https://bookdown.org/yihui/rmarkdown/language-engines.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>Python等多种语言</a>。所以它的功能类似于Python平台的<a href="https://jupyter-notebook.readthedocs.io/en/stable/notebook.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>Jupyter Notebook</a>,不过功能更强大,比如通过R语言在后台运行Shiny App并合并其输出到报告中。其实我更感的兴趣是,了解这样的一种编著系统,以在大数据应用中根据模板与参数动态的生成深度分析报告——《Mastering Shiny》(<a href="https://github.com/hadley/mastering-shiny" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>项目源码</a>)一书本身就可以看成是这样的一篇报告,虽然没有使用动态的参数。基本上搞数据分析的人都要写分析报告,这在各种实际应用场景中还是比较有用的,比如每月、每季自动生成一些深度分析报告。因为基于程序,背后有整个R语言或Python语言等数据科学平台的支持,它能做任何你能想象的深度分析。</div><div>本篇以《Mastering Shiny》一书的<a href="https://github.com/hadley/mastering-shiny" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>项目源码</a>为例,把项目的第1章<a href="https://github.com/hadley/mastering-shiny/blob/main/basic-app.Rmd" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《Your First Shiny App》</a>翻译为中文,并在Windows与Linux平台上输出它的html、word、pdf渲染结果,来了解R markdown这个流行的编著体系。</div><div>一、建立项目环境</div><div>1、下载项目源码</div><div>在<a href="https://github.com/hadley/mastering-shiny" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>项目主页</a>上按“Code”按钮,选“Download Zip”下载压缩文件解压即可。</div><div>2、安装项目依赖的包<br></div><div>install.packages(c(<br> "gapminder", "ggforce", "gh", "globals", "openintro", "profvis", <br> "RSQLite", "shiny", "shinycssloaders", "shinyFeedback", <br> "shinythemes", "testthat", "thematic", "tidyverse", "vroom", <br> "waiter", "xml2", "zeallot" <br>))<br></div><div>3、导入项目<br></div><div>Rstudio菜单上选择File->Open Project,选择上面解压的源码目录到有.Rproj项目描述文件的一级,并选择该项目文件打开。这时getwd()返回的工作目录就是该目录。</div><div>4、修正项目bug<br></div><div>有两个小bug,第一个可能是软件包版本变化引起的问题,书中列出了当时使用的包版本,而上面安装的是最新的版本。</div><div>1)common.R</div><div>把最后修饰错误信息的registerS3method()与error_wrap()函数注释掉,否则build整个项目时会出错,因为registerS3method()运行出错了。</div><div>2)basic-case-study.Rmd中第79行下载neiss的URL,因项目源码结构的改变,其中/raw/master/neiss/要改成/raw/main/neiss/。</div><div>5、build项目测试<br></div><div>这时可以在Rstudio菜单上选择Build->Build All来试着执行所有章节的Rmd脚本渲染生成各章节的html、word文件了。然后会看到在执行到basic-reactivity.Rmd的184-190行时中断了,因为它需要向shinyapps.io部署一个Shiny App,需要有它的API账号。</div> 6、连接shinyapps.io<br>到shinyapps.io上注册一个账号,我是直接用github的账号登录的。然后创建访问shinyapps.io的API令牌和密码。选择Account->Tokens->Add Token。 拷贝token和secret,在Rstudio Console中运行一次下面的语句:<div>library(rsconnect)<br>setAccountInfo(name='your account name', token='your token', secret='your secret')<br></div><div>这样Rstudio->Tools->Global Options->Publishing中就会记住你的发布账号,以后就会自动引用。</div><div>现在,在Build菜单下选择Clear All清空上次Build的痕迹,然后重新运行Build All。</div> 然后还是会在action-graphics.Rmd被中断执行,build的错误信息是部署的Shiny App数量超出了上限: shinyapps.io上显示这时一共部署了5个App,这应该是免费账号的上限。如果要build完整本书,那就要注册一个付费账号了。 7、单独执行一个Rmd渲染<div>现在先清空shinyapps.io上部署的App。点击每个App后面的Archive按钮归档,然后再点击Delete按删除,必须先归档,然后才可以删除。<br><div><br></div></div> 然后单独执行下面的命令渲染action-graphics.Rmd:<div>rmarkdown::render('action-graphics.Rmd','word_document',output_dir = "./docx")<br></div> 该脚本只部署了3个App,可以看到顺利的执行完了。该Rmd脚本把程序、Shiny App输出的图表与文字叙述合并到一起,这是典型的数据分析报告形式。 逐章翻译的时候可以逐章渲染,不过有一个小问题是里面章节的序数及相互之间交叉引用等bookdown扩展标签,在逐章渲染时没有执行,它们在整个项目build时才会执行,这是需要注意的,现在可以先不管它。<div>执行下面的命令渲染输出html文件:</div><div>rmarkdown::render('action-graphics.Rmd','html_document',output_dir = "./docx")<br></div> 渲染输出pdf文件要做一些安装配置,后面再详细介绍。 二、翻译basic-app.Rmd<div>1、翻译<br><div>因为书已经翻译好了,翻译Rmd源码脚本的工作是很直接的,就是把译稿里的<a href="http://jeanye.cn/mastering-shiny/chapter01.docx" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>译文</a>,逐段逐句替换掉<a href="https://github.com/hadley/mastering-shiny/blob/main/basic-app.Rmd" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>Rmd源码</a>里的英文,主要的工作量在于大量起格式化作用的R markdown及bookdown标签的处理,因为要保留这些标签以保留原格式,这比翻译的工作量都要大,整整搞了1天。这是翻译好的脚本,另存为<a href="http://jeanye.cn/mastering-shiny/scripts/basic-app-zh.Rmd" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>basic-app-zh.Rmd</a>。执行下面的命令渲染输出word文件:</div><div>rmarkdown::render('basic-app-zh.Rmd','html_document',output_dir = "./docx")<br></div></div> 2、Word格式输出 上图可以看到书中的脚注显示在页面底部,在横线以下。下图可以看到该脚本合并了整个Shiny App的运行界面(然而渲染时并没有显示界面窗口,它是在后台运行的): <div>3、本地运行</div>可以看看后台运行在Rmd脚本中的实现:<div>```</div><div>{r basic-server, echo = FALSE, out.width = "75%", fig.cap = "现在我们提供了连接输出和输入的服务器函数,我们有了一个功能齐全的应用程序", message = FALSE}<br>demo <- demoApp$new("basic-app/server", ui, server)<br>demo$takeScreenshot()<br>```<br></div><div>通过新建一个demoApp对象在后台运行它{r basic-server, echo = FALSE},然后调用它的takeScreenshot()函数截取它应该显示的界面。所以这个App运行在本机的R进程中,不需要发布到shinyapps.io等服务器上。渲染结果会显示界面截图而不是上面的脚本程序。</div> R6Class对象demoApp在<a href="https://github.com/hadley/mastering-shiny/blob/main/demo.R" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>demo.R</a>中定义,它在basic-app-zh.Rmd的开始处加载:<div>```{r, include = FALSE}<br>source("common.R")<br>source("demo.R")<br>```<br></div> <div><br></div> 4、shinyapps.io服务器上部署运行<div>作为比较,看看前面提到的<a href="https://github.com/hadley/mastering-shiny/blob/main/action-graphics.Rmd" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>acttion-graphics.Rmd</a>中是怎样把Shiny App部署到shinyapps.io上并截图的,它同样也是后台运行,没有显示界面。</div><div>```{r puppies, echo = FALSE, message = FALSE, fig.cap = demo$caption("An app that displays cute pictures of puppies using `renderImage()`."), out.width = "50%"}<br>demo <- demoApp$new("action-graphics/puppies", ui, server, assets = "puppy-photos")<br>demo$takeScreenshot("corgi")<br>demo$setInputs(id = "KCdYn0xu2fU")<br>demo$takeScreenshot("lab")<br>demo$deploy()<br>```<br></div><div>嗯,通过调用demoApp对象的deploy()函数实现。</div> 渲染效果如下: 有关后台运行Shiny App的详细说明,可以参阅《Mastering Shiny》一书的<a href="https://mastering-shiny.org/scaling-testing.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《Testing》</a>一章(<a href="http://jeanye.cn/mastering-shiny/chapter21.docx" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>中文译文</a>)。 5、html格式输出<div>执行下面的语句输出html格式文件:</div><div>rmarkdown::render('basic-app-zh.Rmd','html_document',output_dir = "./docx")<br></div> 注意它的脚注集中显示在页面的底部,与Word格式不同。 6、pdf中文支持<br>为支持中文渲染输出为pdf,Rmd脚本的开头处增加了以下的YAML定义,详细安装配置后面再介绍:<br>---<br>header-includes:<br>- \usepackage{ctex}<br>output:<br>pdf_document:<br>latex_engine: xelatex<br>---<div>执行下面的命令渲染输出pdf文件:</div><div>rmarkdown::render('basic-app-zh.Rmd','pdf_document',output_dir = "./docx")<br></div> 7、直接输出结果的代码<br>上面运行交互式Shiny App的R markdown界面截图代码稍为有点复杂,那是比较特殊的情况,因为交互式Shiny App需要一个UI界面以接受交互式输入,所以通过demoApp对象作特殊处理,不显示UI界面以在后台运行(可以通过Shiny App的session对象由程序根据R markdown脚本传入的参数设定App的输入来模拟人机交互,上面的例子中demoApp对象提供了函数setInputs()直接实现:demo$setInputs(id = "KCdYn0xu2fU"))。一般的代码就可以直接合并输出,比如<a href="https://github.com/hadley/mastering-shiny/blob/main/introduction.Rmd" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i> introduction.Rmd</a>中最后列出软件包版本的一段,与<a href="https://jupyter-notebook.readthedocs.io/en/stable/notebook.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>Jupyter Notebook</a>的用法相似: <div>执行下面的语句渲染输出html文件:</div><div>rmarkdown::render('introduction.Rmd','html_document',output_dir = "./docx")<br></div><div>渲染结果如下:<br></div> 8、不运行的代码<div>对于渲染时只显示而不运行的代码,通过以下格式来定义:</div><div>{r, = FALSE}<br></div> <div>三、Windows上渲染pdf安装配置<br></div><div>Rmd脚本渲染输出pdf需要TeX和LaTeX系统。<br><div><a href="https://www.latex-project.org/get/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>LaTeX</a> 是<a href="https://www.tug.org/texlive/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>TeX</a>的封装,主要的设计目标是分离内容与格式,以便作者能专注于内容创作而非版式设计,LaTeX 使用 TeX作为它的排版(格式)引擎,R markdown通过<a href="https://yihui.org/tinytex/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>tinytex</a>包使用LaTeX,渲染pdf时把Rmd脚本编译为TeX脚本并执行,所以需要先安装配置它们。它非常适用于生成高印刷质量的科技类和数学类文档。它也能够生成所有其他种类的文档,小到简单的信件,大到完整的书籍。</div><div>可以参阅<a href="https://www.ctan.org/starter" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>这个文档</a>来开始了解各操作系统平台上的安装。参阅中文的<a href="https://ctan.math.illinois.edu/info/lshort/chinese/lshort-zh-cn.pdf" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>LaTeX简介</a>与<a href="https://www.tug.org/texlive/doc/texlive-zh-cn/texlive-zh-cn.pdf" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>texlive指南</a>。<a href="https://www.tug.org/texlive/distro.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>texlive各操作系统安装版</a>可以从这里下载。</div><div><div>1、安装MiKTeX</div><div>MiKTeX是Windows上比较流行的TeX发行版,安装配置简单,可以从这里<a href="https://miktex.org/download" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>下载</a>,安装说明参阅该<a href="https://miktex.org/howto/install-miktex" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档</a>,按向导执行即可。它的安装文件与安装目录大概需要1G。需要注意安装后的两个设置:</div><div>1)在系统环境变量path中加入xelatex.exe等可执行文件的安装路径,后面将使用xelatex引擎来处理中文。</div></div></div> 2)打开MiKTeX Console,更改宏包安装选项为“总是”自动安装缺失的宏包,否则使用支持中文的ctex宏包时找不到,会出错提示"GUI framework cannot be initialized",参阅该<a href="https://github.com/seebk/LaTeXText/issues/31" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>Issue文档</a>。 2、中文的处理<div>1)测试MiKTeX</div><div>新建一个utf8编码文本文件test.tex如下:</div> 2)在命令行窗口中运行xelatex test.tex生成pdf,第一次运行时需要的时间要长一点,因为要连线下载ctex相关的包: 3)查看生成的pdf,测试通过,安装成功。看到上面最后输出:Output written on test.pdf (1 page)就表示成功生成了pdf文件。 4)测试rmarkdown。在Rstudio中建立一个utf8编码的Rmd文件,然后用rmarkdown::render()函数直接渲染它,如图所示。注意测试用例的写法与上面例子的不同,在Rmd脚本的头部,定义了使用ctex宏包来处理中文,然后用xelatex引擎处理,它比pdflatex引擎更适合处理unicode字符集。具体可以参阅该<a href="https://github.com/yufree/democode/tree/master/cjk" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档</a>,那里有各种中日韩字符处理的例子。 5)查看输出的pdf文件,测试通过。 四、Linux上渲染pdf安装配置<div>Linux平台上比较流行的TeX发行版是<a href="https://www.tug.org/texlive/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>texlive</a>,我在云端虚拟主机上装的是CentOS 7.6,它所带的texlive版本比较旧,没有处理中文的ctex等宏包(参阅<a href="http://t.zoukankan.com/raisok-p-12094705.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档</a>),因此下载最新的texlive-2022镜像安装完整的版本,参阅<a href="https://zhuanlan.zhihu.com/p/297891593" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档</a>及<a href="https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/Images/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>清华大学最新镜像地址</a>。镜像文件大约4.3G,安装另需6.8G。<br><div>1、安装texlive</div><div>如果安装了老版本的texlive,要先删除干净,参阅<a href="http://t.zoukankan.com/raisok-p-12094705.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档</a>与<a href="https://github.com/rstudio/docker-r-session-complete/issues/64" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档2</a>。</div><div># yum erase texlive\*.*</div><div>下载:</div><div># cd /root</div><div># wget https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/Images/texlive2022-20220321.iso</div><div>挂载:</div><div># mount -o loop texlive2022-20220321.iso /mnt/</div><div>安装:</div><div># cd /mnt</div><div># ./install-tl</div><div>输出环境变量:</div><div># vi /etc/profile</div><div># Added for texlive</div><div>export MANPATH=${MANPATH}:/usr/local/texlive/2022/texmf-dist/doc/man<br>export INFOPATH=${INFOPATH}:/usr/local/texlive/2022/texmf-dist/doc/info<br>export PATH=${PATH}:/usr/local/texlive/2022/bin/x86_64-linux:/usr/lib/rstudio-server/bin/pandoc<br></div><div>重启系统或source激活环境变量。</div><div># source /etc/profile</div><div>卸载镜像:</div><div># umount /mnt/</div><div><br></div><div>2、测试安装</div></div><div>1)测试texlive安装。测试用例test.tex同Windows平台,命令行输出要详细一点,生成的pdf是一样的。</div> 2)在Rstudio中测试rmarkdown,注意/etc/profile中设置的texlive环境变量不会带入Rstudio Linux Server的 R session中,需要在Renviron配置文件中加进去,主要是PATH变量,具体可以参阅<a href="https://github.com/rstudio/rstudio/issues/1878" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档1</a>和<a href="https://www.anycodings.com/1questions/2281129/rstudio-shows-a-different-path-variable" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文档2</a>。<div># which R</div><div>/usr/lib64/R-4.1.2/bin/R<br></div><div># cd /usr/lib64/R-4.1.2/lib64/R/etc</div><div># ls</div><div>javaconf ldpaths Makeconf Renviron repositories<br></div><div># vi Renviron</div><div># Added by Jean for texlive 2022/09/15<br>PATH=${PATH}:/usr/local/texlive/2022/bin/x86_64-linux<br></div><div>然后重启Rstudio Linux Server以使路径生效:</div><div># cd /usr/sbin</div><div># ./rstudio-server stop&</div><div># ./rstudio-server start&<br></div> 在Rstudio Console窗口中,可以用Sys.getenv("PATH")查看路径设置是否已经生效,然后运行下面的命令来测试pdf渲染:<div>rmarkdown::render('~/testPDF.Rmd','pdf_document',output_dir = "~/")<br></div><div>测试用例testPDF.Rmd与Windows平台相同,生成的pdf文件也相同。</div> 五、小结<div><a href="https://www.routledge.com/R-Markdown-The-Definitive-Guide/Xie-Allaire-Grolemund/p/book/9781138359338" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《R Markdown: The Definitive Guide》</a>的作者<a href="https://github.com/yihui" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>谢益辉</a>开发或参与开发了knitr、rmarkdown、bookdown等R markdown编著体系的主要R包,他将这种叙述、程序与结果混合的编程模式称为<a href="https://github.com/cosname/rmarkdown-guide/blob/master/01-intro.Rmd" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>文学化编程</a>(由高德纳[Donald E. Knuth,TeX系统的开发者。]在 1984 年提出),与传统的结构化编程及Shiny的反应式编程都很不一样。后两种编程模式,人们在代码中写少量的注解,然后另外写完整的文档,这对于读者很少的专业编程来说,是最清晰高效的。在文学化编程模式下,人们边想、边描述、边解释,然后附上程序、附上运行结果。读者既看文章,也看代码和结果,看的过程就是思考的过程,更接近于人们日常的思考与行为模式,这对于数量众多的非专业编程读者来说是最容易理解最有效的。显然更适合于写数据分析报告及学术论文等图文并茂,需要大量文字充分论述说明的东西。<br></div><div><a href="https://mastering-shiny.org/preface.html" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《Mastering Shiny》</a>一书的R markdown<a href="https://github.com/hadley/mastering-shiny" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>源码</a>,是了解学习R markdown编著体系的一个不错的例子。IT领域有learn by example的传统,通过本篇翻译第一章Rmd脚本的例子,已经了解到该体系的大致框架,这是一个知识体系相当丰富的新领域。在一周的工作日内完成,已经很满意了。这只是一个开始,重要的是它跑通了!深入的了解和应用,还是要把上面R markdown的两本书慢慢读透。</div><div>最后,引用J.J. Allaire在2016年的专访<a href="https://cosx.org/2016/11/interview-j-j-allaire/" target="_blank" class="link"><i class="iconfont icon-iconfontlink"> </i>《RStudio 的前世今生》</a>中的一段话来结束本篇,我觉得对深度分析来说是言之有理的。一家之言,仅作参考:</div><div>可重复性是我们专注于教人们如何编写和使用代码进行数据分析的原因之一。我们没有投入精力开发数据分析的图形界面工具,因为基于图形界面的操作不可重现,不容易检查,不容易共享,也不容易自动化。我们专注于代码。这是一个核心原则,无论如何,我们宁愿让代码更容易运行,而不是试图消除它。<br></div>