附录 B 其它软件

I think, therefore I R.

— William B. King30

B.1 文本编辑器

代码文件也是纯文本,RStudio 集成了编辑器,支持语法高亮。Windows 系统上优秀的代码编辑器有 Notepad++ 非常轻量。Markdown 文本编辑器我们推荐 Typora 编辑器,它是跨平台的,下面以 Ubuntu 环境为例,介绍安装和使用过程:

# or run:
# sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA300B7755AFCFAE
wget -qO - https://typora.io/linux/public-key.asc | sudo apt-key add -

# add Typora's repository
sudo add-apt-repository 'deb https://typora.io/linux ./'
sudo apt-get update

# install typora
sudo apt-get install typora
Typora 主题Typora 主题

图 B.1: Typora 主题

设置中文环境,并且将主题风格样式配置为 Vue,见图B.1(右),Vue 主题可从 Typora 官网下载 https://theme.typora.io/theme/Vue/

  1. Atom 编辑器 https://atom.io/
sudo add-apt-repository ppa:webupd8team/atom
sudo apt-get update
sudo apt-get install atom
  1. Code 编辑器微软出品 https://code.visualstudio.com/

  2. Notepad++ 开源的 Windows 平台上的编辑器 https://notepad-plus-plus.org/

  3. VI & VIM 开源的跨平台编辑器

  4. Atom 和 Code 有商业公司支持的开源免费的跨平台的编辑器

  5. VI/VIM 和 Emacs 是跨平台的编辑器

  6. Markdown 编辑器 + blogdown 记笔记

  7. Typora Markdown 编辑器,支持自定义 CSS 样式

B.2 代码编辑器

VS Code, Sublime Text 和 Atom

B.3 集成开发环境

RStudio 公司的愿景,介绍 RStudio 开发环境提供的效率提升工具或功能

B.3.1 RStudio 桌面版

开源桌面版 RStudio 集成开发环境

图 B.2: 开源桌面版 RStudio 集成开发环境

# mongolite
sudo dnf install -y  openssl-devel cyrus-sasl-devel
# sodium
sudo dnf install -y  libsodium-devel
# rJava
R CMD javareconf
# https://github.com/s-u/rJava
# shinytest::installDependencies()
db <- rstudioapi::getRStudioPackageDependencies()

invisible(lapply(db$name, function(pkg) {
  if (system.file(package = pkg) == "") {
    install.packages(pkg)
  }
}))

B.3.2 RStudio 服务器版

RStudio Server 开源服务器版可以放在虚拟机里或者容器里,RStudio 桌面版装在服务器上,服务器为 Ubuntu/CentOS/Windows 系统,然后本地是 Windows 系统,可以通过远程桌面连接服务器,使用 RStudio;

虚拟机里的 RStudio

图 B.3: 虚拟机里的 RStudio

服务器上启动 Docker ,运行 RStudio 镜像,本地通过桌面浏览器,如谷歌浏览器登陆连接。

容器里的 RStudio

图 B.4: 容器里的 RStudio

  1. 下载 RStudio IDE

    我们从 RStudio 官网下载开源桌面或服务器版本,服务器版本的使用介绍见文档,最常见的就是设置端口

    wget https://download2.rstudio.org/rstudio-server-1.1.456-amd64.deb
    sudo apt-get install gdebi
    sudo gdebi rstudio-server-1.1.456-amd64.deb
  2. 设置端口

    在文件 /etc/rstudio/rserver.conf 下,设置

    www-port=8181

    注意:修改 rserver.conf 文件后需要重启才会生效

    sudo rstudio-server stop
    sudo rstudio-server start

    接着获取机器的 IP 地址,如 192.168.141.3

    ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1/8 scope host lo
        valid_lft forever preferred_lft forever
     inet6 ::1/128 scope host
        valid_lft forever preferred_lft forever
    2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 08:00:27:59:c0:fb brd ff:ff:ff:ff:ff:ff
        inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
           valid_lft 83652sec preferred_lft 83652sec
        inet6 fe80::a00:27ff:fe59:c0fb/64 scope link
           valid_lft forever preferred_lft forever
    3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 08:00:27:09:33:0d brd ff:ff:ff:ff:ff:ff
        inet 192.168.141.3/24 brd 192.168.141.255 scope global dynamic enp0s8
           valid_lft 547sec preferred_lft 547sec
        inet6 fe80::a00:27ff:fe09:330d/64 scope link
           valid_lft forever preferred_lft forever

    然后,就可以从本地浏览器登陆 RStudio 服务器版本,如 http://192.168.141.3:8181/

B.3.3 Shiny 服务器版

shiny 开源服务器版

B.3.4 Eclipse + StatET

Eclipse 配合 StatET 插件 http://www.walware.de/goto/statet 提供R语言的集成开发环境 https://projects.eclipse.org/projects/science.statet

基于 Eclipse 的 R 集成开发环境 StatET

图 B.5: 基于 Eclipse 的 R 集成开发环境 StatET

StatET 基于 Eclipse 首次建立索引很慢,估计半小时到一个小时,添加新的 R 包后,每次启动 StatET 也会建立索引缓存,此外,Eclipse 开发环境占用内存比较多,配置 StatET 的过程如下

B.3.5 Emacs + ESS

Emacs 配合 ESS 插件 https://ess.r-project.org/

B.3.6 Nvim-R

Nvim-R 是一个基于 Vim 的集成开发环境 https://github.com/jalvesaq/Nvim-R

B.4 Git 版本控制

只考虑 Ubuntu 18.04 环境下的三剑客 Git & Github & Gitlab

summary(git2r::repository())
## Local:    devel /home/xiangyun/masr
## Remote:   devel @ origin (git@github.com:XiangyunHuang/masr.git)
## Head:     [ca22690] 2020-06-25: [docker] 忘记先加载 magrittr 包了
## 
## Branches:          2
## Tags:              0
## Commits:         120
## Contributors:      2
## Stashes:           6
## Ignored files:    16
## Untracked files:  82
## Unstaged files:    1
## Staged files:      0
## 
## Latest commits:
## [ca22690] 2020-06-25: [docker] 忘记先加载 magrittr 包了
## [530c86a] 2020-06-25: 文件系统命令和 R 命令的等价表示
## [15ec38f] 2020-06-25: [docker] 添加参考文献和note页面
## [80c603d] 2020-06-25: 添加一个非线性建模的例子
## [b30b76c] 2020-06-25: PlantGrowth 数据集的各种变形操作方式介绍从案例研究移动到数据操作章节

仓库 masr 哪些人给我点赞加星了

library(gh)
my_repos <- gh("GET /repos/:owner/:repo/stargazers", owner = "xiangyunhuang", repo = "masr", page = 1)
vapply(my_repos, "[[", "", "login")
 [1] "XiangyunHuang"   "dddd1007"        "boltomli"        "JackieMium"      "AXGL"            "fyemath"         "rogerclarkgc"   
 [8] "swsoyee"         "joegaotao"       "YTLogos"         "Accelerator086"  "yimingfish"      "gaospecial"      "shenxiangzhuang"
[15] "shuaiwang88"     "LusiXie"         "jamesyangget" 
Git 代码版本管理

图 B.6: Git 代码版本管理

Jeroen Ooms 开发的 gert 包实现在 R 环境中操作 Git,我们可以从幻灯片 — Gert: A minimal git client for R 学习重点内容。

library(gert)
Linking to libgit2 v1.0.0, ssh support: YES, https support: YES
Default user: Xiangyun Huang <xiangyunfaith@outlook.com>
library(magrittr)
git_log(max = 10) %>% 
  subset(grepl("Yihui Xie", x = author), select = c("author", "message"))

提供了 git_rm()git_status()git_add()git_commit() 等函数,其中包含 git_reset() 高级的 Git 操作。此外, 还有 git_branch_*() 系列分支操作函数

B.4.1 安装配置

Ubuntu 16.04.5 默认安装的 Git 版本是 2.7.4,下面安装最新版本Git和配置自己的GitHub账户

  1. 根据官网安装指导 https://git-scm.com/download/linux,在 Ubuntu 14.04.5 和 Ubuntu 16.04.5 安装最新版 GIT

    sudo add-apt-repository -y ppa:git-core/ppa
    sudo apt update && sudo apt install git
  2. 配置账户

    git config --global user.name "你的名字"
    git config --global user.email "你的邮件地址"
    touch .git-credentials
    # 记住密码
    echo "https://username:password@github.com" >> .git-credentials
    git config --global credential.helper store

以 Fedora 为例 安装 tig,首先安装必要的依赖,然后从官网下载源码,编译安装,之后切到任意本地 Git 仓库下,输入 tig 就可以看到如图 B.7 所示的样子了

sudo yum install readline-devel ncurses-devel asciidoc docbook-utils xmlto

tig 主要用于查看 git 提交的历史日志

Git 日志查看器

图 B.7: Git 日志查看器

B.4.2 追踪文件

git add .

提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件

git add -u

提交被修改(modified)和被删除(deleted)文件,不包括新文件(new),git add --update的缩写

git add -A

提交所有变化,git add --all 的缩写

  • 往远程的空的 Github 仓库添加本地文件
git init
git remote add origin https://github.com/XiangyunHuang/notesdown.git
git add -A
git commit -m "balabala"
git push -u origin master

B.4.3 合并上流

git clone --depth=5 https://github.com/XiangyunHuang/cosx.org.git
git submodule update --init --recursive

查看远程分支

cd cosx.org
git remote -v
origin  https://github.com/XiangyunHuang/cosx.org.git (fetch)
origin  https://github.com/XiangyunHuang/cosx.org.git (push)
# 添加上流分支
git remote add upstream https://github.com/cosname/cosx.org.git
# 查看远程分支
git remote -v
origin  https://github.com/XiangyunHuang/cosx.org.git (fetch)
origin  https://github.com/XiangyunHuang/cosx.org.git (push)
upstream        https://github.com/cosname/cosx.org.git (fetch)
upstream        https://github.com/cosname/cosx.org.git (push)
# 获取上流 commit 并且合并到我的 master 分支
git fetch upstream
git merge upstream/master master
git push origin master

B.4.4 大文件支持

sudo apt install git-lfs
git lfs install
git lfs track "*.psd"
git add .gitattributes
git commit -m "track *.psd files using Git LFS"
git push origin master

这玩意迟早需要你购买存储空间,慎用

B.4.5 新建分支

git checkout -b stan     # 新建 stan 分支
git branch -v            # 查看本地分支 stan 前有个星号标记
git pull --rebase git@github.com:XiangyunHuang/cosx.org.git master
# 同步到远程分支 stan
git push --set-upstream origin stan
git push origin master:stan

git add .
git commit -m "balabala"
git push --set-upstream origin stan

本地新建仓库推送至远程分支

git remote add origin https://github.com/XiangyunHuang/notesdown.git
git add .
git commit -m "init cos-art"
# 此时远程仓库 notesdown 还没有 cos-art 分支
git push origin master:cos-art

位于 Github Git Community Book 中译本

B.4.6 创建站点

基于 GitHub Pages 创建站点用于存放图片和数据

  1. 在Github上创建一个空的仓库,命名为 uploads,没有 readme.md 和 LICENSE
  2. 在本地创建目录 uploads
  3. 切换到 uploads 目录下
git init 
git checkout -b gh-pages
git remote add origin https://github.com/XiangyunHuang/uploads.git

添加图片或者数据,并且 git add 和 commit 后

git push --set-upstream origin gh-pages

这样仓库 uploads 只包含 gh-pages 分支,数据地址即为以日期为分割线

https://xiangyunhuang.github.io/uploads/data/eqList2018_05_18.xls

B.4.7 回车换行

CR (Carriage Return) 表示回车,LF (Line Feed) 表示换行,Windows 下用回车加换行表示下一行,UNIX/Linux 采用换行符 (LF) 表示下一行,MAC OS 则采用回车符 (CR) 表示下一行

git config --global core.autocrlf false

B.4.8 子模块

  • 添加子模块到目录 templates/
git submodule add git://github.com/jgm/pandoc-templates.git templates
  • 移除子模块

https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/

B.4.9 克隆项目

git clone --depth=10 --branch=master --recursive \
    git@github.com:XiangyunHuang/pandoc4everything.git

B.4.10 创建 PR

git pull --rebase git@github.com:yihui/xaringan.git master
# then force push to your master branch

参考 https://github.com/yihui/xaringan/pull/107

I don’t recommend you to use your master branch for pull requests, because all commits will be squashed before merging, e.g. c2c2055 Then you will have some trouble with syncing your master branch with the master branch here (your choices are (1) delete your repo and fork again; or (2) force push; either option is not good). For pull requests, I recommend that you always use different branches for different pull requests.

B.4.11 修改 PR

之前一直有一个思想在阻止自己,就是别人的 repo 我是不能修改的,但是在这里,我拥有修改原始仓的权限,那么别人的复制品衍生的分支,我也有修改权限

git fetch origin refs/pull/771/head:patch-2
# 771 是 PR 对应的编号
git checkout patch-2

# 你的修改

git add -u
git commit -m "描述你的修改"

git remote add LalZzy https://github.com/LalZzy/cosx.org.git

git push --set-upstream LalZzy patch-2

整理自统计之都论坛的讨论 https://d.cosx.org/d/420363

B.5 Pandoc 文档处理

Pandoc 是一个万能文档转化器,安装 pandoc,下载网址 https://github.com/jgm/pandoc/releases/latest

sudo apt-get install gdebi-core
wget https://github.com/jgm/pandoc/releases/download/2.9.2/pandoc-2.9.2-1-amd64.deb
sudo chmod +x pandoc-2.9.2-1-amd64.deb
sudo gdebi pandoc-2.9.2-1-amd64.deb

rmarkdown 包裹了 Pandoc 工具,使用 rmarkdown::render() 函数即可将 R Markdown 文档转化为 HTML、LaTeX 和 Markdown 等格式。

B.6 Calibre 书籍管理

Calibre 是一款电子书转化和管理软件,首先安装 calibre

sudo -v && wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sudo sh /dev/stdin

calibre 可以将 epub 格式电子书文档转化为 mobi 格式,bookdown 已经给这个工具穿上了一件马甲,用户只需调用 bookdown::calibre() 函数即可实现电子书格式的转换。

B.7 ImageMagick 图像处理

图像的各种操作,包括合成、转换、旋转等等

首先安装 ImageMagick 软件包中的 convert 程序

asy -f jpg test.asy

指定分辨率

convert -geometry 1000x3000 -density 300 -units PixelsPerInch example.eps example.png

这样不改变图像的像素数,只是给出一个每个像素应该显示多大的提示。

convert -quality 100 -density 300x300 filename.pdf filename.png

高质量大图,给定像素,转化 eps 格式图片,需要先安装 Ghostscript

convert -geometry 1000x3000 example.eps example.png

B.8 OptiPNG 图片优化

OptiPNG 是一个非常好的图片压缩、优化工具

现在,我们设置 chunk 选项 optipng 为非空(non-NULL)的值,例如,'' 去激活这个 hook (益辉称之为钩子,这里勾的是 optipng 这个图片优化工具)

knitr::knit_hooks$set(optipng = knitr::hook_optipng)
library(ggplot2)
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) +
  geom_point()
没有优化

图 B.8: 没有优化

library(ggplot2)
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) +
  geom_point()
优化

图 B.9: 优化

optipng -o5 filename.png

B.9 PDFCrop 裁剪边空

PDFCrop 可将 PDF 图片中留白的部分裁去,再也不用纠结 par 了

B.10 PhantomJS 网页截图

Winston Chang 开发了 webshot 包网页截图,它依赖 PhantomJS,所以首先需要安装

install.packages("webshot")
webshot::install_phantomjs()

以截取网页 https://www.r-project.org/ 为例,

library(webshot)
webshot("https://www.r-project.org/", "r.png")
webshot("https://www.r-project.org/", "r.pdf") # Can also output to PDF

还可以截取 R Markdown 文档内容,注意是先编译 R Markdown 文档为 HTML 文档,然后截取网页

rmdshot(system.file("examples/knitr-minimal.Rmd", package = "knitr"), file = "screenshots/knitr-minimal.png")

裁剪出特定大小的图片,需要额外的系统依赖 GraphicsMagick (recommended) or ImageMagick installed

# Can specify pixel dimensions for resize()
webshot("https://www.r-project.org/", "r-small.png") %>%
  resize("400x") %>%
  shrink()
** Processing: r-small.png
400x442 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 70570 bytes
Input file size = 70867 bytes

Trying:
  zc = 9  zm = 8  zs = 0  f = 0         IDAT size = 59441
  zc = 9  zm = 8  zs = 1  f = 0
  zc = 1  zm = 8  zs = 2  f = 0
  zc = 9  zm = 8  zs = 3  f = 0
  zc = 9  zm = 8  zs = 0  f = 5
  zc = 9  zm = 8  zs = 1  f = 5
  zc = 1  zm = 8  zs = 2  f = 5
  zc = 9  zm = 8  zs = 3  f = 5
                               
Selecting parameters:
  zc = 9  zm = 8  zs = 0  f = 0         IDAT size = 59441

Output IDAT size = 59441 bytes (11129 bytes decrease)
Output file size = 59714 bytes (11153 bytes = 15.74% decrease)

B.11 Inkscape 矢量绘图

Inkscape 是一款开源、免费、跨平台的矢量绘图软件。是替代 Adobe Illustrator(简称 AI) 最佳工具,没有之一

# Ubuntu 20.04 及之前版本
sudo add-apt-repository ppa:inkscape.dev/stable
sudo apt update
sudo apt install inkscape

PDF 图片格式转化为 SVG 格式

inkscape -l output-filename.svg input-filename.pdf

SVG 转 PDF 格式

inkscape -f input-filename.svg -A output-filename.pdf

Jeroen Ooms 开发的 rsvg 包支持将 SVG 格式图片导出为 PNG、PDF、PS 等格式。使用它可以批量将 SVG 格式文件转化为其它格式文件,比如 PDF(rsvg::rsvg_pdf),PS (rsvg::rsvg_ps)和 PNG(rsvg::rsvg_png

svg_paths = list.files(path = "images", pattern = "*.svg", full.names = T)
for (svg in svg_paths) {
  rsvg::rsvg_pdf(svg, file = gsub(pattern  = "\\.svg", replacement=  "\\.pdf", svg))
}

B.12 QPDF PDF 文件操作

Jeroen Ooms 开发的另一个 qpdf 包将 C++ 库 qpdf 搬运到 R 环境中,用于 PDF 文件的拆分 pdf_split(),组合 pdf_combine(),加密( 传递 password 参数值即可加密),提取 pdf_subset() 和压缩 pdf_compress() 等。下面以组合为例,就是将多个 PDF 文件合成一个 PDF 文件。

library(qpdf)
pdf_paths = list.files(path = "images", pattern = "*.pdf", full.names = T)
pdf_combine(input = pdf_paths, output = "images/all.pdf", password = "")

B.13 UML 标准建模图

UML (Unified Modeling Language) 表示统一建模语言

图 B.10: 图片制作、合成、优化、转换等常用工具

Javier Luraschi 将 UML 绘图库 nomnoml 引入 R 社区,开发了 nomnoml 包,相比于 DiagrammeR 包,它显得非常轻量,网站 https://www.nomnoml.com/ 还可以在线编辑、预览、下载 UML 图。 webshot 包可以将网页截图并插入 PDF 文档中。其它制作图形的工具见 B.10

B.14 Graphviz 流程图

Graphviz 官网 http://www.graphviz.org/,常用于绘制流程图,广泛用于 tensorflow 和 mxnet 的模型描述中

数据分析流程图

图 B.11: 数据分析流程图

DiagrammeR 包将 Graphviz 引入 R 语言

library(DiagrammeR)
library(DiagrammeRsvg)
library(magrittr)
library(rsvg)

graph <-
  "graph {
        rankdir=LR; // Left to Right, instead of Top to Bottom
        a -- { b c d };
        b -- { c e };
        c -- { e f };
        d -- { f g };
        e -- h;
        f -- { h i j g };
        g -- k;
        h -- { o l };
        i -- { l m j };
        j -- { m n k };
        k -- { n r };
        l -- { o m };
        m -- { o p n };
        n -- { q r };
        o -- { s p };
        p -- { s t q };
        q -- { t r };
        r -- t;
        s -- z;
        t -- z;
    }
"
# 导出图形
grViz(graph) %>%
  export_svg %>% charToRaw %>% rsvg_pdf("graph.pdf")
grViz(graph) %>%
  export_svg %>% charToRaw %>% rsvg_png("graph.png")
grViz(graph) %>%
  export_svg %>% charToRaw %>% rsvg_svg("graph.svg")

B.15 LaTeX 排版工具

另外值得一提的是 TikZ 和 PGF(Portable Graphic Format)宏包,支持强大的绘图功能,图形质量达到出版级别,详细的使用说明见宏包手册 https://pgf-tikz.github.io/pgf/pgfmanual.pdf

B.15.1 TinyTeX 发行版

library(tinytex)
# 升级 TinyTeX 发行版
upgrade_tinytex <- function(repos = NULL) {
  # 此处还要考虑用户输错的情况和选择离用户最近(快)的站点
  if(is.null(repos)) repos = "https://mirrors.tuna.tsinghua.edu.cn/CTAN/"
  
  file_ext <- if (.Platform$OS.type == "windows") ".exe" else ".sh"
  tlmgr_url <- paste(repos, "/systems/texlive/tlnet/update-tlmgr-latest", file_ext, sep = "")
  file_name <- paste0("update-tlmgr-latest", file_ext)
  download.file(url = tlmgr_url, destfile = file_name, 
                mode = if (.Platform$OS.type == "windows") "wb" else "w")
  
  # window下 命令行窗口下 如何执行 exe 文件
  if(.Platform$OS.type == "windows"){
    shell.exec(file = file_name)
    file.remove("update-tlmgr-latest.exe")
  }
  else{
    system("sudo sh update-tlmgr-latest.sh  -- --upgrade")
    
    file.remove("update-tlmgr-latest.sh")
  }
  
  # 类似地 Linux 下执行 sh
  # 升级完了 删除 update-tlmgr-latest.exe
}

Winston Chang 整理了一份 LaTeX 常用命令速查小抄 https://wch.github.io/latexsheet/latexsheet.pdf

B.15.2 安装和更新

tlmgr (TeXLive Manager) 是 LaTeX 包管理器

# 就近选择 CTAN 镜像站点
tlmgr option repository https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/tlnet
tlmgr option repository http://mirror.ctan.org/systems/texlive/tlnet
# 可更新的 TeX 包列表
tlmgr update --list
# 更新所有已经安装的 TeX 包
tlmgr update --all
# 更新 tlmgr 管理器本身
tlmgr update --self
# 安装
tlmgr install ctex fandol
# 列出套装
tlmgr list schemes
tlmgr list collections
# 列出已经安装的 TeX 包
tlmgr list --only-installed
# 安装 GPG 公钥(只限Win/Mac)
tlmgr --repository http://www.preining.info/tlgpg/ install tlgpg

B.15.4 TikZ 绘图工具

TikZ 绘制书籍封面 https://latexdraw.com/how-to-create-a-beautiful-cover-page-in-latex-using-tikz/

TikZ 绘制知识清单,书籍章节结构等 https://www.latexstudio.net/index/lists/barsearch/author/1680.html

更多例子参考 https://github.com/FriendlyUser/LatexDiagrams

TikZ 绘制 Excel 风格的 Smart 图

Excel Smart Diagram

图 B.12: Excel Smart Diagram

TikZ 绘制 Venn 图

现代统计是一门跨学科交叉应用的艺术

图 B.13: 现代统计是一门跨学科交叉应用的艺术

TikZ 绘制气泡图

LaTeX 家族

图 B.14: LaTeX 家族

TikZ 绘制树形项目结构图

树形项目结构图

图 B.15: 树形项目结构图

TikZ 绘制三维图

TikZ 绘制的 Octave 图标

图 B.16: TikZ 绘制的 Octave 图标

B.16 Octave 科学计算

%% fig1
tx = ty = linspace (-8, 8, 41)';
[xx, yy] = meshgrid (tx, ty);
r = sqrt (xx .^ 2 + yy .^ 2) + eps;
tz = sin (r) ./ r;
mesh (tx, ty, tz);
xlabel ("tx");
ylabel ("ty");
zlabel ("tz");
title ("3-D Sombrero plot");


% fig2
x = 0:0.01:3;
hf = figure ();
plot (x, erf (x));
hold on;
plot (x, x, "r");
axis ([0, 3, 0, 1]);
text (0.65, 0.6175, ['$\displaystyle\leftarrow x = {2\over\sqrt{\pi}}'...
                     '\int_{0}^{x}e^{-t^2} dt = 0.6175$']);
xlabel ("x");
ylabel ("erf (x)");
title ("erf (x) with text annotation");
set (hf, "visible", "off");
print (hf, "plot15_7.pdf", "-dpdflatexstandalone");
set (hf, "visible", "on");
system ("pdflatex plot15_7");
open ("plot15_7.pdf");

%% fig3

clf ();
surf (peaks);
peaks(50)
print -dpswrite -PPS_printer

%% images/peaks-inc
hf = figure (1);
surf (peaks);
print (hf, "peaks.pdf", "-dpdflatexstandalone");

%% windows
hf = figure (1);
peaks(10);
print (hf, "peaks.pdf", "-dpdf");
print (hf, "peaks.eps", "-color"," -deps");

print (hf, "peaks.svg", "-color"," -dsvg");


%% windows
hf = figure (1);
peaks(50);
print (hf, "peaks-more.eps", "-color"," -deps");

print (hf, "peaks-more.svg", "-color"," -dsvg");

B.17 Python 绘图

我们推荐读者创建一个 Python 虚拟环境来使用,环境隔离可以减少对系统的侵入,方便迭代更新和项目管理。创建一个虚拟环境,步骤非常简单,下面以 CentOS 8 为例:

  1. 安装虚拟模块 virtualenv

    sudo dnf install -y virtualenv
  2. 准备 Python 虚拟环境存放位置

    sudo mkdir -p /opt/.virtualenvs/r-tensorflow
  3. 给虚拟环境必要的访问权限

    sudo chown -R $(whoami):$(whoami) /opt/.virtualenvs/r-tensorflow
  4. 初始化虚拟环境

    virtualenv -p /usr/bin/python3 /opt/.virtualenvs/r-tensorflow
  5. 激活虚拟环境,安装必要的模块

    source /opt/.virtualenvs/r-tensorflow/bin/activate
    pip install numpy

一般来讲,系统自带的 pip 版本较低,可以考虑升级 pip 版本。

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U

根据项目配置文件 requirements.txt 安装多个 Python 模块,每个 Python 项目都应该有这么个文件来描述项目需要的依赖环境,包含 Python 模块及其版本号。

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt

指定 Python 模块的镜像地址,加快下载速度,特别是对于国内的环境,加速镜像站点非常有意义,特别是遇到大型的 Python 模块,比如 tensorflow 框架

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow

Python 的 matplotlib 模块支持保存的图片格式有 eps, pdf, pgf, png, ps, raw, rgba, svg, svgz,不支持 cairo_pdf 绘图设备,所以这里使用 pdf 设备,但是这样会导致图形没有字体嵌入,从而不符合出版要求。一个解决办法是在后期嵌入字体,图形默认使用数学字体 STIX 和英文字体 DejaVu Sans,所以需要预先安装这些字体。

# CentOS 8
sudo dnf install -y dejavu-fonts-common dejavu-sans-fonts \
  dejavu-serif-fonts dejavu-sans-mono-fonts

借助 grDevices 包提供的 embedFonts() 函数,它支持 postscript 和 pdf 图形设备,嵌入字体借助了 Ghostscript 以及 PDF 阅读器 MuPDF

Windows 系统下需要手动指定 Ghostscript 安装路径,特别地,如果你想增加可选字体范围,需要指定相应字体搜索路径,而 Linux/MacOS 平台下不需要关心 Ghostscript 的安装路径问题,

Sys.setenv(R_GSCMD = "C:/Program Files/gs/gs9.26/bin/gswin64c.exe")
embedFonts(
  file = "cm.pdf", outfile = "cm-embed.pdf",
  fontpaths = system.file("fonts", package = "fontcm")
)
embedFonts(file = "cm.pdf", outfile = "cm-embed.pdf") 

另一个解决办法是使用 LaTeX 渲染图片中的文字,这就需要额外安装一些 LaTeX 宏包,此时默认执行渲染的 LaTeX 引擎是 PDFLaTeX。

tlmgr install type1cm cm-super dvipng psnfss ucs ncntrsbk helvetic

每年 4 月是 TeX Live 的升级月,升级指导见 https://www.tug.org/texlive/upgrade.html,升级之后,需要更新所有 LaTeX 宏包。

tlmgr update --self --all

如图 B.17 所示,我们采用第二个方法,它可以支持更好的数学公式显示,更多详情见 https://matplotlib.org/tutorials/text/mathtext.html

matplotlib 示例

图 B.17: matplotlib 示例

如果你的系统是 Windows/MacOS 可以添加 GPG 验证以增加安全性,最简单的方式就是:

tlmgr --repository http://www.preining.info/tlgpg/ install tlgpg

二维函数 \(f(x,y) = 20 + x^2 + y^2 - 10*\cos(2*\pi*x) - 10*\cos(2*\pi*y)\) 最小值 0 最大值 80

from math import cos, pi
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm

from matplotlib import rcParams
rcParams.update({'font.size': 18, 'text.usetex': True}) # 其它可配置选项见 rcParams.keys()
plt.switch_backend('agg')

xDomain = np.arange(-5.12, 5.12, .08)
yDomain = np.arange(-5.12, 5.12, .08)

X, Y = np.meshgrid(xDomain, yDomain)
z = [20 + x**2 + y**2 - (10*(cos(2*pi*x) + cos(2*pi*y))) for x in xDomain for y in yDomain]
Z = np.array(z).reshape(128,128)

fig = plt.figure(figsize = (12,10))
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap=cm.RdYlGn, linewidth=1, antialiased=False)

ax.set_xlim(-5.12, 5.12)
## (-5.12, 5.12)
ax.set_ylim(-5.12, 5.12)
## (-5.12, 5.12)
ax.set_zlim(0, 80)
## (0.0, 80.0)
fig.colorbar(surf, aspect=30)
## <matplotlib.colorbar.Colorbar object at 0x7fd56a4b5518>
plt.title(r'Rastrigin Function in Two Dimensions')
plt.show()

B.18 CmdStan 概率编程

remotes::install_github('stan-dev/cmdstanr')

Stan 的命令行接口功能最全全新,使用 cmdstanr 包可以滚动更新 CmdStan,相比于 rstan/rstanarm 包,cmdstanr 包的一个巨大优势是和 Stan 软件的更新分离。由此带来的好处,后续可以在文中见到

library(cmdstanr)
library(bayesplot)
# library(posterior)

file <- file.path(cmdstan_path(), "examples", "bernoulli", "bernoulli.stan")
mod <- cmdstan_model(file)

data_list <- list(N = 10, y = c(0, 1, 0, 0, 0, 0, 0, 0, 0, 1))

fit <- mod$sample(
  data = data_list,
  seed = 2020,
  chains = 2,
  parallel_chains = 2
)
## Running MCMC with 2 parallel chains...
## 
## Running ./bernoulli 'id=1' random 'seed=2020' data \
##   'file=/tmp/Rtmpo6Sy51/standata-bc1e884f8c.json' output \
##   'file=/tmp/Rtmpo6Sy51/bernoulli-202006270626-1-1bc98f.csv' \
##   'method=sample' 'save_warmup=0' 'algorithm=hmc' 'engine=nuts' \
##   adapt 'engaged=1'
## Running ./bernoulli 'id=2' random 'seed=2021' data \
##   'file=/tmp/Rtmpo6Sy51/standata-bc1e884f8c.json' output \
##   'file=/tmp/Rtmpo6Sy51/bernoulli-202006270626-2-1bc98f.csv' \
##   'method=sample' 'save_warmup=0' 'algorithm=hmc' 'engine=nuts' \
##   adapt 'engaged=1'
## Chain 1 Iteration:    1 / 2000 [  0%]  (Warmup) 
## Chain 1 Iteration:  100 / 2000 [  5%]  (Warmup) 
## Chain 1 Iteration:  200 / 2000 [ 10%]  (Warmup) 
## Chain 1 Iteration:  300 / 2000 [ 15%]  (Warmup) 
## Chain 1 Iteration:  400 / 2000 [ 20%]  (Warmup) 
## Chain 1 Iteration:  500 / 2000 [ 25%]  (Warmup) 
## Chain 1 Iteration:  600 / 2000 [ 30%]  (Warmup) 
## Chain 1 Iteration:  700 / 2000 [ 35%]  (Warmup) 
## Chain 1 Iteration:  800 / 2000 [ 40%]  (Warmup) 
## Chain 1 Iteration:  900 / 2000 [ 45%]  (Warmup) 
## Chain 1 Iteration: 1000 / 2000 [ 50%]  (Warmup) 
## Chain 1 Iteration: 1001 / 2000 [ 50%]  (Sampling) 
## Chain 1 Iteration: 1100 / 2000 [ 55%]  (Sampling) 
## Chain 1 Iteration: 1200 / 2000 [ 60%]  (Sampling) 
## Chain 1 Iteration: 1300 / 2000 [ 65%]  (Sampling) 
## Chain 1 Iteration: 1400 / 2000 [ 70%]  (Sampling) 
## Chain 1 Iteration: 1500 / 2000 [ 75%]  (Sampling) 
## Chain 1 Iteration: 1600 / 2000 [ 80%]  (Sampling) 
## Chain 1 Iteration: 1700 / 2000 [ 85%]  (Sampling) 
## Chain 1 Iteration: 1800 / 2000 [ 90%]  (Sampling) 
## Chain 1 Iteration: 1900 / 2000 [ 95%]  (Sampling) 
## Chain 1 Iteration: 2000 / 2000 [100%]  (Sampling) 
## Chain 2 Iteration:    1 / 2000 [  0%]  (Warmup) 
## Chain 2 Iteration:  100 / 2000 [  5%]  (Warmup) 
## Chain 2 Iteration:  200 / 2000 [ 10%]  (Warmup) 
## Chain 2 Iteration:  300 / 2000 [ 15%]  (Warmup) 
## Chain 2 Iteration:  400 / 2000 [ 20%]  (Warmup) 
## Chain 2 Iteration:  500 / 2000 [ 25%]  (Warmup) 
## Chain 2 Iteration:  600 / 2000 [ 30%]  (Warmup) 
## Chain 2 Iteration:  700 / 2000 [ 35%]  (Warmup) 
## Chain 2 Iteration:  800 / 2000 [ 40%]  (Warmup) 
## Chain 2 Iteration:  900 / 2000 [ 45%]  (Warmup) 
## Chain 2 Iteration: 1000 / 2000 [ 50%]  (Warmup) 
## Chain 2 Iteration: 1001 / 2000 [ 50%]  (Sampling) 
## Chain 2 Iteration: 1100 / 2000 [ 55%]  (Sampling) 
## Chain 2 Iteration: 1200 / 2000 [ 60%]  (Sampling) 
## Chain 2 Iteration: 1300 / 2000 [ 65%]  (Sampling) 
## Chain 2 Iteration: 1400 / 2000 [ 70%]  (Sampling) 
## Chain 2 Iteration: 1500 / 2000 [ 75%]  (Sampling) 
## Chain 2 Iteration: 1600 / 2000 [ 80%]  (Sampling) 
## Chain 2 Iteration: 1700 / 2000 [ 85%]  (Sampling) 
## Chain 2 Iteration: 1800 / 2000 [ 90%]  (Sampling) 
## Chain 2 Iteration: 1900 / 2000 [ 95%]  (Sampling) 
## Chain 2 Iteration: 2000 / 2000 [100%]  (Sampling) 
## Chain 1 finished in 0.2 seconds.
## Chain 2 finished in 0.2 seconds.
## 
## Both chains finished successfully.
## Mean chain execution time: 0.2 seconds.
## Total execution time: 0.3 seconds.

模型结果输出

fit$cmdstan_summary()
## Running bin/stansummary \
##   /tmp/RtmpTAntwY/bernoulli-202006252209-1-c10c5e.csv \
##   /tmp/RtmpTAntwY/bernoulli-202006252209-2-c10c5e.csv
## Inference for Stan model: bernoulli_model
## 2 chains: each with iter=(1000,1000); warmup=(0,0); thin=(1,1); 2000 iterations saved.
## 
## Warmup took (0.0063, 0.0061) seconds, 0.012 seconds total
## Sampling took (0.013, 0.011) seconds, 0.023 seconds total
## 
##                 Mean     MCSE  StdDev     5%   50%   95%    N_Eff  N_Eff/s    R_hat
## lp__            -7.2  2.8e-02    0.69   -8.7  -7.0  -6.8  6.2e+02  2.7e+04  1.0e+00
## accept_stat__   0.94  2.1e-03   0.099   0.72  0.98   1.0  2.2e+03  9.3e+04  1.0e+00
## stepsize__      0.88  1.0e-01    0.10   0.78  0.98  0.98  1.0e+00  4.3e+01  3.6e+13
## treedepth__      1.5  2.1e-01    0.68    1.0   1.0   3.0  1.1e+01  4.6e+02  1.0e+00
## n_leapfrog__     3.0  6.5e-01     1.8    1.0   3.0   7.0  7.6e+00  3.2e+02  1.1e+00
## divergent__     0.00      nan    0.00   0.00  0.00  0.00      nan      nan      nan
## energy__         7.7  3.6e-02    0.99    6.8   7.4   9.7  7.6e+02  3.3e+04  1.0e+00
## theta           0.25  4.5e-03    0.11  0.082  0.24  0.45  6.5e+02  2.8e+04  1.0e+00
## 
## Samples were drawn using hmc with nuts.
## For each parameter, N_Eff is a crude measure of effective sample size,
## and R_hat is the potential scale reduction factor on split chains (at 
## convergence, R_hat=1).
fit$summary()
## # A tibble: 2 x 10
##   variable   mean median    sd   mad      q5    q95  rhat ess_bulk
##   <chr>     <dbl>  <dbl> <dbl> <dbl>   <dbl>  <dbl> <dbl>    <dbl>
## 1 lp__     -7.23  -6.96  0.688 0.290 -8.65   -6.75   1.00     726.
## 2 theta     0.247  0.237 0.114 0.114  0.0826  0.454  1.00     692.
## # … with 1 more variable: ess_tail <dbl>
# this is a draws_array object from the posterior package
draws_array <- fit$draws()
str(draws_array)
##  'draws_array' num [1:1000, 1:2, 1:2] -6.84 -6.84 -7.26 -6.89 -6.79..
##  - attr(*, "dimnames")=List of 3
##   ..$ iteration: chr [1:1000] "1" "2" "3" "4" ...
##   ..$ chain    : chr [1:2] "1" "2"
##   ..$ variable : chr [1:2] "lp__" "theta"
# can be passed directly to bayesplot to plot posterior distribution
mcmc_hist(fit$draws("theta"))

B.19 VBox 虚拟机

B.19.1 从命令行启动虚拟机

当前我的虚拟机里安装了两个系统 Fedora 29 和 CentOS 8.2

VBoxManage list vms
"Fedora 29" {d316fe8d-c053-4941-8a45-a59fd476898d}
"CentOS 8.2" {f1613f26-ea65-4f02-9cb6-6a79a758a60e}

以无图形化界面的方式启动虚拟机 CentOS 8.2

VBoxManage startvm "CentOS 8.2" --type headless
# 或者
VBoxHeadless --startvm "CentOS 8.2"

其它常用的命令还有

VBoxManage list runningvms # 列出运行中的虚拟机
VBoxManage controlvm "CentOS 8.2" acpipowerbutton # 关闭虚拟机,等价于点击系统关闭按钮,正常关机
VBoxManage controlvm "CentOS 8.2" poweroff # 关闭虚拟机,等价于直接关闭电源,非正常关机
VBoxManage controlvm "CentOS 8.2" pause # 暂停虚拟机的运行
VBoxManage controlvm "CentOS 8.2" resume # 恢复暂停的虚拟机
VBoxManage controlvm "CentOS 8.2" savestate # 保存当前虚拟机的运行状态

更多细节解释见 VBox 官方文档

B.20 Docker 虚拟环境

Docker 相比虚拟机占用资源少,拉起来就可以用,虚拟机还需要各种环境配置,很多与R有关的项目现在都提供Docker镜像,大大方便了开发人员和数据分析师。当然 docker 的环境隔离性,对主机系统侵入小,即使挂了,再拉起来也就是了,安全性和可靠性高。

基于 The Rocker Project31 快速构建数据分析环境,Rocker项目 站在 DebianR 的肩膀上,在 Docker内配置众多数据分析和开发的工具,免去用户手动配置的复杂性。此事非有心者不能为之 ,因为需费时费力找寻依赖库,编译 R 包,还要尽可能地给 Docker 镜像减负,以便部署。如果想抢先试水的赶快去 Rocker 项目主页。

其它容器相关项目有 SingularityKubernetes 容器集群管理,更多参见高策的博客 http://gaocegege.com

本节介绍与本书配套的 VBox 镜像和 Docker 容器镜像,方便读者直接运行书籍原稿中的例子,尽量不限于软件环境配置的苦海中,因为对于大多数初学者来说,软件配置是一件不小的麻烦事。

本书依赖的 R 包和配置环境比较复杂,所以将整个运行环境打包成 Docker 镜像,方便读者重现,构建镜像的 Dockerfile 文件随同书籍源文件一起托管在 Github 上,方便读者研究。本地编译书籍只需三步走,先将存放在 Github 上的书籍项目克隆到本地,如果本地环境中没有 Git,你需要从它的官网 https://git-scm.com/ 下载安装适配本地系统的 Git 软件。

git clone https://github.com/XiangyunHuang/masr.git

然后在 Git Bash 的模拟终端器中,启动虚拟机,拉取准备好的镜像文件。为了方便读者重现本书的内容,特将书籍的编译环境打包成 Docker 镜像。在启动镜像前需要确保本地已经安装 Docker 软件 https://www.docker.com/products/docker-desktop,安装过程请看官网教程。

docker-machine.exe start default
docker pull xiangyunhuang/masr

最后 cd 进入书籍项目所在目录,运行如下命令编译书籍

docker run --rm -u docker -v "/${PWD}://home/docker/workspace" \
  xiangyunhuang/masr make gitbook

编译成功后,可以在目录 _book/ 下看到生成的文件,点击文件 index.html 选择谷歌浏览器打开,不要使用 IE 浏览器,推荐使用谷歌浏览器获取最佳阅读体验,尽情地阅读吧!

如果你想了解编译书籍的环境和过程,我推荐你阅读随书籍源文件一起的 Dockerfile 文件, Docker Hub 是根据此文件构建的镜像,打包成功后,大约占用空间 2 Gb,本书在 RStudio IDE 下用 R Markdown (Xie, Allaire, and Grolemund 2018) 编辑的,编译本书获得电子版还需要一些 R 包和软件。Pandoc https://pandoc.org/ 软件是系统 Fedora 30 仓库自带的,版本是 2.2.1,较新的 RStudio IDE 捆绑的 Pandoc 软件一般会高于此版本。如果你打算在本地系统上编译书籍,RStudio IDE 捆绑的 Pandoc 软件版本已经足够,当然你也可以在 https://github.com/jgm/pandoc/releases/latest 下载安装最新版本,此外,你还需参考书籍随附的 Dockerfile 文件配置 C++ 代码编译环境,安装所需的 R 包,并确保本地安装的版本不低于镜像内的版本。

镜像中已安装的 R 包列表可运行如下命令查看。

docker run --rm xiangyunhuang/masr \ 
  Rscript -e 'xfun::session_info(.packages(TRUE))'

Docker & Docker Machine & Docker Swarm

  1. 容器与镜像的操作

    docker --version
    # Docker version 18.03.0-ce, build 0520e24302

    查看容器

    docker ps -a

    删除容器 docker rm 容器 ID,删除前要确认已经停止该容器的运行

    docker rm 6f932357e6ce

    查看镜像

    docker images

    删除镜像

    docker rmi 镜像 ID

    docker rmi 811281c54b23
  2. 拉取镜像

    docker pull rocker/verse:latest
  3. 运行容器

    docker run --name verse -d -p 8282:8080 -e ROOT=TRUE \
       -e USER=rstudio -e PASSWORD=cloud rocker/verse

    将主机端口 8282 映射给虚拟机/容器的 8080 端口,RStudio Server 默认使用的端口是 8787,因此改为 8080 需要修改 /etc/rstudio/rserver.conf 文件,添加

    www-port=8080

    然后重启 RStudio Server,之后可以在浏览器中登陆,登陆网址为 http://ip-addr:8080,其中 ip-addr 可在容器中运行如下一行命令获得

    ip addr

更多关于服务器版本的 RStudio 介绍,请参考 https://docs.rstudio.com/ide/server-pro/access-and-security.html

Docker Machine

基本命令

  • 查看 docker machine 版本信息

    docker-machine --version
    # docker-machine.exe version 0.14.0, build 89b8332
  • 列出创建的虚拟机

    # 启动前
    docker-machine ls
    # NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
    # default   -        virtualbox   Stopped                 Unknown
    # 启动后
    docker-machine ls
    # NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
    # default   *        virtualbox   Running   tcp://192.168.99.100:2376           v18.03.0-ce
  • 查看虚拟机 default 的 ip

    docker-machine ip default
    # 192.168.99.100
  • 启动虚拟机

    docker-machine start default
    # Starting "default"...
    # (default) Check network to re-create if needed...
    # (default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
    # (default) Waiting for an IP...
    # Machine "default" was started.
    # Waiting for SSH to be available...
    # Detecting the provisioner...
    # Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
  • 进入 Docker 环境

    docker-machine ssh default
                            ##         .
                      ## ## ##        ==
                   ## ## ## ## ##    ===
               /"""""""""""""""""\___/ ===
          ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
               \______ o           __/
                 \    \         __/
                  \____\_______/
     _                 _   ____     _            _
    | |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
    | '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
    | |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
    |_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
    Boot2Docker version 18.03.0-ce, build HEAD : 404ee40 - Thu Mar 22 17:12:23 UTC 2018
    Docker version 18.03.0-ce, build 0520e24
  • 查看容器

    docker ps -a
    # CONTAINER ID        IMAGE               COMMAND             CREATED            STATUS                   PORTS               NAMES
    # 69e6929d269e        rocker/verse        "/init"             3 weeks ago        Exited (0) 10 days ago                       verse
  • 启动/停止容器

    docker start verse
    # verse
    docker stop verse
    # verse
  • 查看虚拟机 default 的环境

    docker-machine env default
    # export DOCKER_TLS_VERIFY="1"
    # export DOCKER_HOST="tcp://192.168.99.100:2376"
    # export DOCKER_CERT_PATH="D:\Docker\machines\default"
    # export DOCKER_MACHINE_NAME="default"
    # export COMPOSE_CONVERT_WINDOWS_PATHS="true"
    # # Run this command to configure your shell:
    # # eval $("C:\Program Files\Docker Toolbox\docker-machine.exe" env default)
  • 关闭虚拟机 default

    docker-machine stop default
    # Stopping "default"...
    # Machine "default" was stopped.

更多详情见帮助文档 https://docs.docker.com/machine/get-started

B.21 安装的 R 包

本小节仅用于展示目前书籍写作过程中安装的 R 包依赖,不会出现在最终的书稿中

sessionInfo(sort(.packages(T)))
library(magrittr)
pdb <- tools::CRAN_package_db()
pkg <- subset(desc::desc_get_deps(), subset = type == "Imports", select = "package", drop = TRUE)
pkg <- tools::package_dependencies(packages = pkg, db = pdb, recursive = FALSE) %>% # 是否包含递归依赖
  unlist() %>%
  as.vector() %>%
  c(., pkg) %>%
  unique() %>%
  sort()

pkg_quote <- c(
  "Armadillo", "Rcpp", "R", "Stan", "DataTables", "Dygraphs", "ggplot2",
  "Grobs", "Geospatial", "Eigen", "Sundown", "plog", "TeX Live", "Tidyverse",
  "LaTeX", "ADMB", "matplotlib", "Yihui Xie", "With", "Highcharts",
  "kable", "plotly.js", "Python", "Formattable"
)
# 单引号
pkg_regexp <- paste("'(", paste(pkg_quote, collapse = "|"), ")'", sep = "")
# R 包列表
subset(pdb,
  subset = !duplicated(pdb$Package) & Package %in% pkg,
  select = c("Package", "Version", "Title")
) %>%
  transform(.,
    Title = gsub("(\\\n)", " ", Title),
    Package = paste("**", Package, "**", sep = "")
  ) %>%
  transform(., Title = gsub(pkg_regexp, "\\1", Title)) %>%
  transform(., Title = gsub('"(Grid)"', "\\1", Title)) %>%
  knitr::kable(.,
    caption = "依赖的 R 包", format = "pandoc",
    booktabs = TRUE, row.names = FALSE
  )

本书意欲覆盖的内容

inla_pdb <- data.frame(
  Package = "INLA",
  Title = paste(
    "Full Bayesian Analysis of Latent Gaussian Models",
    "using Integrated Nested Laplace Approximations"
  )
)
pkgs <- c(
  "ggplot2", "cowplot", "patchwork", "rgl", "MASS", "nlme", "mgcv",
  "lme4", "gee", "gam", "gamm4", "cgam", "cglm", "pscl",
  "GLMMadaptive", "gee4", "geoR", "LaplacesDemon", "glmnet",
  "betareg", "quantreg", "agridat", "moments", "R2BayesX",
  "geoRglm", "spaMM", "spBayes", "CARBayes", "PrevMap",
  "FRK", "lgcp", "HSAR", "spNNGP", "MuMIn", "BANOVA",
  "rpql", "QGglmm", "glmmsr", "glmmboot", "glmm",
  "glmmML", "glmmEP", "r2glmm", "hglm", "glmmLasso",
  "blme", "MCMCglmm", "MCMCpack", "glmmTMB", "geepack",
  "glmmfields", "rstan", "rstanarm", "brms", "greta",
  "BayesX", "Boom", "nimble", "rjags", "R2OpenBUGS",
  "R2BayesX", "BoomSpikeSlab", "inlabru", "INLABMA",
  "lmtest", "VGAM", "plotly", "leaflet", "LatticeKrig"
)
pdb <- tools::CRAN_package_db()
book_pdb <- subset(pdb,
  subset = !duplicated(pdb$Package) & Package %in% pkgs,
  select = c("Package", "Title")
)
book_pdb <- rbind.data.frame(book_pdb, inla_pdb)
book_pdb$Title <- gsub("(\\\n)", " ", book_pdb$Title)
book_pdb$Title <- gsub("'(Armadillo|BayesX|Eigen|ggplot2|lme4|mgcv|Stan|Leaflet|plotly.js)'", "\\1", book_pdb$Title)
book_pdb$Package <- paste("**", book_pdb$Package, "**", sep = "")
knitr::kable(book_pdb,
  caption = "本书使用的 R 包", format = "pandoc",
  booktabs = TRUE, row.names = FALSE
)

参考文献

Xie, Yihui, J. J. Allaire, and Garrett Grolemund. 2018. R Markdown: The Definitive Guide. Boca Raton, Florida: Chapman; Hall/CRC. https://bookdown.org/yihui/rmarkdown.