penggabungan data.tabel pada nama kolom duplikat / bagaimana cara menulis J yang sesuai dengan nama di Y?

Saya mengalami beberapa masalah dalam menggunakan data.table untuk penggabungan "ganda". Inilah yang ingin saya lakukan dalam bahasa Inggris sederhana. Saya memiliki beberapa data grafik/jaringan (yaitu, node dan tepi) dan saya ingin menggabungkan beberapa atribut simpul ke dalam data.tabel saya yang berisi tepinya. Bagaimana cara menggabungkan informasi tambahan dari data.table "simpul" ke dalam data.tabel "tepi" dua kali (sekali untuk kolom "Dari" dan sekali untuk kolom "Ke")? Penggabungan pertama berfungsi dengan mudah, tetapi pada penggabungan kedua, sepertinya saya tidak tahu cara memasukkan kolom yang baru digabungkan ke dalam DT pengembalian saya (yaitu, menulis pernyataan j yang benar. Berikut adalah beberapa contoh data menggambarkan:

set.seed(1)
nodes <- data.table( NodeID=c("N1", "N2", "N3", "N4", "N5"), 
                     Name=c("Alice", "Bob", "Charlie", "David", "Emily"), 
                     key="NodeID")

edges <- data.table( EdgeID=1:10, 
                     From=sample(nodes$NodeID, 10, replace=TRUE), 
                     To=sample(nodes$NodeID, 10, replace=TRUE))
setkey(edges, From, To)

Output yang saya inginkan adalah memiliki data.table baru yang menambahkan kolom "Nama" dari node data.table ke tepi data.table DUA KALI: sekali untuk kolom "Dari" dan sekali untuk kolom "Ke".

   From EdgeID To    FromName ToName
1:   N1     10 N4    Alice    David
2:   N2      2 N1    Bob      Alice
3:   N2      1 N2    Bob      Bob
4:   N2      5 N4    Bob      David
5:   N3      3 N4    Charlie  David
6:   N4      9 N2    David    Bob
...

Penggabungan pertama (untuk kolom "Dari") mudah: edge[nodes] Penggabungan kedua lebih sulit karena memerlukan argumen by terpisah (untuk kolom "Ke"). Namun menentukan argumen oleh memaksa Anda juga menentukan j. Namun bagaimana saya bisa merujuk ke kolom baru yang akan dibuat hanya setelah penggabungan selesai?

edges[nodes, ????, To]

Mungkin saya benar-benar keluar jalur di sini dan ada cara yang lebih baik untuk melakukannya.


person Chris    schedule 07.12.2013    source sumber
comment
Ini bukan data.table tetapi jika Anda mengonversi node dan tepi ke bingkai data edges_df <- as.data.frame(edges); nodes_df <- as.data.frame(nodes) maka SQL mendukung gabungan multi-arah dan dapat digunakan seperti this: library(sqldf); sqldf(pilih e.*, n1.Name sebagai FromName, n2.Name sebagai ToName dari edge_df e, node_df n1, node_df n2 pada e.'From' = n1.NodeID dan e.'To' = n2.NodeID)`   -  person G. Grothendieck    schedule 07.12.2013


Jawaban (2)


Saya akan menyetel kunci edges dua kali, dan bergabung dua kali.

setkey(edges, From)
edges[nodes, FromName := Name]
setkey(edges, To)
edges[nodes, ToName := Name]

## one-liner
setkey(setkey(edges, From)[nodes, FromName := Name], To)[nodes, ToName := Name]
person Blue Magister    schedule 07.12.2013
comment
Saya pribadi lebih suka yang multi-liner. Lebih mudah untuk melihat apa yang telah Anda lakukan. +1 - person A5C1D2H2I1M1N2O1R2T1; 07.12.2013
comment
+1 Saya tahu saya melewatkan sesuatu yang sangat mendasar tentang data.table. - person Chris; 08.12.2013

Sepertinya Anda mencoba melakukan sesuatu seperti berikut:

library(reshape2)
packageVersion("data.table")
# [1] ‘1.8.11’
x <- melt(edges, id.vars="EdgeID")
setkey(x, "value")
setkey(nodes, "NodeID")
dcast.data.table(nodes[x], EdgeID ~ variable, value.var="Name")
#     EdgeID    From      To
#  1:      1     Bob     Bob
#  2:      2     Bob   Alice
#  3:      3 Charlie   David
#  4:      4   Emily     Bob
#  5:      5     Bob   David
#  6:      6   Emily Charlie
#  7:      7   Emily   David
#  8:      8   David   Emily
#  9:      9   David     Bob
# 10:     10   Alice   David

Ide dasarnya adalah mengubah tepi data.table menjadi kumpulan data panjang sebelum digabungkan, dan kemudian membentuk kembali keluarannya menjadi bentuk lebar setelah penggabungan.


CATATAN: Untuk menggunakan dcast.data.table, Anda memerlukan versi data.table yang lebih baru (setidaknya versi 1.8.11). Untuk menginstal versi pengembangan terbaru, instal dengan:

   install.packages("data.table", repos="http://R-Forge.R-project.org")

Anda juga dapat menggabungkan lagi dengan edge jika Anda ingin kolom From dan To yang asli ada di output:

dcast.data.table(nodes[x], EdgeID ~ variable, value.var="Name")[edges]
#     EdgeID    From      To From.1 To.1
#  1:      1     Bob     Bob     N2   N2
#  2:      2     Bob   Alice     N2   N1
#  3:      3 Charlie   David     N3   N4
#  ///SNIP///
#  9:      9   David     Bob     N4   N2
# 10:     10   Alice   David     N1   N4
person A5C1D2H2I1M1N2O1R2T1    schedule 07.12.2013