Gambaran
Saya relatif akrab dengan data.table, tidak begitu banyak dengan dplyr. Saya telah membaca beberapa dplyrsketsa dan contoh yang muncul di SO, dan sejauh ini kesimpulan saya adalah:
data.tabledandplyrsebanding dalam kecepatan, kecuali ketika ada banyak (yaitu> 10-100K) kelompok, dan dalam beberapa keadaan lain (lihat tolok ukur di bawah)dplyrmemiliki sintaks yang lebih mudah diaksesdplyrabstrak (atau akan) potensi interaksi DB- Ada beberapa perbedaan fungsionalitas kecil (lihat "Contoh / Penggunaan" di bawah)
Dalam pikiran saya 2. tidak menanggung banyak beban karena saya cukup akrab dengannya data.table, meskipun saya mengerti bahwa bagi pengguna baru keduanya akan menjadi faktor besar. Saya ingin menghindari argumen tentang mana yang lebih intuitif, karena itu tidak relevan untuk pertanyaan spesifik saya yang diajukan dari sudut pandang seseorang yang sudah terbiasa data.table. Saya juga ingin menghindari diskusi tentang bagaimana "lebih intuitif" mengarah pada analisis yang lebih cepat (tentu saja benar, tetapi sekali lagi, bukan yang paling saya minati di sini).
Pertanyaan
Yang ingin saya ketahui adalah:
- Apakah ada tugas analitis yang jauh lebih mudah untuk dikodekan dengan satu atau paket lain untuk orang yang akrab dengan paket (yaitu beberapa kombinasi penekanan tombol yang diperlukan vs tingkat esoterisme yang diperlukan, di mana kurang dari masing-masing adalah hal yang baik).
- Apakah ada tugas analitik yang dilakukan secara substansial (yaitu lebih dari 2x) lebih efisien dalam satu paket vs yang lain.
Satu pertanyaan SO baru-baru ini membuat saya berpikir tentang ini sedikit lebih, karena sampai saat itu saya tidak berpikir dplyrakan menawarkan banyak hal di luar apa yang sudah bisa saya lakukan data.table. Ini dplyrsolusinya (data di akhir Q):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
Yang jauh lebih baik daripada upaya hack saya pada data.tablesolusi. Yang mengatakan, data.tablesolusi yang baik juga cukup bagus (terima kasih Jean-Robert, Arun, dan perhatikan di sini saya lebih suka pernyataan tunggal daripada solusi yang paling optimal):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
Sintaksis untuk yang terakhir mungkin tampak sangat esoteris, tetapi sebenarnya cukup mudah jika Anda terbiasa data.table(yaitu tidak menggunakan beberapa trik yang lebih esoteris).
Idealnya yang ingin saya lihat adalah beberapa contoh yang baik jika dplyratau data.tablecaranya jauh lebih ringkas atau berkinerja lebih baik.
Contohnya
Pemakaiandplyrtidak mengizinkan operasi yang dikelompokkan yang mengembalikan jumlah baris sewenang-wenang (dari pertanyaan eddi , perhatikan: sepertinya ini akan diimplementasikan dalam dplyr 0.5 , juga, @beginneR menunjukkan potensi penyelesaian dengan menggunakandojawaban untuk pertanyaan @ eddi).data.tablemendukung rolling bergabung (terima kasih @dholstius) serta tumpang tindih bergabungdata.tablesecara internal mengoptimalkan ekspresi bentukDT[col == value]atauDT[col %in% values]untuk kecepatan melalui pengindeksan otomatis yang menggunakan pencarian biner saat menggunakan sintaks R dasar yang sama. Lihat di sini untuk detail lebih lanjut dan tolok ukur kecil.dplyrmenawarkan versi evaluasi fungsi standar (misalnyaregroup,summarize_each_) yang dapat menyederhanakan penggunaan programatikdplyr(perhatikan penggunaan programatikdata.tablepasti dimungkinkan, hanya memerlukan beberapa pemikiran, penggantian / penawaran, dll, setidaknya setahu saya)
- Saya menjalankan tolok ukur saya sendiri dan menemukan kedua paket tersebut dapat dibandingkan dalam analisis gaya "split apply menggabungkan", kecuali ketika ada sejumlah besar kelompok (> 100K) di mana titik
data.tablemenjadi jauh lebih cepat. - @Arun menjalankan beberapa tolok ukur pada gabungan , menunjukkan bahwa
data.tableskala lebih baik daripadadplyrjumlah grup yang bertambah (diperbarui dengan perangkat tambahan terbaru di kedua paket dan versi terbaru R). Juga, suatu tolok ukur ketika mencoba untuk mendapatkan nilai unik memilikidata.table~ 6x lebih cepat. - (Tidak diverifikasi) memiliki
data.table75% lebih cepat pada versi yang lebih besar dari grup / apply / sort sementaradplyr40% lebih cepat pada yang lebih kecil ( pertanyaan SO lain dari komentar , terima kasih danas). - Matt, penulis utama
data.table, telah membandingkan operasi pengelompokandata.table,dplyrdan pythonpandashingga 2 miliar baris (~ 100GB dalam RAM) . - Sebuah patokan yang lebih tua di 80K kelompok memiliki
data.table~ 8x lebih cepat
Data
Ini adalah contoh pertama yang saya tunjukkan di bagian pertanyaan.
dat <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), name = c("Jane", "Jane", "Jane", "Jane",
"Jane", "Jane", "Jane", "Jane", "Bob", "Bob", "Bob", "Bob", "Bob",
"Bob", "Bob", "Bob"), year = c(1980L, 1981L, 1982L, 1983L, 1984L,
1985L, 1986L, 1987L, 1985L, 1986L, 1987L, 1988L, 1989L, 1990L,
1991L, 1992L), job = c("Manager", "Manager", "Manager", "Manager",
"Manager", "Manager", "Boss", "Boss", "Manager", "Manager", "Manager",
"Boss", "Boss", "Boss", "Boss", "Boss"), job2 = c(1L, 1L, 1L,
1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L)), .Names = c("id",
"name", "year", "job", "job2"), class = "data.frame", row.names = c(NA,
-16L))
dplyrdan data.tabletim bekerja pada tolok ukur, jadi jawabannya akan ada di beberapa titik. # 2 (sintaksis) imO benar-benar salah, tetapi jelas menjelajah ke wilayah opini, jadi saya memilih untuk menutup juga.
(d)plyrukuran 0
dplyrdan plyrberkaitan dengan sintaks dan pada dasarnya adalah alasan utama mengapa saya tidak suka sintaks mereka, adalah bahwa saya harus belajar terlalu banyak (baca lebih dari 1) fungsi tambahan (dengan nama yang masih tidak masuk akal bagi saya), ingat apa yang mereka lakukan, argumen apa yang mereka ambil, dll. Itu selalu merupakan perubahan besar bagi saya dari plyr-filsafat.
.SD.). [Serius] Saya pikir ini adalah perbedaan desain yang sah yang akan menarik bagi orang yang berbeda
dplyradalah:as.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]