web-dev-qa-db-ja.com

dplyrを使用して列の範囲グループ化を行う方法は?

列のrange値に基づいてdata.tableをグループ化したいのですが、dplyrライブラリでこれを行うにはどうすればよいですか?

たとえば、私のデータテーブルは次のようになります。

library(data.table)
library(dplyr)
DT <- data.table(A=1:100, B=runif(100), Amount=runif(100, 0, 100))

ここで、DTを列Bの0.05間隔で20のグループにグループ化し、各グループに含まれる行数をカウントします。たとえば、列Bの値が[0、0.05)の範囲にある行は、グループを形成します。列Bの値が[0.05、0.1)の範囲にある行は、別のグループを形成します。このグループ機能を実行する効率的な方法はありますか?

どうもありがとうございました。

----------------------------- akrunの回答に関するその他の質問。あなたの答えをありがとうakrun。 「カット」機能について新しい質問がありました。私のDTが以下のような場合:

DT <- data.table(A=1:10, B=c(0.01, 0.04, 0.06, 0.09, 0.1, 0.13, 0.14, 0.15, 0.17, 0.71)) 

次のコードを使用します。

DT %>% 
  group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05), right=F) ) %>% 
  summarise(n= n()) %>%
  arrange(as.numeric(gr))

私はこのような結果を見ることを期待しています:

          gr n
1   [0,0.05) 2
2 [0.05,0.1) 2
3 [0.1,0.15) 3
4 [0.15,0.2) 2
5 [0.7,0.75) 1

しかし、私が得た結果は次のようになります。

          gr n
1   [0,0.05) 2
2 [0.05,0.1) 2
3 [0.1,0.15) 4
4 [0.15,0.2) 1
5 [0.7,0.75) 1 

値0.15が正しく割り当てられていないようです。これについて何か考えはありますか?

9
Carter

cutを使用してグループ化を行うことができます。 _group_by_内に「gr」列を作成し、summariseを使用して各グループの要素数を作成し(n())、出力を順序付けます(arrange) 'gr'に基づく。

_library(dplyr)
 DT %>% 
     group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05)) ) %>% 
     summarise(n= n()) %>%
     arrange(as.numeric(gr))
_

初期オブジェクトは_data.table_であるため、これは_data.table_メソッドを使用して実行できます(@Frankのkeybyの使用に関する提案が含まれています)

_library(data.table)
DT[,.N , keyby = .(gr=cut(B, breaks=seq(0, 1, by=0.05)))]
_

編集:

OPの投稿の更新に基づいて、seqに少数を差し引くことができます。

_lvls <- levels(cut(DT$B, seq(0, 1, by =0.05)))
DT %>%
   group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05) -
                 .Machine$double.eps, right=FALSE, labels=lvls)) %>% 
   summarise(n=n()) %>% 
   arrange(as.numeric(gr))
#          gr n
#1   (0,0.05] 2
#2 (0.05,0.1] 2
#3 (0.1,0.15] 3
#4 (0.15,0.2] 2
#5 (0.7,0.75] 1
_
15
akrun