3

次の 2 つのデータ テーブルがあるとします。

dt1 <- data.table(id=1:3,val1=c("a","a","b"),key="id")
#    id val1
# 1:  1    a
# 2:  2    a
# 3:  3    b


dt2 <- data.table(id=c(1:3,1:2),val2=10:14,key="id")
#    id val2
# 1:  1   10
# 2:  1   13
# 3:  2   11
# 4:  2   14
# 5:  3   12

dt1それが their によって識別される人々 のリストでidありdt2、これらの同じ人々に関する観察のリストであり、特派員 であるとしましょうid

val2ここで、の各グループのの平均を計算したいと思いval1ます。私は次の方法でそれを行うことができることを理解しました:

dt1[dt2][,mean(val2),by=val1]
#    val1 V1
# 1:    a 12
# 2:    b 12

しかし、FAQ (セクション 1.14) も読んだことがありますが、これは効率的ではありません (少なくとも非常に大きなデータ テーブルの場合)。

それで、それを行うためのより良い、より効率的な方法はありますか?

編集:別の関連する質問:次の2行で同じ結果が得られることがわかりました:

dt1[dt2][,mean(val2),by=val1]
dt2[dt1][,mean(val2),by=val1]

それらは同等ですか、それとも2つに違いはありますか?

4

1 に答える 1

5

あなたの場合、それをしても大丈夫です。ドキュメントで説明されている iiuc は、たとえば、このシナリオ (すべての列でグループ化/集計していない場合) です。

dt1 <- data.table(id=1:3,val1=c("a","a","b"),key="id")
dt2 <- data.table(id=c(1:3,1:2),val2=10:14,key="id")

dt2[, val3 := rep(5:7, c(2,1,2))]
#    id val2 val3
# 1:  1   10    5
# 2:  1   13    5
# 3:  2   11    6
# 4:  2   14    7
# 5:  3   12    7

val2ここで、ごとに alone の平均を求めたい場合、val1すべての列を結合しても意味がありません。この場合、次のことができます。

dt1[dt2, list(val1, val2)][, mean(val2), by=val1]
#    val1 V1
# 1:    a 12
# 2:    b 12

代わりに:

# gives same result but performs join on all columns
dt1[dt2][, mean(val2), by=val1]

dt1[dt2]2 番目の質問については、 と の違いを理解することが不可欠だと思いますdt2[dt1]。このため、データは最良の例ではありません。仮定、

dt1 <- data.table(id=c(1,4,5), val1=c("a","a","b"))
dt2 <- data.table(id=c(1,2,3,6,7,8), val2=c(6,5,3,4,2,1))

setkey(dt1, "id")
setkey(dt2, "id")

dt1[dt2]for every idinを取り、dt2他のすべての列の対応する値をフェッチしてdt1、結合を実行します。

dt1[dt2]
#    id val1 val2
# 1:  1    a    6
# 2:  2   NA    5
# 3:  3   NA    3
# 4:  6   NA    4
# 5:  7   NA    2
# 6:  8   NA    1

dt2[dt1] 結合を実行するために、の他の列からの対応する値のfor everyidを取ります。dt1dt2

dt2[dt1]
#    id val2 val1
# 1:  1    6    a
# 2:  4   NA    a
# 3:  5   NA    b

の値にはの idのみdt1[dt2]が含まれていることに注意してください。同様に にあるものだけが含まれます。あなたの場合、s はまったく同じであるため(発生回数を無視して)、両方の結合で同じ結合が得られます(列の順序を除く)、iiuc.dt2dt2[dt1]dt1id


この部分を完成させるために、「完全な」結合が必要な場合は with を使用mergeall=TRUEます。merge.data.tableメソッドが実装されます。

merge(dt1, dt2, all = TRUE)

merge(dt1, dt2, all.x = TRUE) 
# is equivalent to
dt2[dt1]

merge(dt1, dt2, all.y = TRUE)
# is equivalent to
dt1[dt2]
于 2013-04-05T09:43:31.620 に答える