跳至主要内容

在 R 中合并数据集

在本教程中,您将学习如何在 R 中连接多个数据集。
· 8分钟 阅读

使用 AI 探索

在实际应用中,数据分散存放在不同服务器、不同文件中。当所需数据来自多个来源时,掌握如何聚合它们至关重要,这样既能尽量减少信息损失,又能依据数据结构进行合理配对。

本教程将带您了解:

  • 横向与纵向合并数据集
  • 什么是主键,以及它如何为数据增添结构
  • 不同类型的连接(如 left-join、inner-join、full-join)及其选择方法
  • 需要留意的一个常见问题及其解决办法

拼接数据集

从高层来看,合并数据集有两种方式:通过添加行来增加信息,或通过添加列来增加信息。一般而言,当多个数据集具有相同的列集合或相同的观测集合时,您可以分别将它们纵向或横向拼接。让我们通过示例来学习。

纵向添加数据集

当您拥有多个具有相同列集合的数据集时,可以将一个数据集纵向拼接到另一个数据集上。也就是说,保留数据集的列,并向其中添加更多行。将此类信息放在同一个文件中,有助于您更轻松地聚合数据、把握全局,而无需在多个文件之间来回切换并丢失线索。

数据集 1

MakeNum models
Honda63
BMW10

数据集 2

MakeNum models
Ford26
Tesla4

需要注意的是,如果多个数据集中包含相同的观测,并且您使用 rbind() 进行纵向拼接,最终表中会出现重复观测。尽管两个数据集必须拥有相同的变量集合(即列),但列的顺序并不要求一致。请在下面的控制台中亲自验证!

在您的工作区中,已提供上面看到的两个数据集 dataset1 和 dataset2。请尝试调整 dataset1 的列顺序。分别对 dataset1 与 dataset2,以及 reordered_dataset1 与 dataset2 调用 rbind()。


            # Add datasets vertically
            rbind(dataset1, dataset2)

            # Reorder columns
            reordered_dataset1 <- dataset1[, c(2, 1)]

            # See that rbind() is robust to column ordering
            rbind(reordered_dataset1, dataset2)
            

在执行 rbind() 之后,您的结果应当把四个车系整合到同一张表中,如下所示:

纵向拼接后的数据集

MakeNum models
Honda63
BMW10
Ford26
Tesla4

横向添加数据集

当多个数据集代表相同的一组观测时,您可以将它们横向拼接。这一次,保留数据集的行,并为其添加更多列。在这种情况下,您需要检查各数据集观测的顺序是否一致。若数据集的行数不同,或行数相同但排序不一致,就可能把一组列与另一组列进行不合理的配对。

让我们延续上面的示例。假设您有两个数据文件:一个包含车系及其独特车型数量,另一个包含车系及其总销量:

提供的独特车型数量

MakeNum models
Honda63
BMW10
Ford26
Tesla4

总销量

MakeSales
Ford119157
BMW25908
Honda188328
Tesla29975

需要注意的是,如果多个数据集中包含相同的观测,并且您使用 cbind() 进行横向拼接,最终表中会出现冗余列。虽然两个数据集包含相关信息,但行的顺序非常重要!

在下面的控制台中,对 models 和 sales 调用 cbind() 并打印结果:


            # Add datasets horizontally
            cbind(models, sales)
            

您应当会看到类似如下的结果:

Models & Sales

MakeNum modelsMakeSales
Honda63Ford119157
BMW10BMW25908
Ford26Honda188328
Tesla4Tesla29975

您看到问题了吗?这些数据并不整洁!

根据这门基础课程中讲授的整洁数据原则,数据集中的每条观测都应当在唯一一行中表示。再者,如果您只在一个数据集的部分行上有信息,并希望仅为这些行添加信息该怎么办?换句话说,如果您想从一个数据集中为另一个数据集添加更多列,但这两个数据集的观测数量并不相同,又该如何处理?

主键与外键

在尝试合并数据集时,第一步是寻找数据集的主键。主键是能唯一标识数据集中每条观测的列或列的组合。在车系、独特车型数量和总销量的示例中,数据集的主键是 make 列。

现在,我们可以执行连接,这是将数据集合并为单一表的标准方式。

连接的类型

连接的类型有很多。您可以在 Joining Data in R with dplyr 课程中,学习如何使用变异连接从一个数据集补充另一个数据集的列,如何使用过滤连接在数据集之间进行筛选,以及如何使用集合运算在数据集间取舍。下面是一些最常见的类型。

left_join(x, y):返回 x 的所有行,以及来自 x 和 y 的所有列。在 y 中没有匹配项的 x 行,其新列将填充 NA。如果 x 与 y 之间存在多重匹配,则返回所有匹配组合。

inner_join(x, y):返回在 y 中存在匹配值的 x 的所有行,以及来自 x 和 y 的所有列。如果 x 与 y 之间存在多重匹配,则返回所有匹配组合。

full_join(x, y):返回 x 和 y 的所有行与所有列。若无匹配值,缺失一方将返回 NA。

上述连接属于变异连接,因为它们会将两个数据集的变量合并在一起。

缺失键

假设您有两个数据集。第一个数据集名为 size,包含人名及其衣服尺码:

 > size
name size
1  Tom    M
2  Dan   XL
3 Keil    S

第二个数据集名为 color,包含人们的姓氏、衬衫颜色偏好,并在 row.names 属性中存储了一些信息:

 > color
     surname color
Tom     Jeon  <NA>
Dan    Smith  Dark
Bob McLadden Light

注意这里可能出现什么问题了吗?当存在缺失键或重复键时,双表连接会变得复杂。在此示例中,R 的数据框会在 row.names 属性中存储重要信息。在这种情况下,您无法使用连接函数访问该键,因为连接函数只能访问数据框的列。

轻松解决该问题的技巧是使用 tibble 包中的 rownames_to_column() 函数。它会返回您的数据集副本,并将行名作为一列添加到数据中。rownames_to_column() 的第一个参数是数据框对象,第二个参数是一个字符串,用于指定要添加的列名。

请在下面的控制台中探索。数据集 size 与 color 已预加载到您的工作区。


            # Explore here!

            

最后的思考

在现实世界中,数据可能被拆分在多个数据集、多个不同格式中。由于 R 的设计是围绕单一数据表来工作的,将多个数据集整理并合并为一张表是一项必备技能。完成 Importing & Cleaning Data with R 技能路径,学习解析与合并任意格式的数据。查看 DataCamp 的 R 数据导入 教程。学习愉快!

主题