给定两个数据帧:
df1 = data.frame(CustomerId = c(1:6), Product = c(rep("Toaster", 3), rep("Radio", 3)))
df2 = data.frame(CustomerId = c(2, 4, 6), State = c(rep("Alabama", 2), rep("Ohio", 1)))
df1
# CustomerId Product
# 1 Toaster
# 2 Toaster
# 3 Toaster
# 4 Radio
# 5 Radio
# 6 Radio
df2
# CustomerId State
# 2 Alabama
# 4 Alabama
# 6 Ohio
如何进行数据库样式(即sql样式)连接?也就是说,我如何获得:
df1和df2的内部连接:仅返回左表在右表中具有匹配键的行。df1和df2的外部连接:返回两个表中的所有行,连接左侧表中具有匹配键的记录。df1和df2的左外联接(或简单的左联接)返回左表中的所有行,以及右表中具有匹配键的所有行。df1和df2的右外部连接返回右表中的所有行,以及左表中具有匹配键的所有行。
额外学分:
如何执行SQL样式的选择语句?
在R Wiki上有一些很好的例子。我会在这里偷一对:
合并方法
由于键的名称相同,所以进行内部连接的简单方法是merge():
merge(df1, df2)
可以使用“all”关键字创建完整的内部联接(两个表中的所有记录):
merge(df1, df2, all=TRUE)
df1和df2的左外连接:
merge(df1, df2, all.x=TRUE)
df1和df2的右外连接:
merge(df1, df2, all.y=TRUE)
你可以翻转它们,拍打它们,然后摩擦它们,以获得你询问的其他两个外部连接:)
下标方法
使用下标方法与左边的df1进行左外部连接将是:
df1[,"State"]<-df2[df1[ ,"Product"], "State"]
另一种外部联接的组合可以通过对左外部联接下标示例进行排序来创建。(是的,我知道这相当于说“我会把它作为练习留给读者……”)
内部连接有data.table方法,它非常节省时间和内存(对于一些更大的data.frames也是必要的):
library(data.table)
dt1 <- data.table(df1, key = "CustomerId")
dt2 <- data.table(df2, key = "CustomerId")
joined.dt1.dt.2 <- dt1[dt2]
merge也适用于data.tables(因为它是通用的并调用merge.data.table)
merge(dt1, dt2)
stackoverflow上记录的data.table:如何执行data.table合并操作将外键上的SQL联接转换为R data.table语法合并更大数据的有效替代方案。帧R如何在R中与data.table进行基本的左外连接?
另一个选项是plyr包中的join函数。【2022年注意:plyr现已退役,并已被dplyr取代。dplyr中的连接操作在本答案中描述。】
library(plyr)
join(df1, df2,
type = "inner")
# CustomerId Product State
# 1 2 Toaster Alabama
# 2 4 Radio Alabama
# 3 6 Radio Ohio
类型选项:内部、左侧、右侧、完整。
从…起join:与merge不同,[join]保留x的顺序,无论使用何种连接类型。
我建议您查看Gabor Grothendieck的sqldf包,它允许您用SQL表示这些操作。
library(sqldf)
## inner join
df3 <- sqldf("SELECT CustomerId, Product, State
FROM df1
JOIN df2 USING(CustomerID)")
## left join (substitute 'right' for right join)
df4 <- sqldf("SELECT CustomerId, Product, State
FROM df1
LEFT JOIN df2 USING(CustomerID)")
我发现SQL语法比它的R等效语法更简单和自然(但这可能只是反映了我的RDBMS偏见)。
有关连接的更多信息,请参阅Gabor的sqldfGitHub。