如何通过不同的列名合并两个data.table?

Zel*_*ong 27 merge r data.table

我有两个data.table Xÿ.

X:area, id, value
在列ÿ:ID, price, sales

创建两个data.tables:

X = data.table(area=c('US', 'UK', 'EU'),
               id=c('c001', 'c002', 'c003'),
               value=c(100, 200, 300)
              )

Y = data.table(ID=c('c001', 'c002', 'c003'),
               price=c(500, 200, 400),
               sales=c(20, 30, 15)
              )
Run Code Online (Sandbox Code Playgroud)

我为XY设置了键:

setkey(X, id)
setkey(Y, ID)
Run Code Online (Sandbox Code Playgroud)

现在,我尝试加入XŸ通过idXIDÿ:

merge(X, Y)
merge(X, Y, by=c('id', 'ID'))
merge(X, Y, by.x='id', by.y='ID')
Run Code Online (Sandbox Code Playgroud)

所有引发的错误都说明by参数中的列名无效.

我参考了data.table手册,发现merge函数不支持by.xby.y参数.

如何在不更改列名的情况下,通过不同的列名连接两个data.tables ?

追加:
我设法加入了两个表X[Y],但为什么merge函数在data.table中失败?

tos*_*pig 27

data.table版本1.9.6开始(在2015年9月的CRAN上),您可以指定by.xby.y参数data.table::merge

merge(x=X, y=Y, by.x="id", by.y="ID")[]
#     id area value price sales
#1: c001   US   100   500    20
#2: c002   UK   200   200    30
#3: c003   EU   300   400    15
Run Code Online (Sandbox Code Playgroud)

然而,在data.table 1.9.6可以 specfy了on在参数X[Y]符号

X [Y]语法现在可以加入,而无需使用new on参数设置键.例如:DT1 [DT2,on = c(x ="y")]将DT2的列"y"与DT1的"x"连接.DT1 [DT2,on ="y"]将连接两个data.tables的列"y".

X[Y, on=c(id = "ID")]
#   area   id value price sales
#1:   US c001   100   500    20
#2:   UK c002   200   200    30
#3:   EU c003   300   400    15
Run Code Online (Sandbox Code Playgroud)

这个答案data.table作者有更多的细节


Ric*_*son 16

使用此操作:

X[Y]
#    area   id value price sales
# 1:   US c001   100   500    20
# 2:   UK c002   200   200    30
# 3:   EU c003   300   400    15
Run Code Online (Sandbox Code Playgroud)

或者这个操作:

Y[X]
#      ID price sales area value
# 1: c001   500    20   US   100
# 2: c002   200    30   UK   200
# 3: c003   400    15   EU   300
Run Code Online (Sandbox Code Playgroud)

编辑您编辑您的问题后,我读了第1.12 常见问题:"什么是X [Y]和合并(X,Y)之间的didifference",害得我签?merge,我发现有根据两种不同的合并功能您正在使用哪个包裹.默认值为merge.data.framedata.table使用merge.data.table.相比

merge(X, Y, by.x = "id", by.y = "ID") # which is merge.data.table
# Error in merge.data.table(X, Y, by.x = "id", by.y = "ID") : 
# A non-empty vector of column names for `by` is required.
Run Code Online (Sandbox Code Playgroud)

merge.data.frame(X, Y, by.x = "id", by.y = "ID")
#     id area value price sales
# 1 c001   US   100   500    20
# 2 c002   UK   200   200    30
# 3 c003   EU   300   400    15
Run Code Online (Sandbox Code Playgroud)

根据@Michael Bernsteiner 的评论编辑完整性,看起来data.table团队正计划实施by.xby.y进入该merge.data.table功能,但尚未这样做.


Col*_*vel 5

当您使用合并失败,by.xby.ydata.table。获取您的数据:

> merge(X,Y, by.x='id', by.y='ID')
Error in merge.data.table(X, Y, by.x = "id", by.y = "ID")
Run Code Online (Sandbox Code Playgroud)

您可以data.table与 merge 一起使用,但您需要使用by参数进行连接(因此将列重命名为具有相同的colnames

Y = setNames(Y,c('id','price','sales'))
Run Code Online (Sandbox Code Playgroud)

这仍然不起作用:

merge(X,Y, by.x='id', by.y='id')
Error in merge.data.table(X, Y, by.x = "id", by.y = "id") :
Run Code Online (Sandbox Code Playgroud)

但这会起作用:

> merge(X,Y, by='id')
#     id area value price sales
#1: c001   US   100   500    20
#2: c002   UK   200   200    30
#3: c003   EU   300   400    15
Run Code Online (Sandbox Code Playgroud)

或者,您需要转换data.table为 todata.frame才能使用mergewithby.xby.yarguments:

merge(data.frame(X), data.frame(Y), by.x='id', by.y='ID')
Run Code Online (Sandbox Code Playgroud)