Halo. Saya bingung dengan perilaku data.table saat menggabungkan dan mengelompokkan pada kolom yang sama. Tampaknya melakukan agregat (misalnya jumlah) pada data yang dikelompokkan, daripada data yang tidak dikelompokkan. Saya tidak selalu mengatakan ini salah - tetapi ini berbeda dengan alat lain dan saya bertanya-tanya apa penjelasannya atau apakah saya melakukan sesuatu yang salah (atau jika mungkin ini bug). Saya telah menyertakan perbandingan dengan dplyr, yang berkinerja lebih seperti yang saya harapkan (dan lebih seperti SQL). NB: Saya sudah mencoba mencari masalah, stackoverflow, dll, seperti yang diminta, tetapi sifat skenario ini (mengelompokkan dan menggabungkan kolom yang sama) agak unik dan saya belum menemukan kecocokan.
#
Minimal reproducible example
Silakan bandingkan kolom Total dalam dua contoh di bawah ini. Misalnya ada tiga baris dengan nilai tiga, jadi saya berharap Totalnya adalah 9, bukan 3.
tabel data
library(data.table)
df <- data.frame(SomeNumber=c(1,2,3,1,2,3,1,2,3))
dt <- data.table(df)
r <- dt[, .(.N, Total=sum(SomeNumber)), by=SomeNumber]
Hasil (r):
SomeNumber N Total
1: 1 3 1
2: 2 3 2
3: 3 3 3
dplyr
library(dplyr)
df <- data.frame(SomeNumber=c(1,2,3,1,2,3,1,2,3))
r <- df %>% group_by(SomeNumber) %>%
summarise(N=n(), Total=sum(SomeNumber)) %>%
ungroup()
Hasil (r):
SomeNumber N Total
1: 1 3 3
2: 2 3 6
3: 3 3 9
#
Output of sessionInfo()
Versi R 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32 / x64 (64-bit)
Berjalan di bawah: Windows> = 8 x64 (build 9200)
Produk matriks: default
lokal:
[1] LC_COLLATE = English_United Kingdom.1252 LC_CTYPE = English_United Kingdom.1252 LC_MONETARY = English_United Kingdom.1252
[4] LC_NUMERIC = C LC_TIME = Inggris_Inggris.1252
paket dasar terlampir:
[1] grafik statistik grDevices menggunakan basis metode kumpulan data
paket terlampir lainnya:
[1] dplyr_0.7.6 data.table_1.11.8 openxlsx_4.1.0 bindrcpp_0.2.2 pivottabler_0.4.0.9000
dimuat melalui namespace (dan tidak dilampirkan):
[1] Rcpp_0.12.19 rstudioapi_0.8 bindr_0.1.1 magrittr_1.5 tidyselect_0.2.4 R6_2.3.0 rlang_0.2.2 fansi_0.3.0 alat_3.5.1
[10] utf8_1.1.4 cli_1.0.1 htmltools_0.3.6 yaml_2.2.0 menegaskan bahwa_0.2.0 digest_0.6.17 tibble_1.4.2 crayon_1.3.4 zip_1.0.0
[19] purrr_0.2.5 htmlwidgets_1.3 glue_1.3.0 compiler_3.5.1 pillar_1.3.0 jsonlite_1.5 pkgconfig_2.0.2
ini berbeda dengan alat lain dan saya bertanya-tanya apa penjelasannya atau apakah saya melakukan sesuatu yang salah (atau jika mungkin ini bug). Saya telah menyertakan perbandingan dengan dplyr, yang berkinerja lebih seperti yang saya harapkan (dan lebih seperti SQL)
Di dalam j
dari DT[, j, by]
, kolom dalam by
memiliki panjang 1. Anda dapat melakukan perhitungan itu seperti .N*SomeNumber
, meskipun:
dt[, .(.N, Total=.N*SomeNumber), by=SomeNumber]
# or, for efficiency with GForce...
dt[, .(.N), by=SomeNumber][, Total := N*SomeNumber][]
Untuk alasannya, lihat pertanyaan "Di dalam setiap grup, mengapa variabel grup panjang-1?" di dalam FAQ di vignette("datatable-faq")
atau https://github.com/Rdatatable/data.table/wiki/Getting-started
Terima kasih @ franknarf1 dan @jangorecki atas balasan dan penunjuk ke FAQ.
Setelah membaca jawaban FAQ dan melakukan sedikit lebih banyak pengujian, tampaknya Anda harus sangat berhati-hati dengan cara Anda menggunakan variabel pengelompokan, karena menggabungkan pada kolom yang berbeda dengan data yang identik dapat menghasilkan hasil yang berbeda, tergantung pada apa yang digunakan untuk pengelompokan. Saya masih menganggap ini aneh dan agak canggung tetapi mungkin ini hanya sesuatu yang perlu saya biasakan.
Contoh:
library(data.table)
df <- data.frame(SomeNumberA=c(1,1,1),SomeNumberB=c(1,1,1))
dt <- data.table(df)
r <- dt[, .(.N, TotalA=sum(SomeNumberA)), by=SomeNumberA]
Hasil di atas: TotalA = 1
library(data.table)
df <- data.frame(SomeNumberA=c(1,1,1),SomeNumberB=c(1,1,1))
dt <- data.table(df)
r <- dt[, .(.N, TotalB=sum(SomeNumberB)), by=SomeNumberA]
Hasil di atas: TotalB = 3
library(data.table)
df <- data.frame(SomeNumberA=c(1,1,1),SomeNumberB=c(1,1,1))
dt <- data.table(df)
r <- dt[, .(.N, TotalA=sum(SomeNumberA), TotalB=sum(SomeNumberB)), by=SomeNumberA]
Tidak ada hasil, gagal dijalankan dengan kesalahan:
Kesalahan dalam gsum (SomeNumberA): objek 'SomeNumberA' tidak ditemukan
Yang terakhir adalah bug ...
Tidak yakin apakah ini adalah nuansa metode pengelompokan / agregasi data.table tetapi ketika mengelompokkan dan menggabungkan dengan satu variabel data.table tidak 'memfaktorkan' panggilan pengelompokan.
yaitu Ia menghitung setiap angka sebagai grupnya sendiri setelah agregasi, jadi dalam kasus Anda, Anda hanya memiliki 3 SomeNumber
variabel untuk dijumlahkan, bukan 9 yang asli.
Perbaikan cepat dan mudah adalah untuk memastikan faktorisasi berlangsung dalam panggilan pengelompokan awal.
library(data.table)
df <- data.frame(SomeNumber=c(1, 2, 3, 1, 2, 3, 1, 2, 3))
dt <- data.table(df)
r <- dt[, .(.N, Total = sum(SomeNumber)), by = as.factor(SomeNumber)]
as.factor N Total
1: 1 3 3
2: 2 3 6
3: 3 3 9
Komentar yang paling membantu
Terima kasih @ franknarf1 dan @jangorecki atas balasan dan penunjuk ke FAQ.
Setelah membaca jawaban FAQ dan melakukan sedikit lebih banyak pengujian, tampaknya Anda harus sangat berhati-hati dengan cara Anda menggunakan variabel pengelompokan, karena menggabungkan pada kolom yang berbeda dengan data yang identik dapat menghasilkan hasil yang berbeda, tergantung pada apa yang digunakan untuk pengelompokan. Saya masih menganggap ini aneh dan agak canggung tetapi mungkin ini hanya sesuatu yang perlu saya biasakan.
Contoh:
Hasil di atas: TotalA = 1
Hasil di atas: TotalB = 3
Tidak ada hasil, gagal dijalankan dengan kesalahan:
Kesalahan dalam gsum (SomeNumberA): objek 'SomeNumberA' tidak ditemukan