Logo
Section 1 / 9

Tidyverse 概述

了解 tidyverse 是什么,什么是整洁数据,以及它如何让 R 中的数据科学工作更加有条理、易读且高效。

导入

Tidyverse 概述

了解 tidyverse 是什么,什么是整洁数据,以及它如何让 R 中的数据科学工作更加有条理、易读且高效。

让我们来了解一下 tidyverse 是什么。

tidyverse 是一组为 R 语言设计的包,它们能够无缝协作,使数据操作和可视化更加一致、逻辑清晰且易于阅读。虽然 tidyverse 不是 R 中唯一的数据处理方式,事实上许多 R 用户并不使用 tidyverse,而是坚持使用基础 R,并在其之上叠加其他包。实际上,我们已经具备了在 R 中完成许多分析所需的技能。然而,在数据科学的背景下,转向 tidyverse 有许多显著优势。

一个很快就会发现的事实是:在不使用 tidyverse 的情况下,我们的代码中很大一部分都在进行函数输出到输入之间的转换。而 tidyverse 的核心目标正是通过保持一致性来解决这一问题。它让我们能更专注于分析本身,而不是繁琐的数据处理。

...
The tidyverse logo

对数据科学家来说,一个普遍的经验法则是:大约 80% 的代码都用于数据清洗,也就是将数据“整理”好。tidyverse 能帮助我们将这部分工作减少,从而让我们更专注于分析。tidyverse 中体现的标准化也体现在我们调用和使用各个包中的函数的方式上。这一点非常有价值,因为这意味着无论函数来自哪个包,其结构都与其他 tidyverse 包中的函数保持一致。因此:

  • 学习新的 tidyverse 包和函数变得更加容易——惊喜更少。
  • 即使同事不熟悉具体使用的包,也能轻松理解我们的代码。
  • 一个函数设计的输入可以直接作为另一个函数的输入,一个函数的输出也能直接流入下一个函数,从而减少中间代码来重新组织数据的需求。

此外,tidyverse 还提供了一些其他重要优势。其中之一是其强大的可视化和交互式绘图包。这些包是 R 中制作美观图表的行业标准,因此我们将在后续课程中重点学习如何使用它们。

tidyverse 的核心标准化体现在我们如何组织数据。要使用 tidyverse,我们需要“整洁的数据”——这也是名称的由来。一旦数据变为整洁形式,tidyverse 中的所有函数都会保持这种形式,所有函数也都专门为此种结构设计。整洁数据遵循以下规则:

  • 每一列是一个变量。
  • 每一行是一个观测值。
  • 每个单元格包含单一值。

不整洁或混乱的数据,则指不符合上述条件的任何数据。

让我们暂停一下,深入探讨这一点。数据框可以以任意方式组织。如果我们有调查数据,可以把每一列当作一个问题,也可以把每一列当作一行。但现在我们要转向 tidyverse,因此需要整洁的数据。根据定义,整洁数据赋予了行和列明确的意义。如果每个受访者对一组问题的回答构成一个观测值(变量),那么为了保持数据整洁,行必须代表受访者,列必须代表问题的答案。

1# 读取 'MySurveyData.csv' 文件, 2# 存储在名为 Var_SurveyData 的变量中 3VAR_SurveyDataTidy <- read.csv("MySurveyData.csv", 4 header = TRUE, row.names = 1, 5 stringsAsFactors = FALSE) 6 7# 将数据转置,使其变得“不整洁” 8VAR_SurveyDataUntidy <- t(VAR_SurveyDataTidy) 9 10# 打印整洁的数据 11print("这是整洁的数据") 12VAR_SurveyDataTidy 13 14# 打印不整洁的数据 15print("这是混乱的数据") 16VAR_SurveyDataUntidy

在上面的例子中:

  • 第 3–5 行:我们将一个 CSV 文件读入数据框。
  • 第 8 行:通过转置数据使其变得不整洁。此时观测值不再位于行中,变量也不再位于列中。
  • 第 12 和 16 行:打印整洁与不整洁数据的示例。

再看另一个例子:我们反复将一颗弹珠滚过一张桌子,并测量其在桌面上的最终 x 和 y 坐标。一个整洁的数据集应包含列 roll、final_x 和 final_y,每一行代表一次弹珠滚动。每次滚动是一个观测值,我们测量的变量是 final_x 和 final_y。

1# 读取 'Dice Data' CSV 文件 2# 存储在变量 VAR_DiceData 中 3VAR_DiceData <- read.csv("DiceData.csv") 4 5# 将 X 和 Y 位置列合并为一列 6# 使数据变得不整洁 7VAR_DiceDataCombined <- data.frame(XY_POS = paste(VAR_DiceData$X_POS, 8 VAR_DiceData$Y_POS, sep = ",")) 9 10# 打印整洁的数据 11print("这是整洁的数据") 12VAR_DiceData[1:10,] 13 14# 打印不整洁的数据,因为数据已被转置 15print("这是混乱的数据") 16t(VAR_DiceData[1:10,]) 17 18# 打印不整洁的数据,因为 X 和 Y 位置数据 19# 已被合并为单列 20print("这也是混乱的数据") 21VAR_DiceDataCombined[1:10,]

在这个例子中,我们读取了骰子数据,然后通过两种方式将其变得不整洁:一是转置数据,二是将两个变量合并为一列。

  • 第 7–8 行:将两个变量合并为一列,使数据变得不整洁。
  • 第 16–21 行:打印整洁与不整洁数据的示例。

tidyverse 的核心思想就是围绕“整洁数据集”展开。我们或许会对某些规则持有不同意见,但关键不在于规则本身,而在于拥有一个统一的结构。这种统一结构让我们能够获得前述的各种好处。

现在我们很快会发现,实际工作中很少有数据是以整洁的形式直接到达数据科学家手中的。按照我们的定义,它们往往都是混乱的。而在实践中,tidyverse 会让我们把数据清洗步骤提前到代码的最开始,从而减少整体的数据整理工作量。

1# 加载基础的 tidyverse 库 2library(ggplot2) 3library(purrr) 4library(tibble) 5suppressPackageStartupMessages(library(dplyr)) 6library(tidyr) 7library(stringr) 8library(readr) 9library(forcats) 10 11?dplyr 12 13?tidyr

注意:我们使用 suppressPackageStartupMessages 包裹了 dplyr 包的加载。dplyr 包在加载时会输出大量信息,这个包裹可以屏蔽这些提示消息。

在上面的代码片段中,我们通过加载各个核心包来引入 tidyverse。同时,我们也请求了部分包的帮助文档:dplyr 和 tidyr。

  • 第 2–9 行:加载构成 tidyverse 核心的包。
  • 第 11 和 13 行:分别打印 dplyr 和 tidyr 的帮助文档。

现在我们可以将数据清洗工作与核心分析任务区分开来。诸如拆分单个单元格中合并的值、修正拼写错误、填补缺失值等操作,都可以在进入分析核心之前完成。这是因为这些步骤不需要在分析的不同部分重复执行,也不需要以不同形式进行,因此我们可以尽早完成它们,从而让后续分析更加高效。

R 基础

特殊数据类型——tibbles