Dplyr 教程:使用示例在 R 中合并和连接数据

数据分析导论

数据分析可以分为三个部分:

  • 提取:首先,我们需要从多个来源收集数据并将它们结合起来。
  • 改造:此步骤涉及数据处理。一旦我们整合了所有数据源,我们就可以开始清理数据。
  • 可视化:最后一步是将我们的数据可视化以检查是否存在异常。
数据分析流程
数据分析流程

数据科学家面临的最大挑战之一是数据处理。数据永远无法以所需的格式提供。数据科学家需要花费至少一半的时间来清理和处理数据。这是工作中最关键的任务之一。如果数据处理过程不完整、不精确和不严格,模型将无法正确运行。

分布式计算

R 有一个名为 dplyr 的库来帮助进行数据转换。dplyr 库基本上是围绕四个用于操作数据的函数和五个用于清理数据的动词创建的。之后,我们可以使用 ggplot 库来分析和可视化数据。

我们将学习如何使用 dplyr 库来操作 数据帧.

使用 R Dplyr 合并数据

dplyr 提供了一种很好且方便的方法来合并数据集。我们可能有许多输入数据源,在某些时候,我们需要将它们合并。使用 dplyr 的连接会在原始数据集的右侧添加变量。

Dplyr 连接

以下是 dplyr 中用于合并两个数据集的四种重要连接类型:

功能 目的 参数 多个按键
左连接() 合并两个数据集。保留原表中的所有观测值 数据,来源,目的地,按 = “ID” 出发地,目的地,by = c(“ID”, “ID2”)
right_join() 合并两个数据集。保留目标表中的所有观测值 数据,来源,目的地,按 = “ID” 出发地,目的地,by = c(“ID”, “ID2”)
内部联接() 合并两个数据集。排除所有不匹配的行 数据,来源,目的地,按 = “ID” 出发地,目的地,by = c(“ID”, “ID2”)
完整连接() 合并两个数据集。保留所有观察结果 数据,来源,目的地,按 = “ID” 出发地,目的地,by = c(“ID”, “ID2”)

我们将通过一个简单的例子研究所有的连接类型。

首先,我们建立两个数据集。表 1 包含两个变量,ID 和 y,而表 2 收集 ID 和 z。在每种情况下,我们都需要有一个 密钥对 变量。在我们的例子中,ID 是我们的 变量。该函数将在两个表中查找相同的值,并将返回值绑定到表 1 的右侧。

使用 R Dplyr 合并数据

library(dplyr)
df_primary <- tribble(
  ~ID, ~y,
   "A", 5,
   "B", 5,
   "C", 8,
   "D", 0,
  "F", 9)
df_secondary <- tribble(
  ~ID, ~z,
   "A", 30,
   "B", 21,
   "C", 22,
   "D", 25,
   "E", 29)

Dplyr left_join()

合并两个数据集的最常见方法是使用 left_join() 函数。从下图中我们可以看到,键对与两个数据集中的行 A、B、C 和 D 完全匹配。但是,E 和 F 被遗漏了。我们如何处理这两个观察结果?使用 left_join(),我们将保留原始表中的所有变量,而不考虑目标表中没有键对的变量。在我们的示例中,变量 E 在表 1 中不存在。因此,该行将被删除。变量 F 来自原始表;它将在 left_join() 之后保留并在 z 列中返回 NA。下图重现了使用 left_join() 时将发生的情况。

dplyr left_join() 示例

dplyr left_join() 示例

left_join(df_primary, df_secondary, by ='ID')

输出:

## 
# A tibble: 5 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>		
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25
## 5     F     9    NA

Dplyr right_join()

right_join() 函数的工作原理与 left_join() 完全相同。唯一的区别是删除了行。目标数据框中可用的值 E 存在于新表中,并为 y 列取值 NA。

dplyr right_join() 的示例

dplyr right_join() 的示例

right_join(df_primary, df_secondary, by = 'ID')

输出:

##
# A tibble: 5 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25
## 5     E    NA    29

Dplyr inner_join()

当我们 100% 确定两个数据集不匹配时,我们可以考虑返回 仅由 存在于的行 数据集。当我们需要一个干净的数据集或者我们不想用平均值或中位数填补缺失值时,这是可能的。

inner_join() 可以提供帮助。此函数排除不匹配的行。

dplyr inner_join() 的示例

dplyr inner_join() 的示例

inner_join(df_primary, df_secondary, by ='ID')

输出:

## 
# A tibble: 4 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25

Dplyr full_join()

最后,full_join() 函数保留所有观察结果并用 NA 替换缺失值。

dplyr full_join() 示例

dplyr full_join() 示例

full_join(df_primary, df_secondary, by = 'ID')

输出:

## # A tibble: 6 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25
## 5     F     9    NA
## 6     E    NA    29

多个密钥对

最后但同样重要的是,我们的数据集中可以有多个键。考虑以下数据集,其中有年份或客户购买的产品列表。

R 中的多个密钥对

如果我们尝试合并两个表,R 会抛出错误。为了解决这个问题,我们可以传递两个键对变量。即出现在两个数据集中的 ID 和年份。我们可以使用以下代码合并表 1 和表 2

df_primary <- tribble(
  ~ID, ~year, ~items,
  "A", 2015,3,
  "A", 2016,7,
  "A", 2017,6,
  "B", 2015,4,
  "B", 2016,8,
  "B", 2017,7,
  "C", 2015,4,
  "C", 2016,6,
  "C", 2017,6)
df_secondary <- tribble(
  ~ID, ~year, ~prices,
  "A", 2015,9,
  "A", 2016,8,
  "A", 2017,12,
  "B", 2015,13,
  "B", 2016,14,
  "B", 2017,6,
  "C", 2015,15,
  "C", 2016,15,
  "C", 2017,13)
left_join(df_primary, df_secondary, by = c('ID', 'year'))

输出:

## # A tibble: 9 x 4
##      ID  year items prices
##   <chr> <dbl> <dbl>  <dbl>
## 1     A  2015     3      9
## 2     A  2016     7      8
## 3     A  2017     6     12
## 4     B  2015     4     13
## 5     B  2016     8     14
## 6     B  2017     7      6
## 7     C  2015     4     15
## 8     C  2016     6     15
## 9     C  2017     6     13

R 中的数据清理函数

以下是整理(清理)数据的四个重要函数:

功能 目的 参数
收集() 将数据从宽转换为长 (数据,键,值,na.rm = FALSE)
传播() 将数据从长变为宽 (数据,键,值)
分离() 将一个变量拆分为两个 (数据,col,进入,sep =“”,删除 = TRUE)
单元() 把两个变量合并为一个 (数据,col,浓度,sep =“”,删除 = TRUE)

我们使用 tidyr 库。此库属于用于操作、清理和可视化数据的库集合。如果我们使用 anaconda 安装 R,则该库已安装。我们可以在此处找到该库, https://anaconda.org/r/r-tidyr.

如果尚未安装,请输入以下命令来安装 tidyr:

install tidyr : install.packages("tidyr")

收集()

gather() 函数的目标是将数据从宽转换为长。

句法

gather(data, key, value, na.rm = FALSE)
Arguments:
-data: The data frame used to reshape the dataset 
-key: Name of the new column created
-value: Select the columns used to fill the key column
-na.rm: Remove missing values. FALSE by default

例如:

下面,我们可以直观地看到将宽重塑为长的概念。我们想要创建一个名为“增长”的列,由季度变量的行填充。

R 中的 gather() 函数示例

library(tidyr)
# Create a messy dataset
messy <- data.frame(
  country = c("A", "B", "C"),
  q1_2017 = c(0.03, 0.05, 0.01),
  q2_2017 = c(0.05, 0.07, 0.02),
  q3_2017 = c(0.04, 0.05, 0.01),
  q4_2017 = c(0.03, 0.02, 0.04))
messy

输出:

##   country q1_2017 q2_2017 q3_2017 q4_2017
## 1       A    0.03    0.05    0.04    0.03
## 2       B    0.05    0.07    0.05    0.02
## 3       C    0.01    0.02    0.01    0.04
# Reshape the data
tidier <-messy %>%
gather(quarter, growth, q1_2017:q4_2017)
tidier

输出:

##    country quarter growth
## 1        A q1_2017   0.03
## 2        B q1_2017   0.05
## 3        C q1_2017   0.01
## 4        A q2_2017   0.05
## 5        B q2_2017   0.07
## 6        C q2_2017   0.02
## 7        A q3_2017   0.04
## 8        B q3_2017   0.05
## 9        C q3_2017   0.01
## 10       A q4_2017   0.03
## 11       B q4_2017   0.02
## 12       C q4_2017   0.04

在 gather() 函数中,我们创建了两个新变量 quarter 和 growth,因为我们的原始数据集有一个组变量:即 country 和键值对。

传播()

spread() 函数的作用与 gather 相反。

句法

spread(data, key, value)
arguments: 
data: The data frame used to reshape the dataset
key: Column to reshape long to wide
value: Rows used to fill the new column

例如:

我们可以使用 spread() 将整洁的数据集重塑为混乱的数据集

# Reshape the data
messy_1 <- tidier %>%
  spread(quarter, growth) 
messy_1

输出:

##   country q1_2017 q2_2017 q3_2017 q4_2017
## 1       A    0.03    0.05    0.04    0.03
## 2       B    0.05    0.07    0.05    0.02
## 3       C    0.01    0.02    0.01    0.04

分离()

函数separate()根据分隔符将一列拆分为两列。当变量为日期时,此函数非常有用。我们的分析可能需要关注月份和年份,我们希望将列拆分为两个新变量。

句法

separate(data, col, into, sep= "", remove = TRUE)
arguments:
-data: The data frame used to reshape the dataset 
-col: The column to split
-into: The name of the new variables
-sep: Indicates the symbol used that separates the variable, i.e.:  "-", "_", "&"
-remove: Remove the old column. By default sets to TRUE.

例如:

我们可以通过应用separate()函数将整洁数据集中的季度与年份分开。

separate_tidier <-tidier %>%
separate(quarter, c("Qrt", "year"), sep ="_")
head(separate_tidier)

输出:

##   country Qrt year growth
## 1       A  q1 2017   0.03
## 2       B  q1 2017   0.05
## 3       C  q1 2017   0.01
## 4       A  q2 2017   0.05
## 5       B  q2 2017   0.07
## 6       C  q2 2017   0.02

团结()

unite() 函数将两列合并为一列。

句法

unit(data, col, conc ,sep= "", remove = TRUE)
arguments:
-data: The data frame used to reshape the dataset 
-col: Name of the new column
-conc: Name of the columns to concatenate
-sep: Indicates the symbol used that unites the variable, i.e:  "-", "_", "&"
-remove: Remove the old columns. By default, sets to TRUE

例如:

在上面的例子中,我们将季度和年份分开。如果我们想合并它们怎么办?我们使用以下代码:

unit_tidier <- separate_tidier %>%
  unite(Quarter, Qrt, year, sep ="_")
head(unit_tidier)

输出:

##   country Quarter growth
## 1       A q1_2017   0.03
## 2       B q1_2017   0.05
## 3       C q1_2017   0.01
## 4       A q2_2017   0.05
## 5       B q2_2017   0.07
## 6       C q2_2017   0.02

总结

  • 数据分析 可以分为三个部分:提取(Extraction),变换(Transform),可视化(Visualize)。
  • R 有一个名为 dplyr 的库,可帮助进行数据转换。dplyr 库基本上是围绕四个用于操作数据的函数和五个用于清理数据的动词创建的。
  • dplyr 提供了一种很好且方便的方法来合并数据集。使用 dplyr 进行连接会在原始数据集的右侧添加变量。
  • dplyr 的优点在于它可以处理四种类型的连接,类似于 SQL:
    • 左连接() – 合并两个数据集并保留原始表中的所有观测值。
    • right_join() – 合并两个数据集并保留目标表中的所有观察结果。
    • 内部联接() – 合并两个数据集并排除所有不匹配的行。
    • 完整连接() – 合并两个数据集并保留所有观察结果。
  • 使用 tidyr 库,您可以使用以下函数转换数据集:
    • 收集():将数据由宽型转换为长型。
    • 传播():将数据从长型转换为宽型。
    • 分离():将一个变量拆分为两个。
    • 单元():将两个变量合并为一个。