• 新鲜事R语言
  • 诚邀广大R语言、数据可视化爱好者和我们一起搬迁升级谢益辉著作《现代统计图形》

dapengde Liechi

我新建了两个分支

  • first-edition-update: 主体不动,只是修复代码中的 BUG 和文字编辑错误,前者应该基本没有了,后者还需大家来捉虫
  • develop 分支: 这作为现代统计图形第二版的开发分支,会有翻天覆地的变化,包括但不限于重写所有章节内容,目录大致不变,可以新增章节。分支内容目前是空的bookdown项目架子,欢迎大家发挥集体才智,一起讨论决定书籍大纲和分领各个章节

    Cloud2016 我只配捉虫。可惜原稿作者有洁癖,看了几遍都没见一只虫。连标点虫都没看见。

    我跟 @Liechi 弄的这个 tidyverse 版,主要是练习玩的,可能对此书的修订意义不大。不过,如果将来我们弄得特别牛,并且对此书有用,可以合并进去。

    Liechi 等我弄好 travis 就更方便了。最近搬家,太忙了。

      dapengde 如果所有的例子都升级到 tidyverse 的框架下,至少看起来紧跟时代,古代统计图形终于可以叫回现代统计图形了,加油吧!我现在也没有大把时间搞这个了,偶尔弄弄还行,合并合并 PR 还是可以的

        Cloud2016《现代统计图形》涉及 ggplot 的地方(包括第五章对 ggplot 的专门介绍),@yihui 常用 qplot 来做演示。我的个人经验是实际用哥哥作图时很少会用qplot;Hadley 在 ggplot 书第二版里放弃了第一版先介绍 qplot 的安排,认为不利于初学者掌握哥哥语法。《现代统计图形》里涉及 ggplot 的内容本来不多,qplotggplot 混合出现或许会给一些初学者造成困扰。

        我建议将书里的qplot 统一成 ggplot() + geom_xx() 的形式,不知意下如何?

          Cloud2016 我弄的话就是蜗牛速度了(参考 TNT 擂台赛)。你要是拿出前两天的干劲儿来,重画一遍也就是一两天的事儿啊。

          Cloud2016 qplot 被比喻为拐杖 (crutch) 很贴切:靠它容易起步;拄久了妨碍正常走路;丢掉它才能跑起来。

          qplot() 我觉得只是方便 Base R 用户在 ggplot2 起步。对于连 Base R 都没基础的,qplot() 实在没必要;而习惯了 Base R 的用户,即使学会了 qplot(),仍然会在进入 ggplot2 的过程里很吃力。

          qplot() 是个很尴尬的存在。

            Cloud2016 我把第五章的 qplot 换成了 ggplot + ... 的形式,另外,修改了原文主题部分的一个小问题。我想把改动推到你的库里,但是好像默认会推送我这个分枝上我和大鹏之前的所有改动。我不知道怎么单独推动关于第五章的改动。库在这里:https://github.com/liechi/msgtv

              Liechi 我注意到你 Fork 的是大鹏的库

              你应该直接 Fork 我的库,修改内容后,往分支 first-edition-update 推送 PR。这个分支用来接收第一版的更新,我也是 Git 操作还不太熟,所以另开这么一个分支,免得把 master 主分支搞崩了!

              P.S.
              master 主分支我暂时不想修改,每积累一点量稳定后更新一次,前两天我又猛推了不少更新到主分支,现在我要克制自己,不然太浪费时间了,也搞的我精疲力尽

                dapengde 我刚看了下你的极乐净土版现代统计图形,我注意到你在使用 BT 之前的分栏方式对比展示 Base R 和 ggplot2 绘制的图形,我建议你使用 cowplot 包来安排,我想会方便很多,详情请见 <https://github.com/XiangyunHuang/MSG-Book/issues/29> 此外,毕竟基于 cowplot 的排图方式已经有很成功的实践,见 <https://serialmentor.com/dataviz/histograms-density-plots.html> 支持不同图形系统的组合和强大的注释功能

                  Cloud2016 我想直接 fork 你的库,但是收到提示说我已经 fork 过了,然后提示上显示的是 msgtv 这个库。

                    Liechi 你建立 PR 的时候,上流 repo 选我的仓库,而不是大鹏的仓库

                      Cloud2016 我选择了你的库发 PR,这样以前我跟大鹏作的所有的修改都会被推过来,但我希望推送的只是关于第五章的最近两次修改。我能全推过来,但你只接受最近两次 commits 吗?

                        Cloud2016 这个 issue 我之前看到了。cowplot 我不熟,暂时没顾上尝试,不过我猜那样的话可能每个插图大小都要调整,眼下实在没精力,可能将来统稿时统一修改比较容易吧。况且,这个极乐净土版的练习性和实验性很强,基本属于自娱自乐,我并不确定这个并排显示有没有意义……

                          dapengde 原来你调用了 ggpubr 包,那也无所谓了,它包裹了 cowplot 所以也具有很强的注释能力

                          Liechi 我想了想,你还是把 PR 提给 @dapengde 吧,操作上更方便一些

                            Cloud2016 好的。

                            Liechi 我做了个任务分配表在项目首页。你要是正在画的话,过来注明一下吧,免得同时重复劳动。4.1 到 4.9 章我今天应该能做完。

                              dapengde Liechi

                              我建议在 ggplot2 里复现 Base R 图形能不能不仅仅形似,而且做到神似,神似不是要追求真假难辨,而是在深入了解 Base R 绘图的过程后(这其中很可能涉及统计的内容,如直方图),将其等价地转换为 ggplot2 代码。如果把图库这一章按照这要求复现出来,我想应该能在统计和可视化两个层面上更上一层楼,这对于提高这两方面的水平是非常有意义的。练习的意义就会更深一层,毕竟我发现两位大侠都是 ggplot2 的粉丝,基础的操作都会。

                              为了说清楚,以现代统计图形之图库之直方图为例,

                              # 这是 Base R 版
                              par(mfrow = c(2, 2), mar = c(2, 3, 2, .5), mgp = c(2, .5, 0))
                              data(geyser, package = "MASS")
                              hist(geyser$waiting, main = "(1) freq = TRUE", xlab = "waiting")
                              hist(geyser$waiting, freq = FALSE, xlab = "waiting", main = "(2) freq = FALSE")
                              hist(geyser$waiting, breaks = 5, density = 10, xlab = "waiting", main = "(3) breaks = 5")
                              hist(geyser$waiting, breaks = 40, col = "red", xlab = "waiting", main = "(4) breaks = 40")
                              # 这是 ggplot2 版
                              library(ggplot2)
                              library(cowplot)
                              p <- ggplot(aes(waiting), data = geyser)
                              p1 <- p + geom_histogram(breaks = seq(40, 110, by = 5))
                              p2 <- p + geom_histogram(breaks = seq(40, 110, by = 5), aes(y = stat(density)))
                              p3 <- p + geom_histogram(breaks = seq(40, 110, by = 10))
                              p4 <- p + geom_histogram(breaks = seq(42, 108, by = 2), fill = "red", color = "black")
                              plot_grid(p1, p2, p3, p4, labels = c(
                                "(1) freq = TRUE",
                                "(2) freq = FALSE",
                                "(3) breaks = 5",
                                "(4) breaks = 40"
                              ), ncol = 2)

                              注意 ggplot2 版的 breaks 的设置,它来源于 Base R 版的绘图结果,不是试出来的。以第一个子图为例

                              h <- hist(geyser$waiting, main = "(1) freq = TRUE", xlab = "waiting")
                              h
                              $breaks
                               [1]  40  45  50  55  60  65  70  75  80  85  90  95 100 105 110
                              
                              $counts
                               [1]  2 26 29 25 17 10 34 59 44 35 14  3  0  1
                              
                              $density
                               [1] 0.0013377926 0.0173913043 0.0193979933 0.0167224080 0.0113712375
                               [6] 0.0066889632 0.0227424749 0.0394648829 0.0294314381 0.0234113712
                              [11] 0.0093645485 0.0020066890 0.0000000000 0.0006688963
                              
                              $mids
                               [1]  42.5  47.5  52.5  57.5  62.5  67.5  72.5  77.5  82.5  87.5  92.5  97.5
                              [13] 102.5 107.5
                              
                              $xname
                              [1] "geyser$waiting"
                              
                              $equidist
                              [1] TRUE
                              
                              attr(,"class")
                              [1] "histogram"

                              此节的另一个例子是

                              demo("hist_geyser", package = "MSG")
                              df <- data.frame(x = seq(40, 110, 5), y = 0, 
                                               xend = seq(40, 110, 5), yend = ht)
                              p2 + geom_density(fill = "lightgray", color = "black") +
                                geom_segment(aes(x = x, y = y, xend = xend, yend = yend),
                                  data = df, lty = 3
                                )