-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path01-introduction.Rmd
129 lines (87 loc) · 12.9 KB
/
01-introduction.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
\mainmatter
# 全书概览 {#intro}
我已经在R领域编程超过15年了,在过去的5年里一直全职从事这项工作,这给了我足够的时间来研究这个语言是如何工作的。这本书是我试图将学到的知识传授给大家,这样您就可以快速理解R语言的细节。阅读此书可以帮助您避免我曾经走过的弯路,并教会您使用R语言的工具、技巧和习惯,帮助您解决各类问题。在这个过程中,我希望可以告诉大家,尽管R语言有时存在一些问题,但它的核心是一种为数据科学量身定做的优雅语言。
## 为什么选择R语言
如果您是一名R语言初学者,您可能需要了解为什么学习这样一门奇怪的语言是值得的,对我而言,R语言最棒的地方体现在:
- R是免费,开源,跨平台的语言。如果您使用R语言开展数据分析,任何人都可以很便捷的使用您的代码。
- R拥有多样化并且广受欢迎的社区,既包括了在线社区(如rstats twitter社区),也包括了线下面对面社区(如许多R语言用户见面会)。这其中有两个令人振奋的社区组织,一个是R语言每周通讯,它可以让您方便的了解R语言的相关信息。另一个是R-Ladies,它是一个面向女性用户及少数性别用户的社区。
- R拥有大量的统计建模、机器学习、可视化分析以及数据处理方面的工具包,无论您需要绘制图形还是建立模型,很有可能前人已经帮您完成了相关工作,您可以从中学习到很多知识。
- R拥有用于展示成果的强大工具。RMarkdown可以轻松的将结果转换为HTML文件、PDF文件、Word文档、PowerPoint演示文稿、仪表盘等。Shiny可以帮助您在无需了解任何HTML或Javascript知识情况下创建漂亮的交互式应用程序。
- R提供了RStudio集成开发环境,可以根据数据科学、交互式数据分析和统计编程的需要进行定制。
- R拥有大量尖端工具,统计学和机器学习领域的研究人员通常会在他们的论文中配套一个R包,这意味着您可以立即获得最新的理论研究与技术实现。
- R是数据分析领域的深层支撑语言,拥有缺失值、数据框、矢量化等诸多功能。
- R对于函数式编程范式的支撑非常强大,函数式编程的思想十分契合数据科学,R的核心就是函数式,它提供了函数式编程所需要的许多原生能力。
- RStudio是一家通过向R用户销售专业产品来盈利的公司,它将大部分资金投入到开源社区(RStudio中超过50%的软件工程师从事开源项目)。我为RStudio工作,因为我从根本上相信它的使命。
- 强大的元编程工具。R的元编程功能使您能够神奇地编写简洁明了的函数,并为设计特定领域的语言(如ggplot2、dplyr、data.table等)提供了一个极好的环境。
- R可以轻松协同C、Fortran和C++这样的高性能编程语言。
当然,R语言并不完美,R所面临的最大挑战(也许是机遇)是R的主要用户并非程序员,这意味着:
- 您通常所看到的R代码都是为了解决一个紧迫的问题而匆忙编写的,因此代码并不是很优雅,且不易理解,而大多数用户不会去开展这些代码的优化工作。
- 相较于其他编程语言,R社区更关注结果而并不是过程,软件工程化是的相关优秀经验并没有在R语言开发中的完整应用。例如,大部分的R开发者没有使用源代码控制或或自动化测试。
- 元编程是一把双刃剑,很多R语言的函数使用一些代码技巧来减少键入量,这样的代价是代码变得难以理解或者出产生无法预料的错误。
- 前后不一致是R包中普遍存在的问题,每次使用R语言的时候,您都可以感受到超过25年的演进,这使得学习R非常困难,有太多的特殊情况需要记住。
- R并不是一种速度很快的语言,写得不好的R代码可能会非常慢。R也是一个内存使用的大户。
我个人认为,这些挑战为经验丰富的程序员创造了一个巨大的机会,对R语言和R社区会产生积极深远的影响。R用户确实希望产出高质量的代码,特别是用于可复制的研究,但他们还没有掌握这样的技能。我希望这本书不仅能帮助更多的R语言的用户成为R程序员,还能鼓励其他语言的程序员为R做出贡献。
## 本书的读者范围
本书面向两类读者:
- 中级R语言程序员。他们希望深入研究R,了解这门语言的工作原理,学习新方法解决各类问题。
- 正在学习R的其他语言程序员。他们想了解为什么R语言会这样工作。
如果想要充分理解本书的内容,您需要用R或者其它语言编写大量的代码。您应该熟悉数据分析的基础知识(即数据导入、数据操作和数据可视化),编写过很多相关的函数,并熟悉CRAN软件包的的安装和使用。
我曾经在将这本书定义为参考书(主要用于查找)还是线性可读书籍之间纠结过。 这涉及一些权衡,因为很难在将相关材料保持在一起的同时还对材料进行线性化,而且如果您已经熟悉特定的技术词汇,那么某些概念更容易解释。我尝试使用脚注和交叉引用来确保即使您只是阅读了这章节,您仍然可以理解相关内容。
## 您将从本书中学到什么
这本书提供了我认为高级 R 程序员应该具备的知识:对基础知识的深刻理解加上广泛的词汇,这意味着您可以在需要时了解更多关于某个主题的知识。
阅读本书之后,您将:
- 熟悉 R 的基础。您将了解复杂的数据类型以及对它们执行操作的最佳方法。您将对函数的工作方式有深入的了解,您将知道什么是环境,以及如何使用状态系统。
- 了解函数式编程的含义,以及为什么它是数据科学的有用工具。您将能够快速学习如何使用现有工具,并在需要时拥有创建自己所需工具的能力。
- 了解 R 丰富多样的面向对象系统。您将最熟悉 S3,但您也会了解 S4 和 R6 以及在需要时从哪里可以查找到更多有关的信息。
- 感受元编程范式的优劣性。您将能够创建使用tidy风格的函数,减少代码的输入量,同时创建优雅的代码来实现重要的功能。您还将了解元编程的相关劣势以及如何避免。
- 拥有R语言性能方面的良好直觉。您将了解到如何使用R的分析能力来查明性能瓶颈,并且您将了解足够的 C++ 知识,以便您可将慢速 R 函数转换为快速 C++ 函数。
## 您无法从本书中学到的内容
这本书是关于R语言程序设计的,不是R语言数据分析。如果您需要提升自身在数据科学方面的技能,我建议您去学习[tidyverse](https://www.tidyverse.org/),这是我与我的同事们开发的一组工具包。在本书中您将学习开发tidyverse包的相关技能;如果您想学习如何使用它们,我推荐[_R for Data Science_](http://r4ds.had.co.nz/)。
如果您希望他人使用您的代码,那么需要制作一个R包。这允许您可以将代码与文档、单元测试等捆绑在一起,并通过CRAN轻松分发。在我看来,开发一个包最简单的方法是使用[devtools](http://devtools.r-lib.org), [roxygen2](http://klutometis.github.io/roxygen/), [testthat](http://testthat.r-lib.org)和 [usethis](http://usethis.r-lib.org). 你可以通过学习[_R packages_](http://r-pkgs.had.co.nz/)这本书来了解上述工具包如何使用。
## 基础技能
有两种基础技能对提高R语言程序员的能力很有帮助:阅读代码与科学思维
阅读源代码很重要,因为它可以帮助您编写更好的代码。培养这项技能的一个好方法是查看您最常使用的函数和包的源代码。您可以在自己的代码中使用这些值得效仿的东西,您会对什么是好的 R 代码产生一种品味。您也会看到你不喜欢的东西,要么是因为它的优点不明显,要么是因为它冒犯了您的敏感性。尽管如此,这样的代码还是很有价值的,因为它有助于让您对好的代码和坏的代码建立自身的认识。
在学习 R 时,科学思维非常有帮助。如果您不了解某些东西是如何工作的,您应该提出一个假设,设计一些实验,运行它们并记录结果。这种方式非常有用,因为如果您自身无法解决问题并需要帮助,您可以轻松地向他人展示您的实验。同样,当您获取到了正确知识时,您也将更加认同这样的思维学习方式。
## 推荐阅读
由于 R 社区主要由数据科学家而非计算机科学家组成,因此深入研究 R 技术基础的书籍相对较少。在我个人理解 R 的过程中,我发现使用其他编程中的资源十分有意义。 R 具有函数式编程和面向对象 (OO)编程两种特性,了解这些特性在 R中如何实现将帮助您充分利用现有在其他语言中建立的知识体系,并将帮助您确认可以改进的方向。
如果您想要了解R的对象系统是如何工作的,*《计算机程序的构造和解释》(SICP)*[@SICP] 这本书非常有帮助。这是一本简介而深刻的书,读完这本书,我第一次感觉自己可以设计一个面向对象系统了。这本书是R语言面向对象编程范式的灵感起源,它帮助我了解了这种范式的优缺点。SICP还可以教会大家函数式编程范式,您可以创建相对独立的“纯”函数,并将它们组合起来实现更强大的功能。
为了了解R语言与其它编程语言之间的优劣,*《计算机编程的概念,技术与模型》*[@ctmcp]这本书非常有用,它让我了解了R语言copy-on-modify的含义,这使得代码理解更加容易,虽然它的实现方式并不是十分有效,但这是一个可以解决的问题。
如果您想成为一名更好的程序员,没有比阅读*《程序员修炼之道》*[@pragprog]更好的选择了。这本书与编程语言无关,它为如何成为一句更好的程序员提供了很好的建议。
## 获取帮助
当您遇到无法解决的问题时,有三个主要的途径可以获取帮助:[RStudio社区](https://community.rstudio.com/)、[StackOverflow](http://stackoverflow.com) 和 [R-help邮件列表][r-help]。您可以在每个地方获取到帮助,但这些地方也各有特色。在发布第一个贴子之前,花一点时间了解社区的风格是一个比较好的做法。
再给大家一些通用的建议:
- 请确保您安装了最新版本的R语言及工具包,或许您遇到的问题已经在最新版本中作为bug被修复。
- 花一些时间创建一个可重现的实验或者reprex,这将帮助他人也帮助您自己,而且有时候可以在不询问他人的情况下找到答案,因为在使问题重现的过程中,您通常会找出问题所在。我强烈推荐学习和使用[reprex](https://reprex.tidyverse.org/)包。
如果您需要针对本书习题的帮助,可以从 Malte Grosser 和 Henning Bumann 获得解决方案,网址为 <https://advanced-r-solutions.rbind.io>
## 致谢
我要感谢 R-devel 和 R-help 的许多贡献者以及Stack Overflow 和 RStudio 社区。 有太多朋友对本书进行了贡献,原谅我无法一一列举,但我要特别感谢 Luke Tierney、John Chambers、JJ Allaire 和 Brian Ripley,他们慷慨地付出了宝贵的时间,纠正了我许多的错误。
这本书是公开编写的,完成后会在推特上发布章节。 这确实是一项社区努力:许多人阅读草稿、进行勘误、提出改进建议并贡献内容。 如果没有这些贡献者,这本书就不会这么好,我非常感谢他们的帮助。 特别感谢 Jeff Hammerbacher、Peter Li、Duncan Murdoch 和 Greg Wilson,他们从头到尾阅读了本书并提供了许多修正和建议。
## 约定
全书我使用`f()`代表函数,`g`代表变量和函数参数,`h/`代表路径
较大的代码块包含了输入和输出。 输出带有注释 (`#>`),因此如果您有本书的电子版本,例如 <https://adv-r.hadley.nz/>,您可以轻松地将示例复制并粘贴到 R 中运行。
本书许多示例使用了随机数,我们需要设定`set.seed(1014)`使结果重现,它在每章开始时自动执行。
\newpage
## 使用的R包
```{r, echo = FALSE, results = 'asis', message = FALSE}
library(tibble)
deps <- desc::desc_get_deps()$package[-1]
pkgs <- sessioninfo::package_info(deps, dependencies = FALSE)
df <- tibble(package = pkgs$package, version = pkgs$ondiskversion,
source = gsub("@", "\\\\@", pkgs$source))
knitr::kable(df, format = "markdown")
```
```{r, include = FALSE}
library(dplyr)
ruler <- function(width = getOption("width")) {
x <- seq_len(width)
y <- case_when(
x %% 10 == 0 ~ as.character((x %/% 10) %% 10),
x %% 5 == 0 ~ "+",
TRUE ~ "-"
)
cat(y, "\n", sep = "")
cat(x %% 10, "\n", sep = "")
}
ruler()
```
[r-help]: https://stat.ethz.ch/mailman/listinfo/r-help