2015-09-03 8 views
1

Мне нужно сделать слияние по 5 табам, каждый с общим ключом, числом столбцов с одинаковым именем и числом столбцов с уникальными именами через каждую таблицу.Поведение по умолчанию для именования столбцов для нескольких слияний ... и его изменение

Что я нахожу, заключается в том, что уникальность имени столбца ломается после объединения нескольких таблиц ... что является лучшим способом справиться с этой проблемой и заставить уникальное имя столбца?

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 
+0

, если вам не нужно использовать 'allow.cartesian = TRUE' (который я не вижу в ваших данных примера), вы можете присоединиться к столбцу по ссылке на ваш первый набор данных и присвоить имена новым столбцам. Я очень занят, чтобы ответить на него, но он звучит так: 'DT1 [DT2, new_col: = i.V2] [DT3, new_col2: = i.V2] [...]'. – jangorecki

+0

Мне нужно это, чтобы получить внутреннее соединение. Если я следую вашему коду, я думаю, что мы получим полное внешнее соединение? – tcs

ответ

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 
+0

Спасибо. Это решает дублирующую проблему. Есть ли простой способ установить соглашение об именах? В моем случае я хотел бы изменить каждую повторяющуюся переменную, чтобы иметь схему именования, такую ​​как V2.1, V2.2, V2.3 и V2.4. – tcs

+0

Вы можете переименовать их во все, что захотите. Проверьте '? Setnames' – Arun

+0

Да, это правда - справедливо. Я объединяю 300 + переменных, поэтому я искал метод, который изменил схему/метод именования функции слияния. Мне не нравится, в зависимости от произвольного соглашения об именах (которое меняется в будущем и, следовательно, break code), или ручное кодирование группы переименований. – tcs

Смежные вопросы