
引言
数据科学是一门激动人心的学科,它能让你将原始数据转化为理解、洞察和知识。 《R 数据科学》的目标是帮助你学习 R 中最重要的工具,让你能够高效、可重复地进行数据科学实践,并在此过程中获得一些乐趣 😃。 读完本书后,你将拥有使用 R 的精华部分来应对各种数据科学挑战的工具。
你将学到什么
数据科学是一个广阔的领域,不可能通过阅读一本书就完全掌握。 本书旨在为你打下坚实的基础,让你掌握最重要的工具,并具备足够的知识以便在必要时寻找资源进行更深入的学习。 我们对典型数据科学项目步骤的模型如 Figure 1 所示。

首先,你必须将数据导入 (import) 到 R 中。 这通常意味着你将存储在文件、数据库或网络应用程序接口 (API) 中的数据加载到 R 的一个数据框 (data frame) 中。 如果你不能将数据导入 R,你就无法对它进行数据科学分析!
一旦导入了数据,一个好主意是将其整理 (tidy)。 整理数据意味着将其以一种一致的形式存储,使其存储方式与数据集的语义相匹配。 简而言之,当你的数据是整洁的时,每一列都是一个变量,每一行都是一个观测。 整洁数据很重要,因为一致的结构可以让你专注于回答关于数据的问题,而不是费力地将数据调整成适合不同函数的形式。
一旦你有了整洁的数据,通常的下一步是进行转换 (transform)。 转换包括筛选出感兴趣的观测(比如某个城市的所有人或去年的所有数据),创建作为现有变量函数的新变量(比如根据距离和时间计算速度),以及计算一组汇总统计量(比如计数或均值)。 整理和转换一起被称为数据整理 (wrangling),因为将数据变成易于处理的形式通常感觉像一场战斗!
一旦你拥有了包含所需变量的整洁数据,知识生成的两大引擎便是:可视化和建模。 这两者各有优缺点,因此任何真实的数据分析都会在它们之间多次迭代。
可视化 (Visualization) 本质上是一种人类活动。 一幅好的可视化图表会向你展示意想不到的东西,或引发关于数据的新问题。 一幅好的可视化图表也可能暗示你问错了问题,或者你需要收集不同的数据。 可视化可以给你带来惊喜,但它们的扩展性不是特别好,因为它们需要人类来解读。
模型 (Models) 是可视化的补充工具。 一旦你把问题定义得足够精确,就可以使用模型来回答它们。 模型本质上是数学或计算工具,因此它们通常具有很好的扩展性。 即使扩展性不好,购买更多的计算机通常也比雇佣更多的大脑要便宜! 但是,每个模型都有其假设,而模型本身无法质疑自己的假设。 这意味着模型本质上无法给你带来惊喜。
数据科学的最后一步是沟通 (communication),这是任何数据分析项目中都至关重要的一部分。 除非你能将你的结果传达给他人,否则无论你的模型和可视化让你对数据理解得多么透彻,都是不够的。
围绕所有这些工具的是编程 (programming)。 编程是一个贯穿始终的工具,你在数据科学项目的几乎每个部分都会用到它。 你不需要成为编程专家才能成为一名成功的数据科学家,但学习更多关于编程的知识是值得的,因为成为一名更好的程序员可以让你自动化常见任务,并更轻松地解决新问题。
你会在每个数据科学项目中使用这些工具,但对于大多数项目来说,它们还不够。 这里有一个粗略的 80/20 法则在起作用:你可以用本书中学到的工具处理每个项目中大约 80% 的工作,但你需要其他工具来处理剩下的 20%。 在本书中,我们会为你指出可以学习更多知识的资源。
本书的组织结构
前面对数据科学工具的描述大致是按照你在分析中使用的顺序来组织的(当然,你会多次迭代这些步骤)。 然而,根据我们的经验,首先学习数据导入和整理并非最佳选择,因为 80% 的情况下这个过程是常规而乏味的,而另外 20% 的情况则是怪异且令人沮丧的。 这对于开始学习一个新主题来说是个糟糕的起点! 因此,我们将从已经导入和整理好的数据的可视化和转换开始。 这样,当你导入和整理自己的数据时,你的动力会保持高涨,因为你知道这些辛苦是值得的。
在每一章中,我们都尽量遵循一个一致的模式:从一些激励性的例子开始,让你看到全局,然后深入细节。 书的每个部分都配有练习,以帮助你实践所学。 虽然跳过练习可能很诱人,但没有比通过解决实际问题更好的学习方法了。
你不会学到什么
本书没有涵盖几个重要的主题。 我们认为,严格专注于基本要素,以便你能尽快上手,这一点非常重要。 这意味着本书无法涵盖所有重要的主题。
建模
建模对于数据科学来说非常重要,但它是一个很大的主题,不幸的是,我们在这里没有足够的篇幅给予它应有的介绍。 要了解更多关于建模的知识,我们强烈推荐我们的同事 Max Kuhn 和 Julia Silge 撰写的《Tidy Modeling with R》。 这本书将教你 tidymodels 系列包,正如你可能从名字中猜到的那样,它们与我们在本书中使用的 tidyverse 系列包共享许多约定。
大数据
本书自豪地主要关注小型的、内存中的数据集。 这是一个正确的起点,因为如果你没有处理小数据的经验,你就无法处理大数据。 你将在本书大部分内容中学到的工具可以轻松处理数百兆字节的数据,稍加注意,你通常可以用它们来处理几吉字节的数据。 我们还将向你展示如何从数据库和 parquet 文件中获取数据,这两种格式都常用于存储大数据。 你可能无法处理整个数据集,但这不成问题,因为你通常只需要一个子集或子样本来回答你感兴趣的问题。
如果你经常处理更大数据(比如 10-100 GB),我们建议你学习更多关于 data.table 的知识。 我们在这里不教它,因为它使用了与 tidyverse 不同的接口,并需要你学习一些不同的约定。 然而,它的速度快得令人难以置信,如果你处理的是大数据,那么花时间学习它是值得的,因为性能上的回报是巨大的。
Python, Julia, 及其他
在本书中,你不会学到任何关于 Python、Julia 或其他可用于数据科学的编程语言的知识。 这并不是因为我们认为这些工具不好。 它们很好! 在实践中,大多数数据科学团队会混合使用多种语言,通常至少包括 R 和 Python。 但我们坚信,一次只精通一个工具是最好的,而 R 是一个很好的起点。
先决条件
为了让你能从本书中获得最大收益,我们对你已有的知识做了一些假设。 你应该具备基本的数学素养,如果你已经有一些基础的编程经验,那将很有帮助。 如果你以前从未编程过,你可能会发现 Garrett 的 《Hands on Programming with R》 是本书的一个有价值的补充读物。
要运行本书中的代码,你需要四样东西:R、RStudio、一个名为 tidyverse 的 R 包集合,以及少数其他包。 包是可重复 R 代码的基本单位。 它们包含可重用的函数、描述如何使用它们的文档以及示例数据。
R
要下载 R,请访问 CRAN,即综合 R 存档网络 (comprehensive R archive network),网址是 https://cloud.r-project.org。 R 每年发布一个新的主版本,每年还有 2-3 个次要版本发布。 定期更新是个好主意。 升级可能会有点麻烦,特别是对于需要重新安装所有包的主版本,但拖延只会让情况变得更糟。 我们建议为本书使用 R 4.2.0 或更高版本。
RStudio
RStudio 是一个用于 R 编程的集成开发环境(IDE),你可以从 https://posit.co/download/rstudio-desktop/ 下载。 RStudio 每年更新几次,当有新版本发布时,它会自动通知你,所以不需要自己去检查。 定期升级以利用最新最好的功能是个好主意。 对于本书,请确保你至少拥有 RStudio 2022.02.0 版本。
当你启动 RStudio 时(见 Figure 2),你会在界面中看到两个关键区域:控制台 (console) 窗格和输出 (output) 窗格。 现在,你只需要知道在控制台窗格中输入 R 代码并按 Enter 键来运行它。 随着学习的深入,你会了解更多。1

The tidyverse
你还需要安装一些 R 包。 R 包 (package) 是一个集函数、数据和文档于一体的集合,它扩展了基础 R 的功能。 使用包是成功使用 R 的关键。 你将在本书中学到的大多数包都是所谓的 tidyverse 的一部分。 tidyverse 中的所有包都共享一个共同的数据和 R 编程哲学,并且被设计为可以协同工作。
你可以用一行代码安装完整的 tidyverse:
install.packages("tidyverse")
在你的计算机上,在控制台中输入这行代码,然后按 Enter 键运行它。 R 将从 CRAN 下载这些包并安装到你的计算机上。
在你用 library()
加载一个包之前,你将无法使用该包中的函数、对象或帮助文件。 一旦你安装了一个包,你可以使用 library()
函数来加载它:
library(tidyverse)
#> ── Attaching core tidyverse packages ───────────────────── tidyverse 2.0.0 ──
#> ✔ dplyr 1.1.4 ✔ readr 2.1.5
#> ✔ forcats 1.0.0 ✔ stringr 1.5.1
#> ✔ ggplot2 3.5.2 ✔ tibble 3.3.0
#> ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
#> ✔ purrr 1.0.4
#> ── Conflicts ─────────────────────────────────────── tidyverse_conflicts() ──
#> ✖ dplyr::filter() masks stats::filter()
#> ✖ dplyr::lag() masks stats::lag()
#> ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
这告诉你 tidyverse 加载了九个包:dplyr、forcats、ggplot2、lubridate、purrr、readr、stringr、tibble、tidyr。 这些被认为是 tidyverse 的核心,因为你在几乎每个分析中都会使用它们。
tidyverse 中的包变化相当频繁。 你可以通过运行 tidyverse_update()
来查看是否有可用的更新。
其他包
还有许多其他优秀的包不属于 tidyverse,因为它们解决不同领域的问题,或者基于一套不同的基本原则设计。 这并不能说明它们是更好还是更差,只是它们不同。 换句话说,tidyverse 的补充不是 messyverse (混乱宇宙),而是许多其他相互关联的包的宇宙。 随着你用 R 处理更多的数据科学项目,你将学习新的包和新的数据思维方式。
我们将在本书中使用许多来自 tidyverse 之外的包。 例如,我们将使用以下包,因为它们为我们学习 R 的过程提供了有趣的数据集:
install.packages(
c(
"arrow", "babynames", "curl", "duckdb", "gapminder",
"ggrepel", "ggridges", "ggthemes", "hexbin", "janitor", "Lahman",
"leaflet", "maps", "nycflights13", "openxlsx", "palmerpenguins",
"repurrrsive", "tidymodels", "writexl"
)
)
我们还将为一些个别例子使用一些其他的包。 你现在不需要安装它们,只需记住,当你看到类似这样的错误时:
你需要运行 install.packages("ggrepel")
来安装这个包。
运行 R 代码
上一节向你展示了几个运行 R 代码的例子。 书中的代码看起来是这样的:
1 + 2
#> [1] 3
如果你在本地控制台中运行同样的代码,它会看起来是这样的:
> 1 + 2
[1] 3
这里有两个主要区别。 在你的控制台中,你在 >
(称为提示符 (prompt))后面输入;我们在书中不显示提示符。 在书中,输出用 #>
注释掉;在你的控制台中,它直接出现在你的代码之后。 这两个区别意味着,如果你正在使用本书的电子版,你可以很容易地从书中复制代码并粘贴到控制台中。
在全书中,我们使用一套一致的约定来引用代码:
其他 R 对象(如数据或函数参数)以代码字体显示,不带括号,如
flights
或x
。有时,为了清楚地表明一个对象来自哪个包,我们会使用包名后跟两个冒号,如
dplyr::mutate()
或nycflights13::flights
。 这也是有效的 R 代码。
致谢
本书不仅是 Hadley、Mine 和 Garrett 的成果,也是我们与 R 社区中许多人进行多次对话(线上和线下)的结果。 我们非常感谢与大家的每一次交流;非常感谢你们!
本书是开放式写作的,许多人通过拉取请求 (pull request) 做出了贡献。特别感谢所有 259 位通过 GitHub 拉取请求(按用户名的字母顺序排列)贡献改进的读者:@a-rosenberg, Tim Becker (@a2800276), Abinash Satapathy (@Abinashbunty), Adam Gruer (@adam-gruer), adi pradhan (@adidoit), A. s. (@Adrianzo), Aep Hidyatuloh (@aephidayatuloh), Andrea Gilardi (@agila5), Ajay Deonarine (@ajay-d), @AlanFeder, Daihe Sui (@alansuidaihe), @alberto-agudo, @AlbertRapp, @aleloi, pete (@alonzi), Alex (@ALShum), Andrew M. (@amacfarland), Andrew Landgraf (@andland), @andyhuynh92, Angela Li (@angela-li), Antti Rask (@AnttiRask), LOU Xun (@aquarhead), @ariespirgel, @august-18, Michael Henry (@aviast), Azza Ahmed (@azzaea), Steven Moran (@bambooforest), Brian G. Barkley (@BarkleyBG), Mara Averick (@batpigandme), Oluwafemi OYEDELE (@BB1464), Brent Brewington (@bbrewington), Bill Behrman (@behrman), Ben Herbertson (@benherbertson), Ben Marwick (@benmarwick), Ben Steinberg (@bensteinberg), Benjamin Yeh (@bentyeh), Betul Turkoglu (@betulturkoglu), Brandon Greenwell (@bgreenwell), Bianca Peterson (@BinxiePeterson), Birger Niklas (@BirgerNi), Brett Klamer (@bklamer), @boardtc, Christian (@c-hoh), Caddy (@caddycarine), Camille V Leonard (@camillevleonard), @canovasjm, Cedric Batailler (@cedricbatailler), Christina Wei (@christina-wei), Christian Mongeau (@chrMongeau), Cooper Morris (@coopermor), Colin Gillespie (@csgillespie), Rademeyer Vermaak (@csrvermaak), Chloe Thierstein (@cthierst), Chris Saunders (@ctsa), Abhinav Singh (@curious-abhinav), Curtis Alexander (@curtisalexander), Christian G. Warden (@cwarden), Charlotte Wickham (@cwickham), Kenny Darrell (@darrkj), David Kane (@davidkane9), David (@davidrsch), David Rubinger (@davidrubinger), David Clark (@DDClark), Derwin McGeary (@derwinmcgeary), Daniel Gromer (@dgromer), @Divider85, @djbirke, Danielle Navarro (@djnavarro), Russell Shean (@DOH-RPS1303), Zhuoer Dong (@dongzhuoer), Devin Pastoor (@dpastoor), @DSGeoff, Devarshi Thakkar (@dthakkar09), Julian During (@duju211), Dylan Cashman (@dylancashman), Dirk Eddelbuettel (@eddelbuettel), Edwin Thoen (@EdwinTh), Ahmed El-Gabbas (@elgabbas), Henry Webel (@enryH), Ercan Karadas (@ercan7), Eric Kitaif (@EricKit), Eric Watt (@ericwatt), Erik Erhardt (@erikerhardt), Etienne B. Racine (@etiennebr), Everett Robinson (@evjrob), @fellennert, Flemming Miguel (@flemmingmiguel), Floris Vanderhaeghe (@florisvdh), @funkybluehen, @gabrivera, Garrick Aden-Buie (@gadenbuie), Peter Ganong (@ganong123), Gerome Meyer (@GeroVanMi), Gleb Ebert (@gl-eb), Josh Goldberg (@GoldbergData), bahadir cankardes (@gridgrad), Gustav W Delius (@gustavdelius), Hao Chen (@hao-trivago), Harris McGehee (@harrismcgehee), @hendrikweisser, Hengni Cai (@hengnicai), Iain (@Iain-S), Ian Sealy (@iansealy), Ian Lyttle (@ijlyttle), Ivan Krukov (@ivan-krukov), Jacob Kaplan (@jacobkap), Jazz Weisman (@jazzlw), John Blischak (@jdblischak), John D. Storey (@jdstorey), Gregory Jefferis (@jefferis), Jeffrey Stevens (@JeffreyRStevens), 蒋雨蒙 (@JeldorPKU), Jennifer (Jenny) Bryan (@jennybc), Jen Ren (@jenren), Jeroen Janssens (@jeroenjanssens), @jeromecholewa, Janet Wesner (@jilmun), Jim Hester (@jimhester), JJ Chen (@jjchern), Jacek Kolacz (@jkolacz), Joanne Jang (@joannejang), @johannes4998, John Sears (@johnsears), @jonathanflint, Jon Calder (@jonmcalder), Jonathan Page (@jonpage), Jon Harmon (@jonthegeek), JooYoung Seo (@jooyoungseo), Justinas Petuchovas (@jpetuchovas), Jordan (@jrdnbradford), Jeffrey Arnold (@jrnold), Jose Roberto Ayala Solares (@jroberayalas), Joyce Robbins (@jtr13), @juandering, Julia Stewart Lowndes (@jules32), Sonja (@kaetschap), Kara Woo (@karawoo), Katrin Leinweber (@katrinleinweber), Karandeep Singh (@kdpsingh), Kevin Perese (@kevinxperese), Kevin Ferris (@kferris10), Kirill Sevastyanenko (@kirillseva), Jonathan Kitt (@KittJonathan), @koalabearski, Kirill Müller (@krlmlr), Rafał Kucharski (@kucharsky), Kevin Wright (@kwstat), Noah Landesberg (@landesbergn), Lawrence Wu (@lawwu), @lindbrook, Luke W Johnston (@lwjohnst86), Kara de la Marck (@MarckK), Kunal Marwaha (@marwahaha), Matan Hakim (@matanhakim), Matthias Liew (@MatthiasLiew), Matt Wittbrodt (@MattWittbrodt), Mauro Lepore (@maurolepore), Mark Beveridge (@mbeveridge), @mcewenkhundi, mcsnowface, PhD (@mcsnowface), Matt Herman (@mfherman), Michael Boerman (@michaelboerman), Mitsuo Shiota (@mitsuoxv), Matthew Hendrickson (@mjhendrickson), @MJMarshall, Misty Knight-Finley (@mkfin7), Mohammed Hamdy (@mmhamdy), Maxim Nazarov (@mnazarov), Maria Paula Caldas (@mpaulacaldas), Mustafa Ascha (@mustafaascha), Nelson Areal (@nareal), Nate Olson (@nate-d-olson), Nathanael (@nateaff), @nattalides, Ned Western (@NedJWestern), Nick Clark (@nickclark1000), @nickelas, Nirmal Patel (@nirmalpatel), Nischal Shrestha (@nischalshrestha), Nicholas Tierney (@njtierney), Jakub Nowosad (@Nowosad), Nick Pullen (@nstjhp), @olivier6088, Olivier Cailloux (@oliviercailloux), Robin Penfold (@p0bs), Pablo E. Garcia (@pabloedug), Paul Adamson (@padamson), Penelope Y (@penelopeysm), Peter Hurford (@peterhurford), Peter Baumgartner (@petzi53), Patrick Kennedy (@pkq), Pooya Taherkhani (@pooyataher), Y. Yu (@PursuitOfDataScience), Radu Grosu (@radugrosu), Ranae Dietzel (@Ranae), Ralph Straumann (@rastrau), Rayna M Harris (@raynamharris), @ReeceGoding, Robin Gertenbach (@rgertenbach), Jajo (@RIngyao), Riva Quiroga (@rivaquiroga), Richard Knight (@RJHKnight), Richard Zijdeman (@rlzijdeman), @robertchu03, Robin Kohrs (@RobinKohrs), Robin (@Robinlovelace), Emily Robinson (@robinsones), Rob Tenorio (@robtenorio), Rod Mazloomi (@RodAli), Rohan Alexander (@RohanAlexander), Romero Morais (@RomeroBarata), Albert Y. Kim (@rudeboybert), Saghir (@saghirb), Hojjat Salmasian (@salmasian), Jonas (@sauercrowd), Vebash Naidoo (@sciencificity), Seamus McKinsey (@seamus-mckinsey), @seanpwilliams, Luke Smith (@seasmith), Matthew Sedaghatfar (@sedaghatfar), Sebastian Kraus (@sekR4), Sam Firke (@sfirke), Shannon Ellis (@ShanEllis), @shoili, Christian Heinrich (@Shurakai), S’busiso Mkhondwane (@sibusiso16), SM Raiyyan (@sm-raiyyan), Jakob Krigovsky (@sonicdoe), Stephan Koenig (@stephan-koenig), Stephen Balogun (@stephenbalogun), Steven M. Mortimer (@StevenMMortimer), Stéphane Guillou (@stragu), Sulgi Kim (@sulgik), Sergiusz Bleja (@svenski), Tal Galili (@talgalili), Alec Fisher (@Taurenamo), Todd Gerarden (@tgerarden), Tom Godfrey (@thomasggodfrey), Tim Broderick (@timbroderick), Tim Waterhouse (@timwaterhouse), TJ Mahr (@tjmahr), Thomas Klebel (@tklebel), Tom Prior (@tomjamesprior), Terence Teo (@tteo), @twgardner2, Ulrik Lyngs (@ulyngs), Shinya Uryu (@uribo), Martin Van der Linden (@vanderlindenma), Walter Somerville (@waltersom), @werkstattcodes, Will Beasley (@wibeasley), Yihui Xie (@yihui), Yiming (Paul) Li (@yimingli), @yingxingwu, Hiroaki Yutani (@yutannihilation), Yu Yu Aung (@yuyu-aung), Zach Bogart (@zachbogart), @zeal626, Zeki Akyol (@zekiakyol).
版本说明
本书的在线版本可在 https://r4ds.hadley.nz 查看。 在实体书的再版之间,它会持续更新。 本书的源代码可在 https://github.com/hadley/r4ds 获取。 本书由 Quarto 驱动,这使得编写结合文本和可执行代码的书籍变得容易。
如果你想全面了解 RStudio 的所有功能,请参阅 RStudio 用户指南:https://docs.posit.co/ide/user。↩︎