Data.table: Total salah saat menggabungkan dan mengelompokkan berdasarkan kolom yang sama?

Dibuat pada 10 Okt 2018  ·  4Komentar  ·  Sumber: Rdatatable/data.table

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

bug question

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:

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

Semua 4 komentar

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
Apakah halaman ini membantu?
0 / 5 - 0 peringkat