data.table
キーとインデックスの使用
サーチ…
前書き
備考
公式のビネットはこのトピックのベストな紹介です:
キー対インデックス
data.tableは一連の列によって「キー付け」され、関心のある関数にそれらの列によってデータがソートされていることを伝えることができます。キーを取得または設定するには、 ?key
記載されている機能を使用し?key
。
同様に、関数はdata.tableの「インデックス」を利用することができます。各索引と表は複数の列を持つことができます。一連の列を基準にしてデータの順序に関する情報を保管します。キーのように、インデックスは特定のタスクをスピードアップすることができます。インデックスを取得または設定するには、 ?indices
記載されている関数を使用し?indices
。
インデックスは自動的に設定することもできます(現在は、一度に1つの列に対してのみ)。これの仕組みと必要に応じてそれを無効にする方法の詳細については?datatable.optimize
を参照してください。
確認と更新
キー列には値がありません。
キーとインデックスは属性として格納され、偶然にも表のデータの実際の順序に対応していない可能性があります。多くの関数はキーまたはインデックスの有効性をチェックしてから使用しますが、それは留意する価値があります。
ソート順が保持されていることが明らかでない更新後に、キーとインデックスが削除されます。たとえば、 DT = data.table(a=c(1,2,4), key="a")
から開始して、 DT[2, a := 3]
ように更新すると、キーは破損します。
サブセットの選択のパフォーマンスを向上させる
# example data
set.seed(1)
n = 1e7
ng = 1e4
DT = data.table(
g1 = sample(ng, n, replace=TRUE),
g2 = sample(ng, n, replace=TRUE),
v = rnorm(n)
)
1列のマッチング
==
または%in%
サブセット化操作を初めて実行した後
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0.12 0.03 0.16
g1
のインデックスが自動的に作成されました。その後のサブセッティング操作はほぼ即座に実行されます。
system.time(
DT[ g1 %in% 1:100]
)
# user system elapsed
# 0 0 0
インデックスの作成または使用を監視するには、 verbose=TRUE
オプションを追加するか、グローバル設定options(datatable.verbose=TRUE)
変更しoptions(datatable.verbose=TRUE)
。
複数の列のマッチング
現在、2つの列を照合しても自動的に索引が作成されるわけではありません。
system.time(
DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
# user system elapsed
# 0.57 0.00 0.57
これを再実行すると遅くなります。 setindex(DT, g1, g2)
でインデックスを手動で追加しても、このクエリがパッケージによって最適化されていないため、インデックスは遅くなります。
幸いにも、検索したい値の組み合わせとインデックスを列挙できれば、すぐに等価結合することができます:
system.time(
DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
# user system elapsed
# 0.53 0.00 0.54
setindex(DT, g1, g2)
system.time(
DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
# user system elapsed
# 0 0 0
CJ
では、組み合わせの数が大きすぎることに注意することが重要です。