サーチ…


前書き

Data.tableは、基盤Rからのデータフレームの機能を拡張し、特にパフォーマンスと構文を向上させるパッケージです。詳細については、パッケージのドキュメント領域( data.table入門)を参照してください。

構文

  • DT[i, j, by]
    #DT [where | select | update | do、by]
  • DT[...][...]
    #連鎖
  • ################# Shortcuts, special functions and special symbols inside DT[...]
  • 。()
    list()の代わりにいくつかの引数に#
  • J()
    リスト内の#がiの#で置き換えられました。
  • :=
    #in j、列の追加または変更に使用される関数
  • N
    #iで、行の総数
    #in j、グループ内の行数
  • 。私
    #in j、テーブル内の行番号のベクトル(iでフィルタリングされた)
  • 。SD
    #in j、データの現在のサブセット
    .SDcols引数で選択された#
  • .GRP
    #in j、データのサブセットの現在のインデックス
  • 。によって
    #in j、データの現在のサブセットの値によるリスト
  • V1、V2、...
    #jで作成された名前のない列のデフォルト名
  • ################# Joins inside DT[...]
  • DT1 [DT2、on、j]
    #2つのテーブルを結合する
  • 私。*
    #結合後のDT2の列の特別な接頭辞
  • by = EACHI
    #特殊オプションは結合でのみ使用可能です
  • DT1 [!DT2、on、j]
    #2つのテーブルのアンチ・ジョイン
  • DT1 [DT2、on、roll、j]
    #2つのテーブルを結合し、最後の列をon =
  • ################# Reshaping, stacking and splitting
  • 溶融(DT、id.vars、measure.vars)
    #長い形式に変換する
    #複数の列の場合は、measure.vars = patterns(...)を使用します。
  • dcast(DT、数式)
    #ワイドフォーマットに変換する
  • rbind(DT1、DT2、...)
    #stack列挙されたdata.tables
  • rbindlist(DT_list、idcol)
    #データテーブルのリストをスタックする
  • 分割(DT、by)
    #data.tableをリストに分割する
  • ################# Some other functions specialized for data.tables
  • ホバリング
    #重複結合
  • マージ
    #2つのテーブルを結合する別の方法
  • セット
    #列を追加または変更する別の方法
  • fintersect、fsetdiff、funion、fsetequal、ユニーク、重複、anyDuplicated
    #行を要素とするset-theory操作
  • ユニークN
    #異なる行の数
  • rowidv(DT、cols)
    #colsで指定された各グループ内の行ID(1〜N)
  • rleidv(DT、cols)
    #colsの実行によって決定される各グループ内のグループID(1〜.GRP)
  • シフト(DT、n、タイプ= c(「ラグ」、「リード」))
    #すべての列にシフト演算子を適用する
  • setorder、setcolorder、setnames、setkey、setindex、setattr
    #属性と参照順の変更

備考

インストールとサポート

data.tableパッケージをインストールするには:

# install from CRAN
install.packages("data.table")       

# or install development version 
install.packages("data.table", type = "source", repos = "http://Rdatatable.github.io/data.table")

# and to revert from devel to CRAN, the current version must first be removed
remove.packages("data.table")
install.packages("data.table")

パッケージの公式サイトには、ヘルプの開始を支援するwikiページ、およびウェブ上のプレゼンテーションと記事のリストがあります。 StackOverflowや他の場所で質問をする前に、サポートページをお読みください

パッケージのロード

上記の例の関数の多くは、data.table名前空間に存在します。それらを使用するには、 library(data.table)ような行を最初に追加するか、単純にfread代わりにdata.table::freadようなフルパスを使用する必要があります。個々の関数のヘルプについては、構文はhelp("fread")または?freadです。パッケージがロードされていない場合は、 ?data.table::freadようなフルネームを使用してください。

data.tableの作成

data.tableは、基底Rからのdata.frameクラスの拡張バージョンです。したがって、 class()属性はvector "data.table" "data.frame"あり、data.frameで機能する関数もdata.tableで作業します。 data.tableを作成、ロード、または強制する方法はたくさんあります。

ビルド

data.tableパッケージをインストールしてアクティブ化することを忘れないでください

library(data.table)

同じ名前のコンストラクタがあります:

DT <- data.table(
  x = letters[1:5], 
  y = 1:5, 
  z = (1:5) > 3
)
#    x y     z
# 1: a 1 FALSE
# 2: b 2 FALSE
# 3: c 3 FALSE
# 4: d 4  TRUE
# 5: e 5  TRUE

data.frameとは異なり、 data.tableは文字列をファクタに強制しません。

sapply(DT, class)
#               x           y           z 
#     "character"   "integer"   "logical" 

読む

テキストファイルから読み込むことができます:

dt <- fread("my_file.csv")

read.csvとは異なり、 freadは文字列を要素ではなく文字列として読み込みます。

data.frameを変更する

効率を上げるため、data.tableはdata.frameまたはlistを変更して、(コピーを作成せずに、またはメモリの場所を変更せずに)data.tableをその場で作成する方法を提供します:

# example data.frame
DF <- data.frame(x = letters[1:5], y = 1:5, z = (1:5) > 3)
# modification
setDT(DF)

オブジェクトDFはインプレースで修正されているため、結果を<-割り当てないことに注意してください。 data.frameのクラス属性は保持されます:

sapply(DF, class)
#         x         y         z 
#  "factor" "integer" "logical" 

オブジェクトをdata.tableに強制する

あなたが持っている場合はlistdata.frame 、またはdata.table 、あなたが使用する必要がありますsetDTに変換する機能を data.tableそれはコピーを(これは作るのではなく、参照することにより、変換を行いますので、 as.data.tableありません)。大規模なデータセットを扱う場合は、これが重要です。

あなたは(このようなマトリックスのような)他のRオブジェクトを持っている場合は、使用する必要がありますas.data.tableにそれを強制するdata.table

mat <- matrix(0, ncol = 10, nrow = 10)

DT <- as.data.table(mat)
# or
DT <- data.table(mat)

列の追加と変更

DT[where, select|update|do, by]構文は、data.tableの列を処理するために使用されます。

  • "where"部分がi引数です。
  • "select | update | do"部分はj引数です

これらの2つの引数は、通常、名前ではなく位置によって渡されます。

以下の例のデータは

mtcars = data.table(mtcars, keep.rownames = TRUE)

列全体の編集

新しい列を割り当てるには、 j内で:=演算子を使用します。

mtcars[, mpg_sq := mpg^2]

NULL設定して列を削除する:

mtcars[, mpg_sq := NULL]

:=演算子の多変量形式を使用して複数の列を追加する:

mtcars[, `:=`(mpg_sq = mpg^2, wt_sqrt = sqrt(wt))]
# or 
mtcars[, c("mpg_sq", "wt_sqrt") := .(mpg^2, sqrt(wt))]

列が依存しており、順番に定義する必要がある場合は、1つの方法があります。

mtcars[, c("mpg_sq", "mpg2_hp") := .(temp1 <- mpg^2, temp1/hp)]

.()構文は、 LHS := RHSの右側が列のリストである場合に使用されます。

動的に決定される列名の場合は、かっこを使用します。

vn = "mpg_sq"
mtcars[, (vn) := mpg^2]

ほとんどの場合、カラムはsetで変更することもできます。

set(mtcars, j = "hp_over_wt", v = mtcars$hp/mtcars$wt)

列のサブセットの編集

i引数を使用して、行の部分集合を「編集」する場所を指定します。

mtcars[1:3, newvar := "Hello"]
# or
set(mtcars, j = "newvar", i = 1:3, v = "Hello")  

data.frameの場合と同様に、行番号または論理テストを使用してサブセット化することができます。 iで「結合」を使用することもできますが、別の例ではより複雑な作業が含まれています。

列属性の編集

levels<-またはnames<-などの属性を編集する関数は、実際にオブジェクトを変更されたコピーで置き換えます。 data.tableの1つの列でのみ使用されても、オブジェクト全体がコピーされて置き換えられます。

コピーを持たないオブジェクトを変更するには、 setnamesを使用してdata.tableまたはdata.frameおよびsetattrの列名を変更し、オブジェクトの属性を変更します。

# Print a message to the console whenever the data.table is copied
tracemem(mtcars)
mtcars[, cyl2 := factor(cyl)]

# Neither of these statements copy the data.table
setnames(mtcars, old = "cyl2", new = "cyl_fac")
setattr(mtcars$cyl_fac, "levels", c("four", "six", "eight"))

# Each of these statements copies the data.table
names(mtcars)[names(mtcars) == "cyl_fac"] <- "cf"
levels(mtcars$cf) <- c("IV", "VI", "VIII")

これらの変更は参照によって行われるため、 グローバルに変更されています。ある環境でそれらを変更すると、すべての環境のオブジェクトに影響します。

# This function also changes the levels in the global environment
edit_levels <- function(x) setattr(x, "levels", c("low", "med", "high"))
edit_levels(mtcars$cyl_factor)

data.tableの特殊記号

。SD

.SDは、 data.tableで使用さbyすべての列を除いて、各グループのdata.tableのサブセットを参照します。

.SDlapplyは、 data.tableグループdata.tableに複数のカラムに任意の関数を適用するために使用できます

同じ組み込みデータセットmtcarsを引き続き使用しmtcars

mtcars = data.table(mtcars) # Let's not include rownames to keep things simpler

データセット内のすべての列の、 シリンダ数cyl平均:

mtcars[ , lapply(.SD, mean), by = cyl]

#   cyl      mpg     disp        hp     drat       wt     qsec        vs        am     gear     carb
#1:   6 19.74286 183.3143 122.28571 3.585714 3.117143 17.97714 0.5714286 0.4285714 3.857143 3.428571
#2:   4 26.66364 105.1364  82.63636 4.070909 2.285727 19.13727 0.9090909 0.7272727 4.090909 1.545455
#3:   8 15.10000 353.1000 209.21429 3.229286 3.999214 16.77214 0.0000000 0.1428571 3.285714 3.500000

cylとは別に、 vsamgearcarbなどのデータセットには他のカテゴリの列があります。これらの列のmeanを取ることは実際には意味がありません。だから、これらの列を除外しましょう。これは、 .SDcolsが絵になる場所です。

.SDcols

.SDcolsの列を指定data.tableに含まれています.SD

歯車の数で、データセットのすべての列(連続列)の平均gear 、及び気筒数cylによって配置、 gearcyl

# All the continuous variables in the dataset
cols_chosen <- c("mpg", "disp", "hp", "drat", "wt", "qsec")

mtcars[order(gear, cyl), lapply(.SD, mean), by = .(gear, cyl), .SDcols = cols_chosen]

#   gear cyl    mpg     disp       hp     drat       wt    qsec
#1:    3   4 21.500 120.1000  97.0000 3.700000 2.465000 20.0100
#2:    3   6 19.750 241.5000 107.5000 2.920000 3.337500 19.8300
#3:    3   8 15.050 357.6167 194.1667 3.120833 4.104083 17.1425
#4:    4   4 26.925 102.6250  76.0000 4.110000 2.378125 19.6125
#5:    4   6 19.750 163.8000 116.5000 3.910000 3.093750 17.6700
#6:    5   4 28.200 107.7000 102.0000 4.100000 1.826500 16.8000
#7:    5   6 19.700 145.0000 175.0000 3.620000 2.770000 15.5000
#8:    5   8 15.400 326.0000 299.5000 3.880000 3.370000 14.5500

たぶん、グループ別にmeanを計算したくないかもしれません。データセット内のすべての車の平均を計算するために、 by変数は指定しません。

mtcars[ , lapply(.SD, mean), .SDcols = cols_chosen] 

#        mpg     disp       hp     drat      wt     qsec
#1: 20.09062 230.7219 146.6875 3.596563 3.21725 17.84875

注意:

  • あらかじめcols_chosenを定義する必要はありません。 .SDcolsは列名を直接取ることができます
  • .SDcolsは列番号のベクトルを直接取ることもできます。上記の例では、これはmtcars[ , lapply(.SD, mean), .SDcols = c(1,3:7)]

N

.Nはグループ内の行数の省略形です。

iris[, .(count=.N), by=Species]

#      Species count
#1:     setosa    50
#2: versicolor    50
#3:  virginica    50

data.frameとdata.tableの両方と互換性のあるコードを書く

サブセット設定構文の違い

data.tableは、 data.framematrix 、(2D) array他に、Rで利用可能ないくつかの2次元データ構造の1つです。これらのクラスはすべてサブセット化に非常によく似た構文を使用しますが、 A[rows, cols]スキーマです。

保存されている次のデータを検討matrixdata.framedata.table

ma <- matrix(rnorm(12), nrow=4, dimnames=list(letters[1:4], c('X', 'Y', 'Z')))
df <- as.data.frame(ma)
dt <- as.data.table(ma)

ma[2:3]  #---> returns the 2nd and 3rd items, as if 'ma' were a vector (because it is!)
df[2:3]  #---> returns the 2nd and 3rd columns
dt[2:3]  #---> returns the 2nd and 3rd rows!

何が返されるかを確認したい場合は、 明示的にする方が良いです。

特定のを取得するには、範囲の後にカンマを追加します。

ma[2:3, ]  # \
df[2:3, ]  #  }---> returns the 2nd and 3rd rows
dt[2:3, ]  # /

しかし、 をサブセット化したい場合、いくつかのケースは異なって解釈されます。変数に格納されていない整数または文字インデックスを使用して、3つのすべてを同じ方法でサブセット化することができます。

ma[, 2:3]          #  \
df[, 2:3]          #   \
dt[, 2:3]          #    }---> returns the 2nd and 3rd columns
ma[, c("Y", "Z")]  #   /
df[, c("Y", "Z")]  #  /
dt[, c("Y", "Z")]  # /

ただし、引用符で囲まれていない変数名では異なります

mycols <- 2:3
ma[, mycols]                # \
df[, mycols]                #  }---> returns the 2nd and 3rd columns
dt[, mycols, with = FALSE]  # /

dt[, mycols]                # ---> Raises an error

最後のケースでは、 mycolsは列の名前として評価されます。 dtmycolsという名前の列を見つけることができないため、エラーが発生します。

注: data.tableパッケージdata.tableバージョンでは、この動作は若干異なります。 dtを環境として使用して列索引内のものは評価されていました。だから、 dt[, 2:3]dt[, mycols]はベクトル2:3返します。変数mycolsが親環境に存在するため、2番目のケースではエラーは発生しません。

data.frameとdata.tableとの互換性を維持するための戦略

data.framedata.table動作することが保証されているコードを書く理由はたくさんあります。おそらく、 data.frame使用を余儀なくされたり、使用方法がわからないコードを共有する必要があるかもしれません。したがって、これを達成するためのいくつかの主要な戦略が利便性の順にあります:

  1. 両方のクラスで同じように動作する構文を使用します。
  2. 最短の構文と同じことをする共通の関数を使用してください。
  3. data.tabledata.tableとして動作させdata.frame (例:特定のメソッドprint.data.frame呼び出します)。
  4. それらを最終的にはlistとして扱います。
  5. 何かをする前にテーブルをdata.frameに変換します(巨大なテーブルの場合は悪い考えです)。
  6. 依存関係が問題でない場合は、表をdata.table変換します。

サブセット行その単純な、 [, ]セレクタカンマでつけてください:

A[1:10, ]
A[A$var > 17, ]  # A[var > 17, ] just works for data.table

サブセット列。単一の列が必要な場合は、 $または[[ ]]セレクタを使用します。

A$var
colname <- 'var'
A[[colname]]
A[[1]]

均一な方法で複数の列を取得したい場合は、少しアピールする必要があります。

B <- `[.data.frame`(A, 2:4)

# We can give it a better name
select <- `[.data.frame`
B <- select(A, 2:4)
C <- select(A, c('foo', 'bar'))

サブセット「索引付け」行 data.framedata.frameがありrow.namesdata.tableは独自のkey機能があります。最善の方法は、 row.names完全に避け、 row.namesの場合は既存の最適化をdata.tableすることです。

B <- A[A$var != 0, ]
# or...
B <- with(A, A[var != 0, ])  # data.table will silently index A by var before subsetting

stuff <- c('a', 'c', 'f')
C <- A[match(stuff, A$name), ]  # really worse than: setkey(A); A[stuff, ]

1列のテーブルを取得し、ベクトルとして行を取得します。これまでの私たちが見たことは簡単です:

B <- select(A, 2)    #---> a table with just the second column
C <- unlist(A[1, ])  #---> the first row as a vector (coerced if necessary)

data.tableにキーを設定する

はい、あなたは1.9.6前にSETKEYする必要があります

過去には(1.9.6より前)、テーブルのキーとしてカラムを設定することで、特に大きなテーブルの場合、 data.tableが高速化されました。 [検索速度が544倍向上した2015年9月版のイントロ・ビネット・ページ5を参照]テーブルを設定するときに、この設定キーを 'setkey'で使用するか、 'key ='列を設定する古いコードがあります。

library(data.table)
DT <- data.table(
  x = letters[1:5], 
  y = 5:1, 
  z = (1:5) > 3
)

#> DT
#   x y     z
#1: a 5 FALSE
#2: b 4 FALSE
#3: c 3 FALSE
#4: d 2  TRUE
#5: e 1  TRUE

setkeyコマンドでキーを設定します。複数の列を持つキーを持つことができます。

setkey(DT, y)

テーブルのテーブルのキーを確認する()

tables()

> tables()
     NAME NROW NCOL MB COLS  KEY
[1,] DT      5    3  1 x,y,z y  
Total: 1MB

これはあなたのデータを再ソートすることに注意してください。

#> DT
#   x y     z
#1: e 1  TRUE
#2: d 2  TRUE
#3: c 3 FALSE
#4: b 4 FALSE
#5: a 5 FALSE

今は不要です

v1.9.6以前は、特にテーブルを結合する特定の操作のキーを設定する必要がありました。 data.tableの開発者はスピードアップし、キーの依存関係を置き換えることができる"on="機能を導入しました。詳細な議論については、ここのSOの回答を参照してください

2017年1月、開発者は二次インデックスの周囲にバイナリを書き込んで、 "on"構文を説明し、高速インデックス作成のために他の列を識別できるようにしました。

セカンダリインデックスを作成しますか?

keyと似た方法で、あなたはsetindex(DT, key.col)またはsetindex(DT, key.col) setindexv(DT, "key.col.string")設定できます。ここでDTはあなたのdata.tableです。 setindex(DT, NULL)すべてのインデックスを削除しsetindex(DT, NULL)

indices(DT)を使用してセカンダリインデックスを参照してください。

なぜ二次指標ですか?

これ 、(キーとは異なり)テーブルをソートしませんが、 "on"構文を使用して迅速なインデックス作成を可能にします。キーは1つだけですが、複数のセカンダリインデックスを使用することができます。これにより、テーブルのキーを再作成して解決する必要がなくなります。サブセット化する列を変更すると、サブセット化が高速化されます。

上の例ではyが表DTのキーであったことを思い出してください。

DT
# x y     z
# 1: e 1  TRUE
# 2: d 2  TRUE
# 3: c 3 FALSE
# 4: b 4 FALSE
# 5: a 5 FALSE

# Let us set x as index 
setindex(DT, x)

# Use indices to see what has been set
indices(DT)
# [1] "x"

# fast subset using index and not keyed column
DT["c", on ="x"]
#x y     z
#1: c 3 FALSE

# old way would have been rekeying DT from y to x, doing subset and 
# perhaps keying back to y (now we save two sorts)
# This is a toy example above but would have been more valuable with big data sets


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow