Data.table: 同じ列で集計およびグループ化すると、合計が間違っていますか?

作成日 2018年10月10日  ·  4コメント  ·  ソース: Rdatatable/data.table

こんにちは。 同じ列で集計およびグループ化するときのdata.tableの動作に混乱しています。 グループ化されていないデータではなく、グループ化されたデータに対して集計(合計など)を実行しているようです。 私は必ずしもこれが間違っていると言っているわけではありませんが、他のツールとは異なり、説明が何であるか、または何か間違ったことをしているのか(またはおそらくこれがバグであるのか)疑問に思っていました。 dplyrとの比較を含めました。これは、私が期待するように(そしてSQLのように)実行します。 注意:リクエストに応じて問題やスタックオーバーフローなどを検索しようとしましたが、このシナリオの性質(同じ列のグループ化と集約)は少しユニークであり、一致するものは見つかりませんでした。

# Minimal reproducible example

以下の2つの例の[合計]列を比較してください。 たとえば、値が3の行が3つあるので、合計は3ではなく9になると思います。

データ表

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]

結果(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()

結果(r):

   SomeNumber N Total
1:          1 3     3
2:          2 3     6
3:          3 3     9

# Output of sessionInfo()
Rバージョン3.5.1(2018-07-02)
プラットフォーム:x86_64-w64-mingw32 / x64(64ビット)
実行中:Windows> = 8 x64(ビルド9200)

マトリックス製品:デフォルト

ロケール:
[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 = English_United Kingdom.1252

添付の基本パッケージ:
[1]統計グラフィックgrDevicesutilsデータセットメソッドベース

その他の添付パッケージ:
[1] dplyr_0.7.6 data.table_1.11.8 openxlsx_4.1.0 bindrcpp_0.2.2pivottabler_0.4.0.9000

名前空間を介してロードされます(アタッチされていません):
[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 tools_3.5.1
[10] utf8_1.1.4 cli_1.0.1 htmltools_0.3.6 yaml_2.2.0 assertthat_0.2.0ダイジェスト_0.6.17tibble_1.4.2 crayon_1.3.4 zip_1.0.0
[19] purrr_0.2.5 htmlwidgets_1.3glue_1.3.0compiler_3.5.1 pillar_1.3.0 jsonlite_1.5 pkgconfig_2.0.2

bug question

最も参考になるコメント

返信とFAQへのポインタをありがとう@ franknarf1@jangorecki
FAQの回答を読み、もう少しテストを行った後、グループ化に使用されたものに応じて、同じデータを持つ異なる列に集約すると異なる結果になる可能性があるため、グループ化変数の使用方法に非常に注意する必要があるようです。 私はまだこれが奇妙で少し厄介だと思っていますが、おそらくこれは私が慣れなければならないことです。

例:

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]

上記の結果: 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]

上記の結果: 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]

結果がなく、エラーで失敗します:
gsum(SomeNumberA)のエラー:オブジェクト 'SomeNumberA'が見つかりません

全てのコメント4件

それは他のツールとは異なり、説明が何であるか、または私が何か間違ったことをしているのかどうか(またはおそらくこれがバグであるかどうか)疑問に思っていました。 私はdplyrとの比較を含めました。dplyrは私が期待するように(そしてSQLのように)実行します

インサイドjDT[, j, by] 、の列byあなたが好きなこと、計算を行うことができます1の長さは持っている.N*SomeNumberかかわらを、:

dt[, .(.N, Total=.N*SomeNumber), by=SomeNumber]
# or, for efficiency with GForce...
dt[, .(.N), by=SomeNumber][, Total := N*SomeNumber][]

理論的根拠については、「各グループ内で、グループ変数の長さが-1なのはなぜですか?」という質問を参照してください。 FAQ内のvignette("datatable-faq")またはhttps://github.com/Rdatatable/data.table/wiki/Getting-started

返信とFAQへのポインタをありがとう@ franknarf1@jangorecki
FAQの回答を読み、もう少しテストを行った後、グループ化に使用されたものに応じて、同じデータを持つ異なる列に集約すると異なる結果になる可能性があるため、グループ化変数の使用方法に非常に注意する必要があるようです。 私はまだこれが奇妙で少し厄介だと思っていますが、おそらくこれは私が慣れなければならないことです。

例:

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]

上記の結果: 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]

上記の結果: 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]

結果がなく、エラーで失敗します:
gsum(SomeNumberA)のエラー:オブジェクト 'SomeNumberA'が見つかりません

最後はバグです...

これがdata.tableのグループ化/集約メソッドのニュアンスであるかどうかはわかりませんが、単一の変数data.tableでグループ化および集約する場合、グループ化呼び出しは「因数分解」されません。

それは自身のグループを集約した後だとして、すなわちそれはとてもあなたのケースであなただけの3が残っている、それぞれの数をカウントSomeNumberの代わりに、元の9の、合計変数。

迅速で簡単な修正は、最初のグループ化呼び出し内で因数分解が行われるようにすることです。

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
このページは役に立ちましたか?
0 / 5 - 0 評価