R言語data.tableの概要

13713 ワード

data.tableパケットは、非常に簡潔な汎用フォーマット:DT[i,j,by]を提供し、データセットDTに対してサブセット行iを選択し、byパケットによりjを計算し、dplyrなどのパケットと比較するdataと理解できる.tableの運転速度が速い.
dataを作成するtable
set.seed(1)
DF = data.frame(x=c("b","b","b","a","a"),v=rnorm(5))
DF
##   x          v
## 1 b -0.6264538
## 2 b  0.1836433
## 3 b -0.8356286
## 4 a  1.5952808
## 5 a  0.3295078

これはdataと同じです.frameの作成は同じです
DT = data.table(x=c("b","b","b","a","a"),v=rnorm(5))
DT
##    x          v
## 1: b -0.8204684
## 2: b  0.4874291
## 3: b  0.7383247
## 4: a  0.5757814
## 5: a -0.3053884

あるいはdataを直接frameをdataに変換する.tableタイプ
CARS = data.table(cars)
head(CARS)
##    speed dist
## 1:     4    2
## 2:     4   10
## 3:     7    4
## 4:     7   22
## 5:     8   16
## 6:     9   10
tables()関数を使用して、メモリ内のdataをすべて表示できます.table
tables()
##      NAME NROW NCOL MB COLS       KEY
## [1,] CARS   50    2  1 speed,dist    
## [2,] DT      5    2  1 x,v           
## Total: 2MB

1. Keys
Keysはdataにあるtableでは重要な概念でありdataである.tableには1つのkeyしか設定できませんが、このkeyには複数の列を含めることができます.キーを設定するとdatatableはkeyに従ってデータを並べ替えます.
DT[2,] #  2 
##    x         v
## 1: b 0.4874291
DT[x=="b",] # x=b  
##    x          v
## 1: b -0.8204684
## 2: b  0.4874291
## 3: b  0.7383247
cat(try(DT["b",],silent=TRUE)) 
## Error in `[.data.table`(DT, "b", ) : 
##   When i is a data.table (or character vector), x must be keyed (i.e. sorted, and, marked as sorted) so data.table knows which columns to join to and take advantage of x being sorted. Call setkey(x,...) first, see ?setkey.

キーが設定されていない場合、DT[b]操作は以上のエラーを報告します.setkey()でDT設定キーを設定できます.
setkey(DT,x)
DT["b",]
DT["b"] #      
##    x          v
## 1: b -0.8204684
## 2: b  0.4874291
## 3: b  0.7383247

デフォルトでは、グループのすべての要素mult='all'が返されますが、最初の要素を返すか、最後の要素を返すなど、他の結果が必要な場合は
DT["b",mult="first"]
##    x          v
## 1: b -0.8204684
DT["b",mult="last"]
##    x         v
## 1: b 0.7383247

次に、dataを実証するために1000万行のデータを作成します.tableの性能
grpsize = ceiling(1e7/26^2) # 10 million rows, 676 groups
tt=system.time( DF 26*grpsize),
 y=rep(letters,each=grpsize),
 v=runif(grpsize*26^2),
 stringsAsFactors=FALSE)
 )
head(DF,3)
##   x y         v
## 1 A a 0.9347052
## 2 A a 0.2121425
## 3 A a 0.6516738
tail(DF,3)
##          x y         v
## 10000066 Z z 0.9537745
## 10000067 Z z 0.6654964
## 10000068 Z z 0.9368095
dim(DF)
## [1] 10000068        3

DFのxが"R"の行とyが"h"の行を抽出してみましょう
system.time(ans1 "R" & DF$y=="h",])
##    user  system elapsed 
##    1.35    0.07    1.42
head(ans1,3)
##         x y         v
## 6642058 R h 0.2442074
## 6642059 R h 0.6491902
## 6642060 R h 0.5894140

私たちはdataを使います.tableは同じ操作をします.
DT = as.data.table(DF)
system.time(setkey(DT,x,y))
##    user  system elapsed 
##    0.13    0.01    0.14
system.time(ans2 "R","h")])
##    user  system elapsed 
##    0.02    0.00    0.02

キーを設定すると、ローを抽出する操作には待ち時間がほとんどかかりません.私たちが普段使っている操作より100倍速いことがわかります.注意すべきは、"=="オペレータを使用すると、dataにもかかわらず配列全体がスキャンされます.tableはこの方法でも抽出できますが、遅いので、できるだけ避けましょう.
system.time(ans1 "R" & y=="h"]) # works but is using data.table badly
##    user  system elapsed 
##    1.06    0.00    1.06

2.高速重合(fast grouping)
次にdataについて説明します.tableの2番目のパラメータ
DT[,sum(v)]
## [1] 4999770
head(DT[,sum(v),by=x])
##     x       V1
##  1: A 192270.6
##  2: B 192261.3
##  3: C 192292.2
##  4: D 191924.2
##  5: E 192457.3
##  6: F 192240.2

以上のコードはxをパケットとし,sum関数を順次呼び出し,各パケットxの総和を統計した.この機能はplyrパケットとdplyrパケットにも対応する関数で実現されていることは明らかであり,次にこの3つのパケットの速度を比較する.
#plyr 
system.time(
  ddply(DF,.(x),function(x)sum(x$v))
  )
##    user  system elapsed 
##    1.71    0.22    1.94
#dplyr 
system.time({
  DF%>%
  group_by(x)%>%
  summarise(sum(v))
})
##    user  system elapsed 
##    0.60    0.12    0.72
#data.table 
DT = as.data.table(DF)
system.time({
DT[,sum(v),by=x]
})
##    user  system elapsed 
##    0.12    0.02    0.14

以上の結果から明らかなdataが見られた.tableはdplyrとplyrパッケージよりはるかに速い
3.クイック接続
DT[X]を使用すると、Xのkey(keyが指定されていない場合はデフォルトの最初の列)とDTのkeyが接続されます.同様に、X[DT]はDTとXを接続します.
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
DT
##    x y v
## 1: a 1 1
## 2: a 3 2
## 3: a 6 3
## 4: b 1 4
## 5: b 3 5
## 6: b 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
X = data.table(c("b","c"),foo=c(4,2))
X
##    V1 foo
## 1:  b   4
## 2:  c   2
setkey(DT,x)
DT[X]
##    x y v foo
## 1: b 1 4   4
## 2: b 3 5   4
## 3: b 6 6   4
## 4: c 1 7   2
## 5: c 3 8   2
## 6: c 6 9   2
setkey(X,V1)
X[DT]
##    V1 foo y v
## 1:  a  NA 1 1
## 2:  a  NA 3 2
## 3:  a  NA 6 3
## 4:  b   4 1 4
## 5:  b   4 3 5
## 6:  b   4 6 6
## 7:  c   2 1 7
## 8:  c   2 3 8
## 9:  c   2 6 9

on操作を使用して、同じ2つのカラムを接続することもできます.
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
X = data.table(x=c("b","c"),foo=c(4,2))
DT[X, on="x"] # join on columns 'x'
##    x y v foo
## 1: b 1 4   4
## 2: b 3 5   4
## 3: b 6 6   4
## 4: c 1 7   2
## 5: c 3 8   2
## 6: c 6 9   2

dataも使えますtableのmerge関数
(dt1 1:10], X = 1:10, key = "A"))
##     A  X
##  1: a  1
##  2: b  2
##  3: c  3
##  4: d  4
##  5: e  5
##  6: f  6
##  7: g  7
##  8: h  8
##  9: i  9
## 10: j 10
(dt2 5:14], Y = 1:10, key = "A"))
##     A  Y
##  1: e  1
##  2: f  2
##  3: g  3
##  4: h  4
##  5: i  5
##  6: j  6
##  7: k  7
##  8: l  8
##  9: m  9
## 10: n 10
merge(dt1, dt2)
##    A  X Y
## 1: e  5 1
## 2: f  6 2
## 3: g  7 3
## 4: h  8 4
## 5: i  9 5
## 6: j 10 6

共有主義者(sharism)として、私のすべてのインターネットが発表した図文はCCの著作権に従い、転載は作者の情報を保留し、著者a 358463121コラムを明記してください.http://blog.csdn.net/a358463121、ソースコードについてはGitHubアドレスを明記してください.https://github.com/358463121/.ビジネスの使用は著者に連絡してください.