为多个合并命名列的默认行为......并更改它

时间:2015-09-03 12:14:44

标签: r data.table

我需要跨5个taables进行合并,每个taables都有一个公共密钥,多个具有相同名称的列,以及每个表中具有唯一名称的多个列。

我发现,在多个表合并之后,列名称的唯一性会崩溃...处理此问题的最佳方法是什么,并强制使用唯一的列名称?

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

1 个答案:

答案 0 :(得分:3)

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