2017-06-08 14 views
1

Rのデータフレームまたはデータテーブルの複数の列にわたるグループインデックス(グループ識別子)を計算する最も効率的な方法は何ですか。データフレームの複数の列にわたるグループインデックスを計算するR

例えば、以下のデータフレームに、私は1つの生成のような、グループ識別子を持つ列「インデックス」を追加したい列AとB

DF <- data.frame(a = rep(1:2,6), b = sort(letters[1:3])) 

> DF 
    a b 
1 1 a 
2 2 b 
3 1 c 
4 2 a 
5 1 b 
6 2 c 
7 1 a 
8 2 b 
9 1 c 
10 2 a 
11 1 b 
12 2 c 

六のユニークな組み合わせがありますこれは大規模なデータフレームでは明らかに非効率な方法です:

DF$index <- with(DF, as.numeric(factor(paste0(a, b)))) 

> DF 
    a b index 
1 1 a  1 
2 2 b  5 
3 1 c  3 
4 2 a  4 
5 1 b  2 
6 2 c  6 
7 1 a  1 
8 2 b  5 
9 1 c  3 
10 2 a  4 
11 1 b  2 
12 2 c  6 

非常に大きなデータフレームでこれを行う最も速い方法は何ですか? data.tableを使用して、この程度

+0

非常に大きなデータ使用のためdata.ta ble 'https://stackoverflow.com/tags/data.table/info – jogo

答えて

2

方法、

library(data.table) 
setDT(df)[,group :=.GRP,by = .(a,b)] 

出力

ベースRで
> df 
    a b group 
1: 1 a  1 
2: 2 b  2 
3: 1 c  3 
4: 2 a  4 
5: 1 b  5 
6: 2 c  6 
7: 1 a  1 
8: 2 b  2 
9: 1 c  3 
10: 2 a  4 
11: 1 b  5 
12: 2 c  6 
1

、あなたがinteractionを使用することができ、かなり速くpaste方法よりも、もののdata.tableメソッドはまだ高速です。

DF$index <- as.integer(interaction(DF)) 

これはここ

DF 
    a b index 
1 1 a  1 
2 2 b  4 
3 1 c  5 
4 2 a  2 
5 1 b  3 
6 2 c  6 
7 1 a  1 
8 2 b  4 
9 1 c  5 
10 2 a  2 
11 1 b  3 
12 2 c  6 

タイミング

が大きいデータセットにいくつかのタイミングであり、所望の結果を返す: `

### set up 
# 60K observations 
DF <- data.frame(a = rep(1:2,60000), b = letters[1:20]) 
# make a data table copy 
library(data.table) 
DT <- data.table(DF) 

library(microbenchmark) 
microbenchmark(paste=with(DF, as.numeric(factor(paste0(a, b)))), 
       interaction=as.integer(interaction(DF)), 
       grp=DT[,group :=.GRP,by = .(a,b)]) 
Unit: milliseconds 
     expr  min  lq  mean median  uq  max neval cld 
     paste 38.664541 41.100587 46.315671 42.030301 42.903709 91.32412 100 c 
interaction 4.203244 5.788548 9.927459 6.141646 6.943635 55.15564 100 b 
     grp 1.771617 1.897632 2.772984 2.138828 2.218371 49.41399 100 a 
関連する問題