常见的数据合并函数有rbind,cbind,left_join, right_join, full_join, inner_join等。
接下来我一一为大家介绍这些不同函数的使用及限制
1. 使用 rbind()
rbind() 函数用于将数据框垂直堆叠在一起。这意味着你可以在一个数据框的底部添加另一个数据框的行。所有数据框必须具有相同的列名和相同数量的列。
例如:
假设我们有两个数据框 df1 和 df2,它们有相同的列名和列数。
df1 <- data.frame(id = c(1, 2, 3), value1 = c("A", "B", "C"))
df2 <- data.frame(id = c(4, 5, 6), value1 = c("D", "E", "F"))
# 使用 rbind 合并数据框
df_combined <- rbind(df1, df2)
print(df_combined)
在这里,df1如下图所示:
df2如下图所示:
而合并后的df_combind如下图所示,可以看到这里我们把df1和df2合并成了1个数据。在GBD中,我们可以按这个方法,读取但不同csv文件但格式相同的数据,使用rbind()进行合并。
2. 使用 cbind()
cbind() 函数用于将数据框水平堆叠在一起。这意味着你可以在一个数据框的右侧添加另一个数据框的列。所有数据框必须具有相同的行数。
例如:
假设我们有两个数据框 df1 和 df2,它们有相同的行数。
df1 <- data.frame(id = c(1, 2, 3), value1 = c("A", "B", "C"))
df2 <- data.frame(id = c(4, 5, 6), value2 = c("D", "E", "F"))
# 使用 cbind 合并数据框
df_combined1 <- cbind(df1, df2) # 注意这里直接合并
df_combined2 <- cbind(df1, df2$value1) # 注意这里指定列名
这里我们使用和上面一样的df1和df2,
合并后的df_combined1为
可以看到这里有两列id号,非常不美观,所以我们可以直接合并第二列的value1如df_combined_2:
3.dplyr包中的join系列函数
熟悉SQL的同学都知道,我们在SQL中合并数据时,会使用到Join函数,包括左连接,右连接,内连接和外连接,及全连接等。
那么在R语言中是否也有类似的函数呢?当然也是有的。这里我们使用了R语言中的dplyr包。
dplyr 包提供了多种类型的连接操作,包括 left_join(), right_join(), inner_join(), 和 full_join()等。
下面是这些函数的简要说明以及相应的示例代码。
3.1. 使用 left_join()
left_join() 用于执行左连接,即保留左侧数据框的所有行,并且只包含右侧数据框中与左侧数据框匹配的行。如果右侧没有匹配项,则结果中的那些列将被填充为 NA。
# 创建数据框 df1
df1 <- data.frame(id = c(1, 2, 3), name = c("Alice", "Bob", "Charlie"))
# 创建数据框 df2
df2 <- data.frame(id = c(1, 2, 4), city = c("New York", "Los Angeles", "Chicago"))
# 使用 left_join 进行左连接
result_left <- left_join(df1, df2, by = "id")
result_left结果如下图
3.2. 使用 right_join()
right_join() 用于执行右连接,即保留右侧数据框的所有行,并且只包含左侧数据框中与右侧数据框匹配的行。如果左侧没有匹配项,则结果中的那些列将被填充为 NA。
# 使用 right_join 进行右连接
result_right <- right_join(df1, df2, by = "id")
result_left结果如下图
3.3. 使用 inner_join()
inner_join() 用于执行内连接,即只保留两个数据框中匹配的行。如果任一侧没有匹配项,则不会出现在结果中。
# 使用 inner_join 进行内连接
result_inner <- inner_join(df1, df2, by = "id")
result_inner结果如下图
3.4. 使用 full_join()
full_join() 用于执行全连接,即保留两个数据框的所有行,并且包含所有匹配的行。如果某一方没有匹配项,则结果中的那些列将被填充为 NA
# 使用 full_join 进行全连接
result_full <- full_join(df1, df2, by = "id")
以上就是数据合并的方法展示,接下来我们使用GBD数据库给大家做一个示例。
在使用疾病数据合并SDI数据时,我们假设疾病数据为data2
data2中location_name包含204个国家,year包含1990与2021年,metric中包含Number和Rate。SDI数据包含GBD数据库中204个国家1990-2021年的数据。
data2<- read.csv("data2.csv",header = T)
# sdi 数据
sdi <- read.csv("SDI.csv",header = T,check.names = F)
sdi <- sdi %>% # 宽数据转为长数据
pivot_longer(cols = `1990`:`2021`,names_to = "year") %>%
rename(sdi=value) %>%
dplyr::select(location,year,sdi)
sdi$year <- as.integer(sdi$year)
names(sdi)[1]<-"location_name"
unique(sdi$location_name)
unique(data2$location_name)
# 匹配 sdi 与疾病负担, 生成 data
data <- left_join(data2,sdi,by=c("location_name","year"))
合并后,我们检查data数据中sdi是否有NA
summary(data)
view(data)
显示data数据中有8个NA值。为了方便比较,我们使用view(data)查看数据后,点击sdi列,数据会按升序排列,这时把数据滑到最下面即可看到sdi中为NA的行,他们的location_name为Côte d'Ivoire和Türkiye。
由于是left_join,故这里是也是data2的行名。我们使用unique查看sdi数据中数据所对应的location为Turkey和Cote d'Ivoire。
unique(sdi$location_name)
sdi$location_name[sdi$location_name == "Turkey"] = "Türkiye"
sdi$location_name[sdi$location_name == "Cote d'Ivoire"] = "Côte d'Ivoire"
data <- left_join(data2,sdi,by=c("location_name","year"))
使用代码把sdi数据中的国家名改成和data中一样的国家名。最后再次合并生成data数据集,summary后显示sdi数据中就没有NA值了。
图中所需数据与代码在公众号“公共数据库与孟德尔随机化”后台回复:"代码" 即可获取。
本文分享到这里了,由郑老师团队的统计师撰写
关于郑老师团队及公众号
我们是全国最大的线上医学统计平台,专注于医学生、医护工作者学术研究统计支持,让我们成为你们的统计助理!
我们提供以下科研与统计分析:
①研究者发起的临床试验设计、分析与报告
②医院回顾性数据分析与预测模型
③利用医学公共数据库包括SEER、NHANES、老年健康数据库、GBD数据库、孟德尔随机化等快速挖掘有意义的数据。
④预测模型、NHANES数据库、孟德尔随机化方法、GBD数据库一对一R语言指导
联系助教小董咨询(微信号aq566665)