给出两个数据框:
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 样式选择语句?
通过使用merge
函数及其可选参数:
内部联接: merge(df1, df2)
将适用于这些示例,因为 R 通过公共变量名称自动加入帧,但您很可能希望指定merge(df1, df2, by = "CustomerId")
以确保您只匹配你想要的字段。如果匹配变量在不同数据框中具有不同的名称,也可以使用by.x
和by.y
参数。
外连接: merge(x = df1, y = df2, by = "CustomerId", all = TRUE)
左外: merge(x = df1, y = df2, by = "CustomerId", all.x = TRUE)
右外: merge(x = df1, y = df2, by = "CustomerId", all.y = TRUE)
交叉连接: merge(x = df1, y = df2, by = NULL)
与内连接一样,您可能希望将 “CustomerId” 显式传递给 R 作为匹配变量。我认为最好明确说明要合并的标识符; 如果输入 data.frames 意外更改并且稍后更容易阅读,则更安全。
您可以by
向量给by
合并多个列,例如, by = c("CustomerId", "OrderId")
。
如果要合并的列名不相同,则可以指定例如by.x = "CustomerId_in_df1", by.y = "CustomerId_in_df2"
,其中CustomerId_in_df1
是第一个数据框中列的名称, CustomerId_in_df2
是第二个数据框中列的名称。 (如果需要在多个列上合并,这些也可以是向量。)
我建议查看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 的 sqldf GitHub 。
内连接有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
函数
library(plyr)
join(df1, df2,
type = "inner")
# CustomerId Product State
# 1 2 Toaster Alabama
# 2 4 Radio Alabama
# 3 6 Radio Ohio
type
选项: inner
, left
, right
, full
。
来自?join
:与merge
不同,无论使用何种连接类型,[ join
] 都会保留 x 的顺序。