数据分析中的"国道"—连接
前沿介绍
有时候我们需要/关注的数据不是在一个数据表格中,而是在不同的表格中。例如在高通量测序数据分析时经常是OTU测序的reads在一个表格,而分类信息在另一个表格;或者我们已知道了经纬度数据,但是需要的年平均温度、年降雨量等数据在WorldClim数据库中。此时如何根据已有的样方名、经纬度等“键”信息找到需要的数据呢?
熟悉excel的朋友们大概对VLOOKUP函数不陌生,该函数就能够实现部分类似于连接的功能。但是VLOOKUP无法处理更大的数据,也没办法直接处理存在两个“键”以上情况的数据。
什么是“键”?键就是连接两个数据的关键列,如"样方"所在的列,如"经度" 和“纬度”等。由此可见键的特点一般是unique的,所以判断某一列是否能作为键,首先需要判断的是该列是否在不同表格中均存在,其次是判断该列是否unique。
内连接—inner_join
library(tidyverse)
# if you have not installed this packages,
#you can use the following code :" install.packages("tidyverse") "
df1 <- tibble(
names = paste0("Sample", 1:12),
A = (2:13),
B = rnorm(12),
C = A*2,
lat = c(10,20,30,40,50,60,70,80,90,100,110,120),
long = c(-5,0,5,10,15,20,25,30,35,40,45,50)
)
df2 <- tibble(
names = paste0("Sample", 1:6),
group1 = rep(c("treat1","treat2"),each= 3),
lat = c(20,40,80,90,100,120),
long = c(0,10,30,35,40,50),
MAT = c(22,23,25,28,30,35)
)
df2
数据形式如下:
df1 %>%
inner_join(df2, by = "names")
结果如下:
外连接—左,右和全连接
有时候我们并不是找两个表格中共同存在的部分,而是在表格中找到对应“键”的其它信息。
这时候我们可能需要用到外连接,外连接包括左连接(left_join),右连接(right_join)和全连接(full_join)。
目的1:在df2找到所有df1的names对应的数据
代码如下:
df1 %>%
left_join(df2, by = "names")
注意:左连接不会丢弃df1数据中,对应的键在df2中没有数据的部分,而是会通过NA自动补全。
目的2:在df1中找到所有对应df2 的names对应的数据。
代码如下:
df1 %>%
right_join(df2, by = "names")
注意:相似于左连接,右连接也会自动补齐df2的键(也就是names)在df1数据中不存在的数据。只是本次所使用的数据只是自己随便编辑的数据,df1中包含了所有df2的键所对应的数据。
目的3:找到df1中的经(long)度和纬度(lat)在df2中对应的年平均温度。注意:经纬度和温度均为我随便写的数据。
df1 %>%
left_join(df2, by = c("lat","long"))
相比于内连接(inner_join)来说,外连接不会造成原来数据信息的丢弃。因此,我更加推荐外连接。
对于全连接(full_join),感兴趣的朋友可以自己试一下,我自己不怎么用。
筛选连接
无论是内连接还是外连接,都会保留两个数据中的部分数据,但是有时候我只想根据键,在另一个表格中筛选一些信息,而不想保留键所在的数据框中的其它数据,此时如何做呢?
此时需要用到筛选连接:
目的:在df1数据中,筛选df2的names对应的数据,但是不保留df2已经包含的数据。
df1 %>%
semi_join(df2, by = "names")