Как объединить две таблицы данных с разными именами столбцов?
У меня есть два data.table X и Y.
в столбцах X: area, id, value
столбцы в Y: 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)
)
И я устанавливаю ключи для X и Y:
setkey(X, id)
setkey(Y, ID)
Теперь я пытаюсь присоединиться X и Y к id
в X и id
в Y:
merge(X, Y)
merge(X, Y, by=c('id', 'ID'))
merge(X, Y, by.x='id', by.y='ID')
Все возникшие ошибки говорят о том, что имена столбцов в аргументе by
недействительны.
Я ссылался на руководство по таблице data.table и обнаружил, что функция merge
не поддерживает аргументы by.x
и by.y
.
Как я могу объединить два data.tables с именами разных столбцов без изменения имен столбцов?
Append:
Мне удалось присоединиться к двум таблицам с помощью X[Y]
, но почему функция merge
не работает в data.table?
Ответы
Ответ 1
Используйте эту операцию:
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
или эта операция:
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
Изменить после редактирования вашего вопроса, я прочитал раздел 1.12 FAQ: "Что такое разница между X [Y] и слиянием (X, Y)?", что привело меня к проверке ?merge
, и я обнаружил, что существуют две разные функции слияния в зависимости от того, какой пакет вы используете. По умолчанию используется merge.data.frame
, но data.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.
с
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
Изменить полноту на основе комментария от @Michael Bernsteiner, похоже, команда data.table
планирует реализовать by.x
и by.y
в функцию merge.data.table
, но еще не сделали этого.
Ответ 2
Начиная с версии data.table
версии 1.9.6 (на CRAN на sep 2015) вы можете указать аргументы by.x
и by.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
Однако в таблице данных 1.9.6 вы можете также указать аргумент on
в нотации X[Y]
Синтаксис X [Y] теперь может объединяться без необходимости устанавливать ключи, используя новый аргумент. Например: DT1 [DT2, on = c (x = "y" )] присоединяется к столбцу "y" DT2 с "x" DT1. DT1 [DT2, on = "y" ] присоединил бы столбец "y" обоих data.tables.
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
этот ответ автором data.table
имеет более подробную информацию
Ответ 3
Ошибка слияния при использовании by.x
и by.y
с data.table
. Принимая ваши данные:
> merge(X,Y, by.x='id', by.y='ID')
Error in merge.data.table(X, Y, by.x = "id", by.y = "ID")
Вы можете использовать data.table
с merge, но вам нужно использовать аргумент by
для соединения (так что переименуйте столбцы, чтобы иметь тот же colnames
)
Y = setNames(Y,c('id','price','sales'))
Это все равно не работает:
merge(X,Y, by.x='id', by.y='id')
Error in merge.data.table(X, Y, by.x = "id", by.y = "id") :
Но это сработает:
> 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
В качестве альтернативы вам нужно будет преобразовать data.table
в data.frame
, чтобы использовать merge
с аргументами by.x
и by.y
:
merge(data.frame(X), data.frame(Y), by.x='id', by.y='ID')
Ответ 4
Вы также можете объединить несколько столбцов с разными именами. см. пример ниже
# create data frame authors
authors <- data.frame(
FirstName=c("Lorne", "Loren", "Robin",
"Robin", "Billy"),
LastName=c("Green", "Jaye", "Green",
"Howe", "Jaye"),
Age=c(82, 40, 45, 2, 40),
Income=c(1200000, 40000, 25000, 0, 27500),
Home=c("California", "Washington", "Washington",
"Alberta", "Washington"))
# create data frame books Note First name in authors is same as AuthorFirstname same thing with lastname.
books <- data.frame(
AuthorFirstName=c("Lorne", "Loren", "Loren",
"Loren", "Robin", "Rich"),
AuthorLastName=c("Green", "Jaye", "Jaye", "Jaye",
"Green", "Calaway"),
Book=c("Bonanza", "Midwifery", "Gardening",
"Perennials", "Who_dun_it?", "Support"))
merge(authors, books, by.x=c("FirstName", "LastName"),
by.y=c("AuthorFirstName", "AuthorLastName"),
all.x=TRUE)