Ini adalah sedikit pertanyaan filosofis tentang sintaks gabungan data.table. Saya menemukan semakin banyak kegunaan untuk data.tables, tetapi masih belajar ...
Format X[Y]
gabungan untuk data.tables sangat ringkas, praktis dan efisien, tetapi sejauh yang saya tahu, ini hanya mendukung gabungan dalam dan gabungan luar kanan. Untuk mendapatkan gabungan luar kiri atau penuh, saya perlu menggunakan merge
:
X[Y, nomatch = NA]
- semua baris di Y - gabungan luar kanan (default)X[Y, nomatch = 0]
- hanya baris dengan kecocokan di X dan Y - gabungan dalammerge(X, Y, all = TRUE)
- semua baris dari X dan Y - gabungan luar penuhmerge(X, Y, all.x = TRUE)
- semua baris di X - gabungan luar kiri
Menurut saya, akan berguna jika X[Y]
format gabungan mendukung semua 4 jenis gabungan. Apakah ada alasan mengapa hanya dua jenis gabungan yang didukung?
Bagi saya, nilai parameter nomatch = 0
dan nomatch = NA
tidak terlalu intuitif untuk tindakan yang dilakukan. Hal ini lebih mudah bagi saya untuk memahami dan mengingat merge
sintaks: all = TRUE
, all.x = TRUE
dan all.y = TRUE
. Karena X[Y]
operasi merge
lebih menyerupai daripada match
, mengapa tidak menggunakan merge
sintaks untuk gabungan daripada parameter match
fungsi nomatch
?
Berikut adalah contoh kode dari 4 jenis gabungan:
# sample X and Y data.tables
library(data.table)
X <- data.table(t = 1:4, a = (1:4)^2)
setkey(X, t)
X
# t a
# 1: 1 1
# 2: 2 4
# 3: 3 9
# 4: 4 16
Y <- data.table(t = 3:6, b = (3:6)^2)
setkey(Y, t)
Y
# t b
# 1: 3 9
# 2: 4 16
# 3: 5 25
# 4: 6 36
# all rows from Y - right outer join
X[Y] # default
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
X[Y, nomatch = NA] # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
merge(X, Y, by = "t", all.y = TRUE) # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
identical(X[Y], merge(X, Y, by = "t", all.y = TRUE))
# [1] TRUE
# only rows in both X and Y - inner join
X[Y, nomatch = 0]
# t a b
# 1: 3 9 9
# 2: 4 16 16
merge(X, Y, by = "t") # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
merge(X, Y, by = "t", all = FALSE) # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
identical( X[Y, nomatch = 0], merge(X, Y, by = "t", all = FALSE) )
# [1] TRUE
# all rows from X - left outer join
merge(X, Y, by = "t", all.x = TRUE)
# t a b
# 1: 1 1 NA
# 2: 2 4 NA
# 3: 3 9 9
# 4: 4 16 16
# all rows from both X and Y - full outer join
merge(X, Y, by = "t", all = TRUE)
# t a b
# 1: 1 1 NA
# 2: 2 4 NA
# 3: 3 9 9
# 4: 4 16 16
# 5: 5 NA 25
# 6: 6 NA 36
Pembaruan: data.table v1.9.6 memperkenalkan on=
sintaks, yang memungkinkan ad hoc bergabung pada bidang selain kunci utama. jawaban jangorecki atas pertanyaan Bagaimana cara menggabungkan (menggabungkan) bingkai data (dalam, luar, kiri, kanan)? menyediakan beberapa contoh tipe gabungan tambahan yang dapat ditangani oleh data.table.
sumber
Y[X]
jika Anda ingin kiri luar bergabung dariX[Y]
danrbind(Y[X],X[Y])
jika Anda ingin penuh luar bergabungunique()
pendekatan Anda di bawah ini untuk penggabungan penuh lebih disukairbind(Y[X],X[Y])
, karena rbind akan melibatkan penyalinan tabel. Apakah itu benar?unique(c(unique(X[,t]), unique(Y[,t]))
- ini harus lebih hemat memori karena hanya menggabungkan dua daftar yang akan kurang dari atau sama dengan jumlah baris di X dan Y .Jawaban:
Mengutip dari
data.table
FAQ 1.11 Apa perbedaan antaraX[Y]
danmerge(X, Y)
?Jika Anda ingin gabungan luar kiri dari
X[Y]
Jika Anda ingin full outer join
sumber
X[Y,all=T]
bisa menjadi cara yang elegan untuk menentukan gabungan luar penuh dalam sintaks data.table X [Y]. AtauX[Y,all.x=T]
untuk bergabung kiri. Saya bertanya-tanya mengapa tidak dirancang seperti itu. Hanya pemikiran saja.X[Y[J(unique_keys)]]
?Jawaban @ mnel tepat, jadi terima jawaban itu. Ini hanya tindak lanjut, terlalu lama untuk komentar.
Seperti yang dikatakan mnel, gabungan luar kiri / kanan diperoleh dengan menukar
Y
danX
:Y[X]
-vs-X[Y]
. Jadi 3 dari 4 jenis gabungan didukung dalam sintaks itu, bukan 2, iiuc.Menambahkan yang keempat sepertinya ide yang bagus. Katakanlah kita menambahkan
full=TRUE
atauboth=TRUE
ataumerge=TRUE
(tidak yakin nama argumen terbaik?) Maka hal itu tidak terpikir oleh saya sebelumnya yangX[Y,j,merge=TRUE]
akan berguna untuk alasan setelah TAPI di FAQ 1.12. Permintaan fitur baru sekarang ditambahkan dan ditautkan kembali ke sini, terima kasih:FR # 2301: Tambahkan merge = TRUE argumen untuk X [Y] dan Y [X] bergabung seperti merge ().
Versi terbaru telah dipercepat
merge.data.table
(dengan mengambil salinan dangkal secara internal untuk mengatur kunci lebih efisien, misalnya). Jadi kami mencoba untuk membawamerge()
danX[Y]
lebih dekat, dan memberikan semua pilihan kepada pengguna untuk fleksibilitas penuh. Ada pro dan kontra dari keduanya. Permintaan fitur luar biasa lainnya adalah:FR # 2033: Tambahkan by.x dan by.y ke merge.data.table
Jika ada yang lain, mohon biarkan mereka datang.
Dengan bagian pertanyaan ini:
Jika Anda lebih suka
merge()
sintaks dan 3 argumenall
,all.x
danall.y
kemudian hanya menggunakan bahwa alih-alihX[Y]
. Pikir itu harus mencakup semua kasus. Atau maksud Anda mengapa argumen itunomatch
masuk[.data.table
? Jika demikian, itu hanya cara yang tampak alami diberikan FAQ 2.14: "Bisakah Anda menjelaskan lebih lanjut mengapa data.table terinspirasi oleh sintaks A [B] dalam basis?". Tapi juga, saat ininomatch
hanya membutuhkan dua nilai0
danNA
. Itu bisa diperpanjang sehingga nilai negatif berarti sesuatu, atau 12 berarti menggunakan nilai baris ke-12 untuk mengisi NAs, misalnya, ataunomatch
di masa depan bisa menjadi vektor atau bahkan dirinya sendiri adata.table
.Hm. Bagaimana by-without-by berinteraksi dengan merge = TRUE? Mungkin kita harus membawa ini ke bantuan dataTable .
sumber
join="all", join="all.x", join="all.y" and join="x.and.y"
di tepi catatan saya. Tidak yakin apakah itu lebih baik.join
seperti itu, ide yang bagus. Saya memposting ke bantuan data jadi mari kita lihat. Mungkin berikandata.table
waktu untuk beradaptasi juga. Misalnya, apakah Anda sudah sampai -tanpa-oleh , dan bergabung dengan lingkup yang diwariskan ?join
kata kunci untuk, ketika saya adalah DataTable:X[Y,j,join=string]
. Nilai string yang mungkin untuk bergabung disarankan menjadi: 1) "all.y" dan "right" -Ini "jawaban" adalah proposal untuk diskusi: Seperti yang ditunjukkan dalam komentar saya, saya sarankan menambahkan
join
parameter untuk [.data.table () untuk memungkinkan jenis tambahan bergabung, yaitu:X[Y,j,join=string]
. Selain 4 jenis gabungan biasa, saya juga menyarankan untuk mendukung 3 jenis gabungan eksklusif , dan gabungan silang .Nilai
join
string (dan alias) untuk berbagai jenis gabungan diusulkan menjadi:"all.y"
dan"right"
- gabung kanan, default data.table sekarang (nomatch = NA) - semua baris Y dengan NAs di mana tidak ada kecocokan X;"both"
dan"inner"
- inner join (nomatch = 0) - hanya baris dimana X dan Y cocok;"all.x"
dan"left"
- gabungan kiri - semua baris dari X, NAs di mana tidak ada Y yang cocok:"outer"
dan"full"
- gabungan luar penuh - semua baris dari X dan Y, NAs jika tidak ada kecocokan"only.x"
dan"not.y"
- non-join atau anti-join mengembalikan baris X jika tidak ada kecocokan Y."only.y"
dan"not.x"
- non-join atau anti-join mengembalikan baris Y jika tidak ada kecocokan X."not.both"
- eksklusif bergabung mengembalikan baris X dan Y di mana tidak ada kecocokan dengan tabel lain, yaitu eksklusif-atau (XOR)"cross"
- Gabungan silang atau perkalian Kartesius dengan setiap baris X cocok dengan setiap baris YNilai default
join="all.y"
yang sesuai dengan default saat ini.Nilai string "all", "all.x" dan "all.y" sesuai dengan
merge()
parameter. String "kanan", "kiri", "dalam", dan "luar" mungkin lebih cocok untuk pengguna SQL.String "keduanya" dan "not.both" adalah saran terbaik saya saat ini - tetapi seseorang mungkin memiliki saran string yang lebih baik untuk gabungan dalam dan gabungan eksklusif. (Saya tidak yakin apakah "eksklusif" adalah terminologi yang tepat, perbaiki saya jika ada istilah yang tepat untuk gabungan "XOR".)
Penggunaan dari
join="not.y"
adalah alternatif untukX[-Y,j]
atauX[!Y,j]
non-join sintaks dan mungkin lebih jelas (bagi saya), meskipun saya tidak yakin apakah mereka sama (fitur baru dalam data.table versi 1.8.3).Gabungan silang terkadang berguna, tetapi mungkin tidak sesuai dengan paradigma data.table.
sumber
join
tetapi kecuali itu masuk ke pelacak, itu akan dilupakan.