data.table
再形成、積み重ね、分割
サーチ…
備考
「data.tablesを使用した効率的な再成形」という公式のビネットは、このトピックのベスト・イントロダクションです。
多くの再構成作業では、長い形式と広い形式の間で移動する必要があります。
- ワイド・データは、各列が別々の変数を表すデータであり、行は別々の観測を表す行です
- ロングデータは、フォームID |変数|値であり、各行は観測変数対を表す
data.tableで溶かしてキャストする
data.table
は、効率的かつ簡単にデータを再構築する幅広い可能性を提供します
例えば、長いものから広いものへのvalue.var
、複数の変数を同時にvalue.var
とfun.aggregate
パラメータに渡すことができます
library(data.table) #v>=1.9.6
DT <- data.table(mtcars)
長いものから長いもの
dcast(DT, gear ~ cyl, value.var = c("disp", "hp"), fun = list(mean, sum))
gear disp_mean_4 disp_mean_6 disp_mean_8 hp_mean_4 hp_mean_6 hp_mean_8 disp_sum_4 disp_sum_6 disp_sum_8 hp_sum_4 hp_sum_6 hp_sum_8
1: 3 120.100 241.5 357.6167 97 107.5 194.1667 120.1 483.0 4291.4 97 215 2330
2: 4 102.625 163.8 NaN 76 116.5 NaN 821.0 655.2 0.0 608 466 0
3: 5 107.700 145.0 326.0000 102 175.0 299.5000 215.4 145.0 652.0 204 175 599
これはgear
をインデックス列として設定し、 mean
とsum
はgear
とcyl
組み合わせごとにdisp
とhp
を計算します。いくつかの組み合わせが存在しない場合は、 na.rm = TRUE
( mean
とsum
関数に渡されます)などの追加パラメータを指定するか、組み込みfill
引数を指定することがfill
ます。余白を追加したり、欠落している組み合わせを削除したり、データをサブセット化することもできます。 ?data.table::dcast
もっと見る
ワイドからロングまで
ワイドからロングまでの形をmeasure.vars
に、たとえば、正規表現を使用してmeasure.vars
パラメータに列を渡すことができます
print(melt(DT, c("cyl", "gear"), measure = patterns("^d", "e")), n = 10)
cyl gear variable value1 value2
1: 6 4 1 160.00 16.46
2: 6 4 1 160.00 17.02
3: 4 4 1 108.00 18.61
4: 6 3 1 258.00 19.44
5: 8 3 1 360.00 17.02
---
60: 4 5 2 3.77 5.00
61: 8 5 2 4.22 5.00
62: 6 5 2 3.62 5.00
63: 8 5 2 3.54 5.00
64: 4 4 2 4.11 4.00
これはなりmelt
によるデータcyl
とgear
で始まる変数のすべての値が、索引列としてのd
( disp
& drat
)に存在するであろうvalue1
と文字含まれている変数の値e
それらに( qsec
gear
)がvalue2
列に表示されます。
また、指定しながら、結果にすべての列名を変更することができvariable.name
とvalue.name
引数をしたり、かどうかを決定しcharacter
列が自動的に変換するfactor
を指定しながら、Sかvariable.factor
とvalue.factor
引数を。もっと詳しくは?data.table::melt
`data.table`を使って変形する
data.table
はreshape2
のmelt
& dcast
関数をdcast
ます
( 参考:data.tablesを使用した効率的な再形成 )
library(data.table)
## generate some data
dt <- data.table(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2),
value = rnorm(8)
)
dt
# name numbers value
# 1: firstName 1 -0.8551881
# 2: firstName 2 -1.0561946
# 3: firstName 3 0.2671833
# 4: firstName 4 1.0662379
# 5: secondName 1 -0.4771341
# 6: secondName 2 1.2830651
# 7: secondName 3 -0.6989682
# 8: secondName 4 -0.6592184
ロングトゥーワイド
dcast(data = dt,
formula = name ~ numbers,
value.var = "value")
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
複数の列( data.table
1.9.6)
## add an extra column
dt[, value2 := value * 2]
## cast multiple value columns
dcast(data = dt,
formula = name ~ numbers,
value.var = c("value", "value2"))
# name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 0.3672866 -1.6712572 3.190562 0.6590155
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 -1.6409368 0.9748581 1.476649 1.1515627
ワイドからロングまで
## use a wide data.table
dt <- fread("name 1 2 3 4
firstName 0.1836433 -0.8356286 1.5952808 0.3295078
secondName -0.8204684 0.4874291 0.7383247 0.5757814", header = T)
dt
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
## melt to long, specifying the id column, and the name of the columns
## in the resulting long data.table
melt(dt,
id.vars = "name",
variable.name = "numbers",
value.name = "myValue")
# name numbers myValue
# 1: firstName 1 0.1836433
# 2: secondName 1 -0.8204684
# 3: firstName 2 -0.8356286
# 4: secondName 2 0.4874291
# 5: firstName 3 1.5952808
# 6: secondName 3 0.7383247
# 7: firstName 4 0.3295078
# 8: secondName 4 0.5757814
メルトを使用したワイドフォーマットからロングフォーマットへ
融解:基本
融解は、データをワイドフォーマットからロングフォーマットに変換するために使用されます。
広いデータセットから始める:
DT = data.table(ID = letters[1:3], Age = 20:22, OB_A = 1:3, OB_B = 4:6, OB_C = 7:9)
data.tableのmelt
関数を使用してデータを溶かすことができます。これは長い形式の別のdata.tableを返します:
melt(DT, id.vars = c("ID","Age"))
1: a 20 OB_A 1
2: b 21 OB_A 2
3: c 22 OB_A 3
4: a 20 OB_B 4
5: b 21 OB_B 5
6: c 22 OB_B 6
7: a 20 OB_C 7
8: b 21 OB_C 8
9: c 22 OB_C 9
class(melt(DT, id.vars = c("ID","Age")))
# "data.table" "data.frame"
id.vars
パラメーターに設定されていない列はすべて変数とみなされます。あるいは、 measure.vars
引数を使用して明示的に設定することもできます。
melt(DT, measure.vars = c("OB_A","OB_B","OB_C"))
ID Age variable value
1: a 20 OB_A 1
2: b 21 OB_A 2
3: c 22 OB_A 3
4: a 20 OB_B 4
5: b 21 OB_B 5
6: c 22 OB_B 6
7: a 20 OB_C 7
8: b 21 OB_C 8
9: c 22 OB_C 9
この場合、 measure.vars
設定されていない列はすべてIDとみなされます。
両方を明示的に設定すると、選択した列のみが返されます。
melt(DT, id.vars = "ID", measure.vars = c("OB_C"))
ID variable value
1: a OB_C 7
2: b OB_C 8
3: c OB_C 9
結果の変数と値の命名
variable.name
とvalue.name
を使用して、返されるテーブルの列名を操作できvariable.name
melt(DT,
id.vars = c("ID"),
measure.vars = c("OB_C"),
variable.name = "Test",
value.name = "Result"
)
ID Test Result
1: a OB_C 7
2: b OB_C 8
3: c OB_C 9
結果のメジャー変数のタイプの設定
デフォルトでは、 measure.vars
をmeasure.vars
すると、すべてのmeasure.vars
が係数に変換されます。
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
class(M_DT[, variable])
# "factor"
代わりに文字として設定するには、 variable.factor
引数を使用しvariable.factor
。
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), variable.factor = FALSE)
class(M_DT[, variable])
# "character"
値は、通常、元の列のデータ型を継承します。
class(DT[, value])
# "integer"
class(M_DT[, value])
# "integer"
競合がある場合、データ型は強制的に強制されます。例えば:
M_DT <- melt(DT,id.vars = c("Age"), measure.vars = c("ID","OB_C"))
class(M_DT[, value])
# "character"
溶かすとき、因子変数は文字型に強制されます:
DT[, OB_C := factor(OB_C)]
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
class(M_DT)
# "character"
これを避け、最初の入力を保持するには、 value.factor
引数を使用します。
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), value.factor = TRUE)
class(M_DT)
# "factor"
欠損値の処理
デフォルトでは、任意のNA
値は溶けたデータに保存されます
DT = data.table(ID = letters[1:3], Age = 20:22, OB_A = 1:3, OB_B = 4:6, OB_C = c(7:8,NA))
melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
ID variable value
1: a OB_C 7
2: b OB_C 8
3: c OB_C NA
これらをデータから削除する必要がある場合は、 na.rm = TRUE
に設定します
melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), na.rm = TRUE)
ID variable value
1: a OB_C 7
2: b OB_C 8
dcastを使用して、長い形式から広い形式へ
キャスティング:基本
キャスティングは、データを長い形式から広い形式に変換するために使用されます。
長いデータセットから始める:
DT = data.table(ID = rep(letters[1:3],3), Age = rep(20:22,3), Test = rep(c("OB_A","OB_B","OB_C"), each = 3), Result = 1:9)
dcast
関数を使用してデータをキャストできます。これは、ワイドフォーマットの別のdata.tableを返します。
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
class(dcast(DT, formula = ID ~ Test, value.var = "Result"))
[1] "data.table" "data.frame"
値をキャストする
適切なキャストにはvalue.var
引数が必要です。指定されていない場合、dcastはデータに基づいて前提を設定します。
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
ID OB_A OB_B OB_C
1: a 20 20 20
2: b 21 21 21
3: c 22 22 22
複数のvalue.var
リストにvalue.var
ことができます
dcast(DT, formula = ID ~ Test, value.var = list("Result","Age"))
ID Result_OB_A Result_OB_B Result_OB_C Age_OB_A Age_OB_B Age_OB_C
1: a 1 4 7 20 20 20
2: b 2 5 8 21 21 21
3: c 3 6 9 22 22 22
式
キャストは、 dcast
のformula引数を使用して制御されdcast
。これはROWS〜COLUMNSという形式です
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
dcast(DT, formula = Test ~ ID, value.var = "Result")
Test a b c
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
行と列の両方を展開するには、 +
dcast(DT, formula = ID + Age ~ Test, value.var = "Result")
ID Age OB_A OB_B OB_C
1: a 20 1 4 7
2: b 21 2 5 8
3: c 22 3 6 9
dcast(DT, formula = ID ~ Age + Test, value.var = "Result")
ID 20_OB_A 20_OB_B 20_OB_C 21_OB_A 21_OB_B 21_OB_C 22_OB_A 22_OB_B 22_OB_C
1: a 1 4 7 NA NA NA NA NA NA
2: b NA NA NA 2 5 8 NA NA NA
3: c NA NA NA NA NA NA 3 6 9
#order is important
dcast(DT, formula = ID ~ Test + Age, value.var = "Result")
ID OB_A_20 OB_A_21 OB_A_22 OB_B_20 OB_B_21 OB_B_22 OB_C_20 OB_C_21 OB_C_22
1: a 1 NA NA 4 NA NA 7 NA NA
2: b NA 2 NA NA 5 NA NA 8 NA
3: c NA NA 3 NA NA 6 NA NA 9
キャスティングは、データ内に観察が存在しない場合に、しばしばセルを作成することができます。デフォルトでは、これは上記のようにNA
で表されます。これをfill=
引数でオーバーライドすることができます。
dcast(DT, formula = ID ~ Test + Age, value.var = "Result", fill = 0)
ID OB_A_20 OB_A_21 OB_A_22 OB_B_20 OB_B_21 OB_B_22 OB_C_20 OB_C_21 OB_C_22
1: a 1 0 0 4 0 0 7 0 0
2: b 0 2 0 0 5 0 0 8 0
3: c 0 0 3 0 0 6 0 0 9
また、数式オブジェクトに2つの特殊変数を使用することもできます
-
.
他の変数を表していない -
...
は他のすべての変数を表します
dcast(DT, formula = Age ~ ., value.var = "Result")
Age .
1: 20 3
2: 21 3
3: 22 3
dcast(DT, formula = ID + Age ~ ..., value.var = "Result")
ID Age OB_A OB_B OB_C
1: a 20 1 4 7
2: b 21 2 5 8
3: c 22 3 6 9
value.varの集計
1つのステップで値をキャストして集計することもできます。この場合、我々は年齢と身分証明書の交点それぞれに3つの観察を有する。私たちが望む集約を設定するために、 fun.aggregate
引数を使用します:
#length
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = length)
ID 20 21 22
1: a 3 0 0
2: b 0 3 0
3: c 0 0 3
#sum
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = sum)
ID 20 21 22
1: a 12 0 0
2: b 0 15 0
3: c 0 0 18
#concatenate
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = function(x){paste(x,collapse = "_")})
ID 20 21 22
1: a 1_4_7
2: b 2_5_8
3: c 3_6_9
fun.aggregate
に複数の関数を使用するためのリストを渡すこともできます
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = list(sum,length))
ID Result_sum_20 Result_sum_21 Result_sum_22 Result_length_20 Result_length_21 Result_length_22
1: a 12 0 0 3 0 0
2: b 0 15 0 0 3 0
3: c 0 0 18 0 0 3
複数の関数と複数の値を渡すと、value.varsのベクトルを渡してすべての組み合わせを計算できます
dcast(DT, formula = ID ~ Age, value.var = c("Result","Test"), fun.aggregate = list(function(x){paste0(x,collapse = "_")},length))
ID Result_function_20 Result_function_21 Result_function_22 Test_function_20 Test_function_21 Test_function_22 Result_length_20 Result_length_21
1: a 1_4_7 OB_A_OB_B_OB_C 3 0
2: b 2_5_8 OB_A_OB_B_OB_C 0 3
3: c 3_6_9 OB_A_OB_B_OB_C 0 0
Result_length_22 Test_length_20 Test_length_21 Test_length_22
1: 0 3 0 0
2: 0 0 3 0
3: 3 0 0 3
各対は、値value1_formula1, value1_formula2, ... , valueN_formula(N-1), valueN_formulaN
の順番で計算されます。
あるいは、 'value.var'をリストとして渡すことによって、値と関数を1対1で評価することもできます。
dcast(DT, formula = ID ~ Age, value.var = list("Result","Test"), fun.aggregate = list(function(x){paste0(x,collapse = "_")},length))
ID Result_function_20 Result_function_21 Result_function_22 Test_length_20 Test_length_21 Test_length_22
1: a 1_4_7 3 0 0
2: b 2_5_8 0 3 0
3: c 3_6_9 0 0 3
結果の列の命名
デフォルトでは、列名の構成要素はアンダースコア_
区切られています。これは、 sep=
引数を使用して手動でオーバーライドできます。
dcast(DT, formula = Test ~ ID + Age, value.var = "Result")
Test a_20 b_21 c_22
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
dcast(DT, formula = Test ~ ID + Age, value.var = "Result", sep = ",")
Test a,20 b,21 c,22
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
これは、 value.var
たちが使用する任意のfun.aggregate
またはvalue.var
を分離します:
dcast(DT, formula = Test ~ ID + Age, value.var = "Result", fun.aggregate = c(sum,length), sep = ",")
Test Result,sum,a,20 Result,sum,b,21 Result,sum,c,22 Result,length,a,20 Result,length,b,21 Result,length,c,22
1: OB_A 1 2 3 1 1 1
2: OB_B 4 5 6 1 1 1
3: OB_C 7 8 9 1 1 1
rbindlistを使用して複数のテーブルをスタックする
Rの一般的な控え目は、次の行に沿っています。
あなたは、
DT1
、DT2
、...、DT11
ような名前を持つ関連テーブルの束を持つべきではありません。反復的に読んで、名前でオブジェクトに割り当てるのは面倒です。解決策は、データのテーブルのリストです!
そのようなリストは次のようになります
set.seed(1)
DT_list = lapply(setNames(1:3, paste0("D", 1:3)), function(i)
data.table(id = 1:2, v = sample(letters, 2)))
$D1
id v
1: 1 g
2: 2 j
$D2
id v
1: 1 o
2: 2 w
$D3
id v
1: 1 f
2: 2 w
もう1つの考え方は、これらのテーブルを積み重ねて1つのテーブルとして格納する必要があるということです。これはrbindlist
を使って簡単に行うことがrbindlist
ます:
DT = rbindlist(DT_list, id="src")
src id v
1: D1 1 g
2: D1 2 j
3: D2 1 o
4: D2 2 w
5: D3 1 f
6: D3 2 w
このフォーマットはdata.tableの構文ではより意味を成しています。ここでは、 "by group"操作は一般的で簡単です。
より深い見通しを得るためには、 グレゴールの答えが始まるのが良いかもしれません。もちろん、 ?rbindlist
もチェックしてください。別の例では、CSVのテーブルの束を読み込み、それらを積み重ねる方法を扱っています 。