data.tableの.I関連の話
irisデータにおいて、Species単位で最大のSepal.Lengthを返す行のデータを取得したい
twitter上でdata.tableマイスター達に教えていただいたので復習しておく。
@dichika 唐突ですがDT[DT[, .I[Sepal.Length==max(Sepal.Length)], by = Species]$V1]が主流らしいです http://t.co/SPHXcjggq9
— Хашаа (@d_khashaa) 2015, 8月 24
@dichika できました。data.tableっぽいやり方だとこのようです。
DT <- data.table(iris)
DT[DT[, .I[Sepal.Length == max(Sepal.Length)], by = Species]$V1]
— Think more, try less (@Keiku) 2015, 8月 25
.Iと組み合わせることでbyで指定したグループ単位の行番号が返ってくる
library("data.table") DT <- as.data.table(iris) DT[,.I[which.max(Sepal.Length)], by=Species] # Species V1 # 1: setosa 15 # 2: versicolor 51 # 3: virginica 132
data.tableのi部分に行番号を指定することで取得大成功。
DT[DT[,.I[which.max(Sepal.Length)], by=Species]$V1] # Sepal.Length Sepal.Width Petal.Length Petal.Width Species # 1: 5.8 4.0 1.2 0.2 setosa # 2: 7.0 3.2 4.7 1.4 versicolor # 3: 7.9 3.8 6.4 2.0 virginica
身もふたもないけど、data.tableの文法に悩んですぐ解決しない場合はdplyr使うのが手っ取り早い。
こんな処理でいちいち考えたくない。
library("dplyr") DT %>% group_by(Species) %>% filter(Sepal.Length==max(Sepal.Length)) # Source: local data table [3 x 5] # Groups: Species # # Sepal.Length Sepal.Width Petal.Length Petal.Width Species # 1 5.8 4.0 1.2 0.2 setosa # 2 7.0 3.2 4.7 1.4 versicolor # 3 7.9 3.8 6.4 2.0 virginica
.Iなどのspecial variableについてはdata.tableのパッケージヘルプ(?data.table)に書いてある。
.Iについての説明は以下の通り。
.I is an integer vector equal to seq_len(nrow(x)).
While grouping, it holds for each item in the group, it's row location in x.
This is useful to subset in j; e.g. DT[, .I[which.max(somecol)], by=grp].