R语言中的表连接

点击下载本文全部代码

一、表连接

在科研中,常常需要将两个表根据某个/些字段进行连接(如将气象站点的坐标与站点的降水值进行连接)。在R中有许多函数可以实现这一功能,如merge()setkey()等,其中dplyr包有一套完整的join系列函数,因此更便于学习。

首先需要明确以下几种连接的含义,x与y分别为需要连接的两个表:

  • 内连接:仅保留x与y中相匹配的观测

  • 左连接:保留x中所有观测,y中保留匹配的观测

  • 右连接:保留y中所有观测,x中保留匹配的观测

  • 全连接:x和y中所有观测都保留

  • 反连接:仅保留x与y中不匹配的观测

     

二、dplyr包中的表连接函数

dplyr包主要包括以下几个join函数:

  • inner_join(x, y, by  …)

  • left_join(x, y, by  …)

  • right_join(x, y, by  …)

  • full_join(x, y, by …)

  • anti_join(x, y, by …)

 

三、实践应用

以下代码逐一介绍了不同join函数的用法,同时条件各不相同。

1. inner_join()

所有join系列函数中,x与y分别为两个表,by属性设置用于连接的字段。

> library(dplyr)
> 
> student <- data.frame(
+   name = c("张三", "李四", "王五", "马六"),
+   score = c(65, 70, 61, 98))
> 
> class <- data.frame(
+   name = c("张三", "王五", "马六", "小明"),
+   grade = c("三年级", "二年级", "四年级", "四年级"))
> 
> inner_join(student, class, by = "name")
  name score  grade
1 张三    65 三年级
2 王五    61 二年级
3 马六    98 四年级

2. left_join()

需要保留用于连接的两个字段,使用keep = TURE

> library(dplyr)
> 
> student <- data.frame(
+   name = c("张三", "李四", "王五", "马六"),
+   score = c(65, 70, 61, 98))
> 
> class <- data.frame(
+   name = c("张三", "王五", "马六", "小明"),
+   grade = c("三年级", "二年级", "四年级", "四年级"))
> 
> left_join(student, class, by = "name", keep = TRUE)
  name.x score name.y  grade
1   张三    65   张三 三年级
2   李四    70   <NA>   <NA>
3   王五    61   王五 二年级
4   马六    98   马六 四年级

3. right_join()

两个表中用于连接的字段名有差异,使用by = c("x字段名" = "y字段名")连接。

> library(dplyr)
> 
> student <- data.frame(
+   name1 = c("张三", "李四", "王五", "马六"),
+   score = c(65, 70, 61, 98))
> 
> class <- data.frame(
+   name2 = c("张三", "王五", "马六", "小明"),
+   grade = c("三年级", "二年级", "四年级", "四年级"))
> 
> right_join(student, class, by = c("name1" = "name2"))
  name1 score  grade
1  张三    65 三年级
2  王五    61 二年级
3  马六    98 四年级
4  小明    NA 四年级

4. full_join()

有多个连接字段时,by属性使用一个包含字段名的向量对象。

> library(dplyr)
> 
> student <- data.frame(
+   name = c("张三", "李四", "王五", "马六"),
+   sex = c("男", "男", "女", "男"),
+   score = c(65, 70, 61, 98))
> 
> class <- data.frame(
+   name = c("张三", "王五", "马六", "小明"),
+   sex = c("男", "男", "男", "女"),
+   grade = c("三年级", "二年级", "四年级", "四年级"))
> 
> full_join(student, class, by = c("name", "sex"))
  name sex score  grade
1 张三  男    65 三年级
2 李四  男    70   <NA>
3 王五  女    61   <NA>
4 马六  男    98 四年级
5 王五  男    NA 二年级
6 小明  女    NA 四年级

5. anti_join()

最后是同时需要两个字段连接,且字段名均不同的情况。

> library(dplyr)
> 
> student <- data.frame(
+   name1 = c("张三", "李四", "王五", "马六"),
+   sex1 = c("男", "男", "女", "男"),
+   score = c(65, 70, 61, 98))
> 
> class <- data.frame(
+   name2 = c("张三", "王五", "马六", "小明"),
+   sex2 = c("男", "男", "男", "女"),
+   grade = c("三年级", "二年级", "四年级", "四年级"))
> 
> anti_join(student, class, keep = True,
+            by = c("name1" = "name2","sex1" = "sex2"))
  name1 sex1 score
1  李四   男    70
2  王五   女    61
Xiaoran Wu
Xiaoran Wu
Master’s student