为多个合并命名列的默认行为...并更改它
Default behavior for naming of columns for multiple merges... and changing it
我需要对 5 个表进行合并,每个表都有一个公共键、多个具有相同名称的列以及每个 table 中具有唯一名称的多个列。
我发现,在多次 table 合并后,列名的唯一性被破坏了...处理此问题并强制使用唯一列名的最佳方法是什么?
library(data.table)
DT1<-data.table(IDs=c(1,1,2,3,4,10), V1=c(1,2,3,4,5,6))
DT2<-data.table(IDs=c(1,2,3,6,10), V2=c(6,7,8,9,10))
DT3<-data.table(IDs=c(3,4,7,8,10), V2=c(1,2,3,4,5))
DT4<-data.table(IDs=c(4,7,6,8,10), V2=c(10,11,12,13,14))
DT5<-data.table(IDs=c(4,7,6,8,10), V2=c(20,21,22,23,24))
tmp<-merge(DT1, DT2, by="IDs")
tmp
tmp<-merge(tmp, DT3, by="IDs")
tmp
tmp<-merge(tmp, DT4, by="IDs")
tmp
tmp<-merge(tmp, DT5, by="IDs")
tmp
注意列名的处理,以及最后一个实例中发生的情况...我最终得到了重复的列名,当我尝试访问该值时,我只获得了第一个值。
> tmp
IDs V1 V2
1: 1 1 6
2: 1 2 6
3: 2 3 7
4: 3 4 8
5: 10 6 10
> tmp<-merge(tmp, DT3, by="IDs")
> tmp
IDs V1 V2.x V2.y
1: 3 4 8 1
2: 10 6 10 5
> tmp<-merge(tmp, DT4, by="IDs")
> tmp
IDs V1 V2.x V2.y V2
1: 10 6 10 5 14
> tmp<-merge(tmp, DT5, by="IDs")
> tmp
IDs V1 V2.x V2.y V2.x V2.y
1: 10 6 10 5 14 24
> tmp$V2.x
[1] 10
data.table
通常允许重复名称。在这种情况下,它还模仿 merge.data.frame
行为。
您可以在合并结果的名称上使用 make.unique()
setnames(tmp, make.unique(names(tmp)))
# IDs V1 V2.x V2.y V2.x.1 V2.y.1
# 1 10 6 10 5 14 24
tmp$V2.x
# [1] 10
tmp$V2.y.1
# [1] 24
或使用 Reduce
和 x[y]
语法如下
# requires 1.9.5+ for the `on=` syntax. Else you've to setkey() first
Reduce(function(x, y) x[y, on="IDs", nomatch=0L], mget(paste0("DT", 1:5)))
# IDs V1 V2 i.V2 i.V2.1 i.V2.2
# 1: 10 6 10 5 14 24
我需要对 5 个表进行合并,每个表都有一个公共键、多个具有相同名称的列以及每个 table 中具有唯一名称的多个列。
我发现,在多次 table 合并后,列名的唯一性被破坏了...处理此问题并强制使用唯一列名的最佳方法是什么?
library(data.table)
DT1<-data.table(IDs=c(1,1,2,3,4,10), V1=c(1,2,3,4,5,6))
DT2<-data.table(IDs=c(1,2,3,6,10), V2=c(6,7,8,9,10))
DT3<-data.table(IDs=c(3,4,7,8,10), V2=c(1,2,3,4,5))
DT4<-data.table(IDs=c(4,7,6,8,10), V2=c(10,11,12,13,14))
DT5<-data.table(IDs=c(4,7,6,8,10), V2=c(20,21,22,23,24))
tmp<-merge(DT1, DT2, by="IDs")
tmp
tmp<-merge(tmp, DT3, by="IDs")
tmp
tmp<-merge(tmp, DT4, by="IDs")
tmp
tmp<-merge(tmp, DT5, by="IDs")
tmp
注意列名的处理,以及最后一个实例中发生的情况...我最终得到了重复的列名,当我尝试访问该值时,我只获得了第一个值。
> tmp
IDs V1 V2
1: 1 1 6
2: 1 2 6
3: 2 3 7
4: 3 4 8
5: 10 6 10
> tmp<-merge(tmp, DT3, by="IDs")
> tmp
IDs V1 V2.x V2.y
1: 3 4 8 1
2: 10 6 10 5
> tmp<-merge(tmp, DT4, by="IDs")
> tmp
IDs V1 V2.x V2.y V2
1: 10 6 10 5 14
> tmp<-merge(tmp, DT5, by="IDs")
> tmp
IDs V1 V2.x V2.y V2.x V2.y
1: 10 6 10 5 14 24
> tmp$V2.x
[1] 10
data.table
通常允许重复名称。在这种情况下,它还模仿 merge.data.frame
行为。
您可以在合并结果的名称上使用 make.unique()
setnames(tmp, make.unique(names(tmp)))
# IDs V1 V2.x V2.y V2.x.1 V2.y.1
# 1 10 6 10 5 14 24
tmp$V2.x
# [1] 10
tmp$V2.y.1
# [1] 24
或使用 Reduce
和 x[y]
语法如下
# requires 1.9.5+ for the `on=` syntax. Else you've to setkey() first
Reduce(function(x, y) x[y, on="IDs", nomatch=0L], mget(paste0("DT", 1:5)))
# IDs V1 V2 i.V2 i.V2.1 i.V2.2
# 1: 10 6 10 5 14 24