附录一:现代科研兵刃谱

工欲善其事,必先利其器。今天绝大多数知识都是工具生产出来的,也就是想使用知识,肯定要先学工具,而工具又需要知识铺垫,这就成了一个鸡生蛋蛋生鸡的问题。虽然事后总结都有千般道理,但就我人经验而言,工具与知识是相辅相成缺一不可的,过于关注知识会导致脱离实际而沉迷于工具选择则有很高的迁移成本。这里的忠告就是不要想太多,先迈开步子,遵循梯度下降算法来寻优。也就是说,随便找个工具用起来,用实战来丰富需求,根据需求定向选择最适合自己的工具而不做工具的奴隶,如有必要,自己创造工具。另外,尽量选择那些花费百分之二十的精力可以掌握百分之八十的内容或应用场景的工具。同时系统学习那些使用频率高的工具,其余的只要知道其存在即可,不要捡芝麻丢西瓜。

文本编辑

科研用文本编辑工具主要应对排版要求,早期排版系统基本都是通过 TeX 语言来实现的,后来由于个人电脑普及及新兴学科的出现,很多科研人员上手会用的都是可见即可得的文本编辑器。现在期刊投稿一般会支持基于 TeX 的投稿及常见可见即可得文档,这些都是本地编辑。另一个当前流行的可见即可得文本编辑方式是在线协作,例如谷歌文档石墨文档腾讯文档等。对于需要协作完成的论文,在线协作文档极大方便了实时交互与版本控制。其实利用基于Git的GitHub也可以实现在线协作与修订,不过门槛比较高,但有希望成为一些期刊今后的投稿系统原型。例如 Authorea 就集成了在线协作、支持markdown、文献管理、数据分析、托管、版本控制、投稿等一系列功能,有希望成为下一代文本编辑工具,价格并不便宜但好于传统办公软件。数据分析环境容器化与项目化正在成为一种流行趋势。部署数据分析环境是很头疼的事,各类包依赖、软件版本混杂与系统平台大大阻碍了分析效率。目前有两个分支解决方案,一种是通过云计算或集群计算平台来实现在线数据分析,目前 R Cloud 与 RStudio 内测的RStudio Cloud就是代表;另一种则是对软件配置环境进行打包,确保本地部署的一致性,这条路需要容器化技术作为依托,docker 差不多是目前最流行的轻量容器化技术。目前市面上已经有针对Jupyter notebooks的Binder,可以直接将一个Github 仓库打包成 docker 镜像然后一键部署到JupyterHub上,也可以通过stencila本地创作后在线部署。R社区也有rocker镜像或liftr包来实现分析环境的快速部署。当然单纯分析脚本是不够的,数据也应该可以打包或链接并方便分享,目前支持此功能的此类产品是CodeOcean,容器叫做胶囊,里面可以打包脚本、数据及生成docker镜像的配置文件,而且也有期刊支持胶囊与论文的同步发表了,但目前版本控制功能还没有,无论如何研究中的可重复性危机有望基于技术来减弱。

还有些文本编辑器是基于纯文本的,通过文本中的控制语句来实现排版,TeX就是其中最流行的。Overleaf支持基于 TeX 的在线文档协作,甚至你可以直接用其向特定期刊投稿,同样的工具还有sharelatex。不过,TeX的控制语句实在太丰富,学习起来比较困难。Pandoc 的出现方便了其他更简单的标记语言对 Tex 的转换,其中最容易上手的是Markdown。不过 Markdown 存在很多版本,其中基础版支持的排版功能非常有限,Pandoc 对其进行的扩展则支持了更丰富的功能方便排版。所以理论上你可以使用 Markdown 来写论文,不过这需要你的编辑器支持一些额外的功能。

总结一下,作为现代科研工具,理想文本编辑器需要至少有以下功能:

  • 支持在线协作、评论与修订
  • 支持版本控制
  • 支持常见文献管理工具
  • 支持期刊样式排版
  • 容易上手

文献管理

现在的文献管理工具一般都支持常见文本编辑工具,也就是可以很方便的插入参考文献。然而,文献管理工具要同时具有收集、整理与分析的功能为佳。当前主流文献管理工具都已经支持浏览器层次的文献收集,也就是直接通过快捷键、脚本或浏览器扩展一键自动提取文章页面中参考文献信息并存入用户指定的文献库。要实现这个功能,多数需要知道文献数据库网页结构,当前很多文献数据库都推出了自己的文献收集应用,有的直接收购了文献管理软件。

Endnote是比较老牌的文献管理工具,不同于前面所说的网页采集,其自身就有与常见数据库的搜索接口,国内科研机构图书馆大都提供培训。与之类似的NoteExpress则属于国产软件,据说对中文期刊格式支持更好,类似的还有Mendeley医学文献王、服务 TeX 里 BibTex 的 JabRef 与Mac OS 下的Papers。这些工具起步较早,从单机时代就有用户,还有些工具诞生于互联网时代,有着更丰富的功能。

Zotero 属于互联网精神的产物,特别是前者本身就是基于火狐浏览器,其支持的文献格式样式都非常多,而且也有着丰富的文本分析扩展应用。Paperpile则属于基于谷歌文档的应用,可以很方便地管理在谷歌文档中使用到的文献。DOIcrossref的出现则更方便了文献的搜索定位。可以说基于互联网的团队化文献管理正在成为趋势。

如果需要文献信息学方面的研究,CiteSpace 功能比较全,如果需要文本分析,可以利用 R 语言中的自然语言处理包来进行。

总结一下,作为现代科研工具,理想文献管理软件需要至少有以下功能:

  • 支持常见文本编辑器
  • 支持在线文献采集
  • 支持文献库协作与共享
  • 支持文献信息学探索
  • 容易上手

数据处理与绘图

数据处理方面很多学科只需要电子表格与基本的统计分析就可以了,很多在线服务就可以完成。然而,有些学科需要更丰富的功能例如多元统计分析与假设检验时,电子表格提供的功能可能就不那么明显了,有时需要学习使用电子表格的宏扩展来实现。此时,很多人容易陷入哪个分析一定要用哪个软件做的误区,其实多数数据分析软件的算法都差不多,只不过默认值可能不同,有些功能则藏的比较深,此时请善用搜索引擎。

所见即所得的数据处理与绘图软件有很多,Excel、OriginSigmaPlotSPSS 是科研中用的比较多的。这些软件都是图形界面操作且都收费,其内置很多现成的分析模块应对实际科研问题,但这些简化会导致使用者知其然不知其所以然,在分析方法使用上陷入误区。

编程分析与绘图则属于基础的工具,RPythonMatlabSAS 都是这类工具的代表,应该说掌握其中任意一个就足够应对科研中需要的数据分析了。不过通常这类工具比较难学,最好是配合数据分析方法的学习同步掌握,而且要通过案例来理解方法,累积经验。如果推荐一个,那么基于 R 的 ggplot2 作图与其背后的 tidyverse 数据分析套装则是很好的起点。如果更进一步,可以用shiny 来制作交互式数据展示界面。

此外,互联网上也有一些在线应用可以很方便地生成特殊图形例如百度脑图可以用来生成流程图或思维导图、Autodraw可以用来画简笔画、plotly可以在线完成绘图等。甚至网上还有直接上传数据后自动猜测你需要进行分析与制图的Charted。这样的工具只要搜索你所需要的分析然后加上“online”作为关键词就可以找到。

总结一下,作为现代科研工具,理想数据分析与绘图软件至少有以下功能:

  • 支持科研用统计分析
  • 图片默认输出美观大方支持绘图自定义
  • 具备可重复性的宏功能或数据处理脚本
  • 容易上手

数据同步

科研数据在不涉密情况下一定要备份,实验室要配备专用数据处理电脑,用NAS来进行本地备份,每个项目有独立文件夹结构化管理。工作文件夹原则上在实验室电脑上,通过远程登录软件例如 TeamViewer 或终端来处理数据。如果使用个人电脑,工作文件夹要做好云存储,国内的话iCloudOneDrive坚果云就可以,国外可选DropBox谷歌云端硬盘。文献可以通过坚果云的 Webdev 来同步全文。完成的项目要及时存档备份,可使用百度网盘

实验室管理

实验室内部管理可使用slack或国内的钉钉,最好区别工作与私人的交流工具。项目管理可以直接用GitHub项目功能来做,分为计划、进行中与完成三部分,每次组会进行更新。

幻灯片制作

幻灯片制作的工具不仅仅限于微软出品的PowerPoint(ppt)或苹果公司出品的 keynote,但不可否认的是可见即所得的工具对于幻灯片的制作是很方便的。基于 Beamer 的幻灯片虽然足够简洁美观,但也存在一定的制作难度,需要学习 TeX。基于 html5 技术的幻灯片一般支持 markdown 语法编辑,样式可用 CSS 模版进行控制。例如 xaringan 就是基于remark.js 这一网页幻灯片制作工具配合Rmarkdown来制作幻灯片的。不过,幻灯片制作不要沉迷于模版选择,只要不出错就够了,太花哨的功能喧宾夺主。不过从互动角度出发一些挂件例如countdown 来进行倒计时, DirectPoll 进行实时投票统计,也可以同时开视频或进行语音输入

同样,谷歌幻灯片可以实现在线制作幻灯片。很多网站可以直接制作网页版幻灯片,例如基于reveal.jsslides 或基于有漂亮切换类似prezimpress.jsstrut。在线制作幻灯片可以让分享变得很容易并提高了曝光度,很多网站例如slideshareSpeaker Deck 也支持上传本地幻灯片进行分享。

建议日常计划用幻灯片进行总结,图片达到会议级别。

作为现代科研工具,理想幻灯片制作软件至少有以下功能:

  • 简洁的编辑制作页面
  • 模版简洁可自定义
  • 可在线分享

学术交流

学术交流是科研生活中可以说最重要的一环,现代科研体系的分工合作都要通过学术交流来实现。主流趋势包括论文预印本服务器、开放获取与线上学术交流。

预印本指在通过同行评议发表之前事先将论文手稿托管在公开服务器的研究工作。预印本服务器可以加速新思想的交流,接受预印本发表的期刊可以从维基百科上查到。比较知名的预印本服务器包括偏数学物理计算机科学的arxiv、偏生命科学的biorxiv 与偏化学的chemrxiv。国内也有中科院的科技论文预发布平台来服务国内科研人员。很多期刊出版方也在推广自己的预印本服务器来吸引高水平研究,所以可酌情选择。

开放获取是另一个趋势,要求研究工作可以公开让大众阅读。目前很多科研基金都开始有了这方面的要求及预算。但值得注意的是虽然开放获取期刊可能有更好的阅读数与引用表现,但有很多机构的开放获取期刊属于掠夺性期刊,给钱就发表,对学术评价与学科发展非常不利,可以通过一些网络上的列表来鉴别或选择。要实现开放获取或者说透明科研,f1000researchPeerJ还有Plos都是还不错的先行者,它们在实践一些新理念,不过显然并不便宜。

线上学术交流除了期刊外,实际还要包括学术博客、多媒体展示、学术出版与网络身份。制作学术博客的工具可以直接借助平台例如科学网博客,也可以自己搭建例如使用WordpressBlogdown或者Netlify等工具。幻灯片制作也最好使用网页模式方便交流,xaringanlearnr等其他基于Markdown语言的幻灯片制作工具可以满足要求。学术出版物则可以通过bookdownrticles等工具来完成。线上的学术身份识别对于存在大量重名现象的中国科研人员也是很有必要的,ORCIDResearcher IDScopus Auther ID谷歌学术个人主页及国内的百度学术个人主页都是不错的网上学术名片。在线出版可以考虑leanpub/gitbook/amazon kindle direct publishing或者按需求出版纸质版的 lulu.com。而在线交流的手段则可通过ResearchGateAcademiaLinkedintwitter来完成。

审稿也是很重要的学术交流方式,建议使用 Publons 来构建自己的学术审稿记录。当然你可以在博客或微博上评论最新研究,甚至很多网络期刊网站的评论也有很好的思想碰撞,这里最关键的是要搞清楚你所在学科最活跃的网络交流平台,如果没有,自己搭建一个也无妨。

数据分享

数据分享是一个很重要现代科研特征,越来越多的科研成果正在开放自己的原始数据供社区推动学科进步。其中,figshareOpen Science FrameworkDataverseZenodo都是这一潮流的引领者。良好的数据分享不仅包含原始数据,还要包括处理后数据、数据收集相关信息与处理代码,另外对于共享数据的使用也要尊重数据生产者。这里有一份列表对不同学科的数据分享提供指南。

代码管理

后续我们会看到所有学科都会不可逆引入编程,所以代码管理工具也非常重要。GithubBitbucket都是非常实用的在线代码管理与版本控制平台。而RmarkdownJupyter Notebook等工具背后提倡的文学化编程也是很重要的代码开发工具。此外应考虑为未来自己做好注释并记录运行环境保证重复性。Docker image等完整的数据分析环境也可能成为现代科研的主流。代码的编写要能站到巨人肩上:

Good writers borrow from other authors, great authors steal outright

9.6.18 软件编译流程

C语言源码编译运行过程是这样的:先预处理源码,调入模块,然后转换成汇编语言文件,汇编语言文件可以被汇编器转为机器码,然后通过连接器合并为可执行文件,最后加载到内存里运行。因为C语言是多数操作系统的基础,所以多数操作系统也自带对应的C编译器。更重要的是,C语言的库很丰富,也就是工具函数比较多,换别的就得自己写。这是很有意思的路径依赖案例,事实上任何语言都应该可以拿来写操作系统,不过C是在开发Unix时候设计出来的,现在流行的开发级操作系统都是unix/类unix操作系统,加上C在内存管理与CPU交互上的先天优势,历史机遇下成为了主流。

C的核心地位还体现在很多高级语言的编译器是构建在C之上的,或者是C++之上,多数高级语言都通过限制自由度(例如不让操作内存、功能模块化等)来实现上手容易与较高的开发效率,但只要关注程序性能,肯定回去学C或C++的。GNU的GCC编译器是一个相对通用的编译器合集,可以用来编译包括C在内的多种语言。然而,GCC也是有历史包袱的,所有有人就另起炉灶单独针对C或C++重写了效率更高的编译器及其后台,这就是苹果的LLVM项目与clang编译器。但要注意的是LLVM支持的语言不如GCC多,所以如果你还要用到fortain或java编译器,那就还是老老实实用GCC吧,或者cmake的时候分别指定编译器,只要你不嫌麻烦。一般而言,效率与性能往往不能兼得。

高级语言的编译过程跟相对底层的C或C++是不一样的,Java就是自己定义了一套运行环境JVM,编译出的文件也是JVM可读的,这就提高了Java的可移植性,降低了跨平台开发的难度,当然你得保证这些平台上可以运行JVM。其实很多高级语言是解释型的,REPL里可直接运行代码,但同样会有人为高级语言写编译器来提高运行性能,这个是按需求来。我个人感觉是用REPL的人一般是应用层的,关心有没有满足自己需求的函数;用编译语言的人一般是开发层的,关心软件工程及性能。然而,高级语言里如果打算提高运行效率,也会提供C或C++的接口让程序员可以通过外力来提高自由度。过度的功能封装实际也限制了高级语言的应用场景。

说到效率,自然少不了并行计算,openmp就是一种并行化方案,可以支撑C与C++。很多R包会通过使用 openmp 来底层加速算法,但这样的包一般都需要单独编译。目前GCC与Clang在编译器层其实都实现了对 openmp 的支持,编译时加上 -fopenmp 就可以。不过 mac os 自带的编译器是没有这个功能的,所以你需要 homebrew 来自己安装这些支持 openmp 的编译器然后在 .R/Makevars 里把默认编译器换成新的就可以了。

例如你装了llvm/Clang,可以写上:

CC=/usr/local/opt/llvm/bin/clang CXX=/usr/local/opt/llvm/bin/clang++ CXX11=/usr/local/opt/llvm/bin/clang++

或者GCC版(注意版本要对应):

CC=/usr/local/bin/gcc-8 CXX=/usr/local/bin/gcc-8 CXX11=/usr/local/bin/gcc-8

或者更简单的方法就是不用并行计算,直接在.R/Makevars 里参数留空强制跳过对openmp的编译要求:

SHLIB_OPENMP_CFLAGS= SHLIB_OPENMP_CXXFLAGS=

同样的道理可以用在开发上,如果你编写R包涉及了相关并行计算功能,需要在src目录下创建Makevars文件来帮助用户提前配置编译参数,不过这方面我就没经验了。

R包管理

对于R包的管理,建议打印相关Rstudio出品的小抄作为参考。同时作为IDE,Rstiduo提供了包开发的模版,可以使用formatRRd2roxgen来重新格式化旧代码。用 Git 进行版本控制,同时使用roxygen2来编写开发文档。为了让包更容易使用,可以用Rmarkdown来写小品文方便读者上手,另外就是使用testthat来进行代码的单元测试。对于代码的执行效率,可以用Profvis进行可视化而集成在线测试则可以通过travis-ciappveyor来分别对R包进行Linux与Windows系统下的测试并统计代码覆盖率。可以在 Github 上发布、选择许可证、在 CRAN 上发布,也可以添加演示数据、提供 shiny 应用、写更新日志与 Readme 文档且放上前面所说的测试结果、下载量及覆盖度的各类徽章…你甚至还可以用 hexSticker 给自己软件包做个六边形贴纸当商标。当然,包完成后可通过 pkgdown来制作网站并通过learnr 来制作交互式教程。