J'ai deux data.tableXetY.
colonnes dansX: area, id, value
colonnes dansY: ID, price, sales
Créez les deux 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)
)
Et je mets les clés pourXetY:
setkey(X, id)
setkey(Y, ID)
Maintenant, j'essaie de rejoindreXetYpar id
dansXet ID
dansY:
merge(X, Y)
merge(X, Y, by=c('id', 'ID'))
merge(X, Y, by.x='id', by.y='ID')
Tous ont déclenché une erreur en indiquant que les noms de colonne dans l'argument by
n'étaient pas valides.
J'ai fait référence au manuel de data.table et j'ai trouvé la fonction merge
ne prenant pas en charge les arguments by.x
et by.y
.
Comment pourrais-je joindre deux data.tables par des noms de colonne différents sans changer les noms de colonne ?
Ajouter :
J'ai réussi à joindre les deux tables par X[Y]
, mais pourquoi la fonction merge
échoue-t-elle dans data.table?
Utilisez cette opération:
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
ou cette opération:
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
Modifier après avoir modifié votre question, j'ai lu la section 1.12 du FAQ : "Quelle est la différence entre X [Y] et la fusion (X, Y)?", Ce qui m'a amené à la caisse ?merge
et moi avons découvert qu'il existe deux fonctions de fusion différentes selon le package que vous utilisez. La valeur par défaut est merge.data.frame
mais data.table utilise merge.data.table
. Comparer
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.
avec
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
Editer pour compléter sur la base d'un commentaire de @Michael Bernsteiner, il semble que l'équipe data.table
envisage d'implémenter by.x
et by.y
dans la fonction merge.data.table
, mais ne l'a pas encore fait.
À partir de data.table
version 1.9.6 (sur CRAN le sep 2015), vous pouvez spécifier les arguments by.x
et by.y
dans 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
Cependant, dans data.table 1.9.6, vous pouvez aussi spécifier l’argument on
dans la notation X[Y]
.
La syntaxe X [Y] peut maintenant être jointe sans avoir à définir de clés à l'aide du nouvel argument on. Par exemple: DT1 [DT2, on = c (x = "y")] joindrait la colonne "y" de DT2 à "x" de DT1. DT1 [DT2, on = "y"] rejoindrait la colonne "y" des deux 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
this answer de l'auteur data.table
a plus de détails
La fusion échoue lorsque vous utilisez by.x
et by.y
avec data.table
. Prendre vos données:
> merge(X,Y, by.x='id', by.y='ID')
Error in merge.data.table(X, Y, by.x = "id", by.y = "ID")
Vous pouvez utiliser data.table
avec fusion, mais vous devez utiliser l'argument by
pour vous joindre (renommez donc les colonnes pour qu'elles aient le même colnames
Y = setNames(Y,c('id','price','sales'))
Cela ne fonctionnera toujours pas:
merge(X,Y, by.x='id', by.y='id')
Error in merge.data.table(X, Y, by.x = "id", by.y = "id") :
Mais cela fonctionnera:
> 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
Sinon, vous devez convertir data.table
en data.frame
pour pouvoir utiliser merge
avec les arguments by.x
et by.y
:
merge(data.frame(X), data.frame(Y), by.x='id', by.y='ID')
Vous pouvez également fusionner en utilisant plusieurs colonnes portant des noms différents. voir exemple ci-dessous
# 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)