次のようなデータがあります。
dt <- structure(list(fct = structure(c(1L, 2L, 3L, 4L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"), X = c(2L, 4L, 3L, 2L, 5L, 4L, 7L, 2L, 9L, 1L, 4L, 2L, 5L, 4L, 2L)), .Names = c("fct", "X"), class = "data.frame", row.names = c(NA, -15L))
fct
変数の値に基づいて、このデータフレームから行を選択します。たとえば、「a」または「c」のいずれかを含む行を選択する場合、これを実行できます。
dt[dt$fct == 'a' | dt$fct == 'c', ]
をもたらす
1 a 2
3 c 3
5 c 5
7 a 7
9 c 9
10 a 1
12 c 2
14 c 4
予想通り。しかし、実際のデータはより複雑であり、実際には次のようなベクトルの値に基づいて行を選択したい
vc <- c('a', 'c')
だから私は試した
dt[dt$fct == vc, ]
もちろん、それは機能しません。ベクトルをループして必要な行を引き出して新しいデータフレームに追加する何かをコーディングできることは知っていますが、もっとエレガントな方法があればいいのにと思っていました。
それでは、ベクトルvc
の内容に基づいてデータをフィルタリング/サブセットするにはどうすればよいですか?
?"%in%"
をご覧ください。
dt[dt$fct %in% vc,]
fct X
1 a 2
3 c 3
5 c 5
7 a 7
9 c 9
10 a 1
12 c 2
14 c 4
?is.element
を使用することもできます:
dt[is.element(dt$fct, vc),]
上記と同様に、filter
からdplyr
を使用します。
filter(df, fct %in% vc)
別のオプションは、キー付きdata.table
を使用することです。
library(data.table)
setDT(dt, key = 'fct')[J(vc)] # or: setDT(dt, key = 'fct')[.(vc)]
結果:
fct X
1: a 2
2: a 7
3: a 1
4: c 3
5: c 5
6: c 9
7: c 2
8: c 4
これは何をしますか:
setDT(dt, key = 'fct')
は、fct
列をキーとして、data.frame
をdata.table
(data.frame
の拡張形式)に変換します。[J(vc)]
でvc
ベクトルでサブセット化することができます。注:キーが因子/文字変数の場合、setDT(dt, key = 'fct')[vc]
も使用できますが、vc
が数値ベクトルの場合は機能しません。 vc
が数値ベクトルであり、J()
または.()
でラップされていない場合、vc
は行インデックスとして機能します。
keysとサブセットの概念の詳細な説明は、ビネット Keysと高速バイナリ検索ベースのサブセット 。
コメントで@Frankが提案する代替案:
setDT(dt)[J(vc), on=.(fct)]
vc
にdt
に存在しない値が含まれる場合、nomatch = 0
を追加する必要があります。
setDT(dt, key = 'fct')[J(vc), nomatch = 0]
または:
setDT(dt)[J(vc), on=.(fct), nomatch = 0]