第16章 在工作中应用

    如果说我看得比别人远一些,那是因为我站在巨人的肩膀上。

— Isaac Newton, February 1676

16.1 自动完成业务报表

进入职场之后,有时需要定期完成一些业务汇报。比如,曾经有一份工作摆在我的面前,就是每个月制作一份Word格式的报告,内容是当月全国几十个观测站数据上传到服务器的情况。这份报告的格式是固定的,每次只需把里面的数据和图表更新即可。说来容易,可是每次都要有几十次的拷贝粘贴,非常容易出错,并且耗时耗力。

只恨当年未遇R。

在前几章,我们已经学会了用循环来解决重复工作,学会了对文件进行批量操作,并且学会了用R Markdown来制作Word文档。我们只需把这些本领结合起来,就完全可以让R来完成那些格式固定、只需更新内嵌的数据和图表的业务报告了。

这里,我们来举个例子。

我们仍然使用前面用过的世界各大洲7年的电话数量数据。假定我们需要把每年的情况写一份报告,内容是当年的全球电话数量总和,电话数量最多的洲及其所占比例,并用柱状图来展示。我们看看如何用R自动生成7份格式相同、内容不同的报告。

首先,我们用第7章的方法,建立一个R Markdown文档,作为7份报告的模板。方法是,在RStudio的界面点击菜单 File – New File – R Markdown,在对话框选择Document,将默认输出格式勾选Word即可。我们的文档内容如下:

---
title: "学城报告:全球电话数量"
author: "萨姆"
date: "`r Sys.time()`"
output: word_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r preprocess, echo=FALSE}
wp <- read.csv('c:/r4r/wp.csv')
i <- 1
year <- wp[i, 1]
wpi <- unlist(wp[i, 2:8])
conti <- c("北美", "欧", "亚", "南美", "大洋", "非", "中美")
```

## 数据

在`r year`年,全球电话总数为`r sum(wpi)`。拥有电话数量最多的是`r conti[which.max(wpi)] `洲,电话数量为`r max(wpi)`,占全球总数的`r paste(round(max(wpi)/sum(wpi), 4) * 100, "%", sep ="")`。

## 作图

下图是`r year`年全球各洲电话数量的柱状图。

```{r, echo=FALSE}
barplot(wpi, names.arg = conti)
```

我们来解释一下。这个模板文件可以分为三部分。第一部分是文件头,是新建这个文件时自动生成的,我们只是改了标题和作者等信息。第二部分是数据预处理(r preprocess),将数据读入,并把即将在文档中调用的数据(年份,电话数量,洲名等)准备好。这部分代码的参数echo设置为FALSE,意思是代码不在文档中显示。第三部分是文档的正文,凡是需要根据年份来更新的数据,包括全球电话总数、电话最多的洲名等,都用R Markdown调用R代码的方式来计算。

现在,我们按ctrl+s键,将这个模板文档保存为c:/r4r/rdoc.Rmd。再点击工具栏的Knit按钮,测试一下能否成功生成Word文档。

如果测试成功,我们就可以批量生产了。注意观察这个模板文件里,i <- 1,后面的数据就从wp数据框的第 i行选取,那么不同的文档我们只需更改i <- 1这一行即可。所以,我们 新建一个.r代码文件,敲入下面的代码:

rdoc <- readLines('c:/r4r/rdoc.Rmd', encoding = 'UTF-8')
for (k in 1:7) {
  newrmd <- paste('c:/r4r/', k, '.Rmd', sep = '')
  rdoc[13] <- paste('i <-', k)
  writeLines(rdoc, newrmd, useBytes = TRUE)
  rmarkdown::render(newrmd, encoding = 'UTF-8')
}

第一行是用读入文本文件的方法读入我们刚刚创建的rdoc.Rmd模板文档。从第二行起,开始循环,依次取不同的k值,将rdoc的第13行即i赋值为1的代码,改为赋值为k,然后将改变之后的文档新存为newrmd,最后用rmarkdown的render()函数将newrmd转换为同名的Word文档。

现在,我们来见证一下奇迹的诞生。运行上面的代码,一两秒钟后请来c:/r4r文件夹看看,7个Word报告是不是已经乖乖地等在那里了?

有了这种方法,我们就可以轻松地从无聊的重复劳动中解脱出来,把时间花在更有意义的事情上。那我们就用省出来的时间在R中玩玩扫雷吧!

Example 16.1 仿照批量制作Word报告的方法,将各大洲电话数量情况批量制作成幻灯片,每年一个文件,格式可以是ppt、html或pdf均可。

16.2 可重复研究报告

如果你是刚刚来到某个科研小组的新人,大概已经遭遇或将会遭遇以下情节:

  • 从导师那里得到师兄留下来的参考文献库。可是,你用的文献管理软件跟师兄的不同,光转格式就花了我大半天时间。

  • 师兄已经毕业了,留下的数据处理方法保存在一些专门的商业软件才能打开的文件里。如今,这些软件都升级多次,但导师却对初来乍到的你千叮咛万嘱咐:千万要用旧版软件,不然,师兄的文件就没法正确打开了。

  • 终于想方设法装上了旧版软件,打开师兄的文件一看,是个跟Excel类似的数据表,里边各列数据之间的计算错综复杂,花了两三天时间也没理出个头绪。

  • 那就看看师兄的学位论文里的公式吧,说不定有线索。论文是个Word文档,打开一看,不仅里面的公式都成了乱码,而且对应的数据也不知在哪里找得到。

这时,你大概会暗自嘀咕:这巨人的肩膀咋就这么难爬上去呢?是不是我在科研能力上有问题?

这不是你一个人的问题。虽然科研成果都写在发表的论文里,但很多情况下,实验数据、数据的处理方法、处理的结果这三个层面的内容在传播过程中是分离的。比如,我们在数据处理软件里计算和作图,然后把计算结果和图片拷贝粘贴到论文中发表。如果别人想重复我们发表的工作,就先得花大量时间弄清楚论文中每个公式的含义、公式适用的条件、各种前提假设等等,再回到数据处理软件中实现,这个过程给科研工作的交流带了障碍。

最近几年,学术界发生了几件涉及学术道德的事件,例如日本的小保方晴子事件,我国的韩春雨论文事件,他们的实验难以被同行重复,因此备受质疑,有人为此自杀,有人引咎辞职,无论圈里圈外的人都被惊动了。科研成果被他人使用,人类的科学才会承前启后发展。如果重复别人的方法存在诸多障碍,那么巨人的肩膀就无从谈起。

为了消除这种障碍,“可重复研究报告”这个概念出现了,并且在R语言里实现得相当顺利。R的knitr 、rmarkdown (Allaire et al. 2016)等扩展包,可以将数据处理方法和详细说明、论文结果、结论很方便的有机融合在一篇R文档里,而bookdown 、bookdownplus (Zhao 2017b)、blogdown (Xie 2017)、mindr (Zhao 2017c)、xlsx (Dragulescu 2014)、ReporteRs (Gohel 2017)等扩展包,可以将研究成果轻松输出为美观易用的期刊论文、技术档案、学术论文、书籍、网页、办公文档、思维导图等格式。只要有这样一份报告,同研究组的成员就很容易接手前人的工作;只要换上自己的数据,就会得到自己的新结果,从而来证实前人方法的可重复性。

R的科研一条龙整体解决方案.

图 16.1: R的科研一条龙整体解决方案.

这样,R语言就给我们提供了“科研一条龙”的打包解决方案。在这个方案里,除了原始数据外,其他的所有资料,包括数据处理方法、公式、参考文献等,全部是以纯文本的形式保存的,不对任何软件产生依赖。即使学生毕业、教授退休,即使软件升级,哪怕将来R语言不存在了,哪怕RStudio公司倒闭了,但我们的一切资料都可以用最简单的记事本软件打开阅读,为科研工作的前后相继提供了最大的便利。

R语言,把巨人的肩膀改造成了容易攀登的阶梯。

16.3 课外活动:学以致用

学以致用效果好,以赛代练效率高。

对你自己在学习或工作里用到的数据进行分析,用R markdown 写一份可重复性研究报告。

然后,用 rmarkdown 或 ReporteRs 扩展包,将上述研究报告以幻灯片的形式展示。

References

Allaire, JJ, Joe Cheng, Yihui Xie, Jonathan McPherson, Winston Chang, Jeff Allen, Hadley Wickham, Aron Atkins, and Rob Hyndman. 2016. Rmarkdown: Dynamic Documents for R. https://CRAN.R-project.org/package=rmarkdown.

Zhao, Peng. 2017b. Bookdownplus: Generate Varied Types of Books and Documents with R ’Bookdown’ Package. https://CRAN.R-project.org/package=bookdownplus.

Xie, Yihui. 2017. Blogdown: Create Blogs and Websites with R Markdown. https://github.com/rstudio/blogdown.

Zhao, Peng. 2017c. Mindr: Convert Files Between Markdown or Rmarkdown Files and Mindmaps. https://CRAN.R-project.org/package=mindr.

Dragulescu, Adrian A. 2014. Xlsx: Read, Write, Format Excel 2007 and Excel 97/2000/Xp/2003 Files. https://CRAN.R-project.org/package=xlsx.

Gohel, David. 2017. ReporteRs: Microsoft Word and Powerpoint Documents Generation. https://CRAN.R-project.org/package=ReporteRs.