19

時間のキー値が近いが、まったく同じではないRでデータテーブルを結合する巧妙な方法はありますか? たとえば、さまざまな期間で得られた結果のデータ テーブルがあるとします。

DT1 = data.table(x=rep(c("a","b","c"),each=3), time=c(10,30,60), v=1:9)

ここでは、さまざまな時間 (時間) に取得されたさまざまなカテゴリ (x) のいくつかの値 (v) があります。ここで、さまざまなカテゴリの時間値を提供する別のソースからのデータがあるとします。

DT2=data.table(x=rep(c("a","b","c"),each=1),time=c(10,10,60))

DT2 カテゴリの値 v を予測するために、DT2 の時間をできるだけ DT1 に一致させたいと思うかもしれません。私は次のようなことをしたいと思います

setkeyv(DT2,c("x","time"))
merge(DT1,DT2,by=c("time","v")

どちらが返されますか:

   time x v
1:   10 a 1
2:   10 b 4
3:   60 c 9

しかし、私の時間が同じ精度を持っていなかったらどうなるでしょうか? 例えば:

DT2=data.table(x=rep(c("a","b","c"),each=1),time=c(17,54,3))

同様のマージを実行して、DT1 の時間に近い DT2 の時間を選択する方法はありますか? つまり、17 は 30 に近く、54 は 60 に近く、3 は 10 に近いということですか?

この単純な例が明確でない場合は、私が抱えているより大きな問題について簡単に説明します。列を持つデータ テーブルがあります: カテゴリ、時間、出力 1、出力 2... 関連する時間を持つ何百ものカテゴリがあります。特定の時間にすべてのカテゴリの出力 1 をプルしたい場合があります。時間は明らかなロジックなしでサンプリングされたため、時間は最も近い偶数秒に丸められることがあります。それ以外の場合、時間は最も近い分または 10 分に丸められます。

もっと一般的な形式で時間を書き直すスクリプトを書くこともできますが、見たことのない洗練された data.table ソリューションがあるかどうかに興味があります。ローリングマージを調査しましたが、成功しませんでした。

4

2 に答える 2

23

別のオプションがありますroll='nearest'(CRAN の v1.8.8 の新機能)。

> setkey(DT1,x,time)
> DT1
   x time v
1: a   10 1
2: a   30 2
3: a   60 3
4: b   10 4
5: b   30 5
6: b   60 6
7: c   10 7
8: c   30 8
9: c   60 9
> DT2
   x time
1: a   17
2: b   54
3: c    3
> DT1[DT2,roll="nearest"]
   x time v
1: a   17 1
2: b   54 6
3: c    3 7

17 は 30 よりも 10 に近いように見えるため、最初の行の結果になることに注意してください。

次の観測にロールする必要がある場合 (次の観測は逆方向に繰り越されます):

> DT1[DT2,roll=-Inf]
   x time v
1: a   17 2
2: b   54 6
3: c    3 7
于 2013-03-30T23:05:51.363 に答える
4

findIntervalこれを達成するために使用できます:

setkey(DT2, time)
DT1[, id := findInterval(DT1$time, DT2$time)]
DT2[, id := 1:3]

setkey(DT1, "x", "id")
setkey(DT2, "x", "id")
print(DT1[DT2][, id := NULL])
#    x time v time.1
# 1: a   30 2     17
# 2: b   60 6     54
# 3: c   10 7      3

findIntervalアイデア: の 2 番目の引数は値の昇順を必要とするため、最初に data.table を時間で並べ替えます。ここで、 を使用findIntervalして、 のどの間隔で3, 17, 54値がDT1$time低下し、それを に格納するかを調べますid。この特定のケースでは、たまたま 1 から 3 の範囲になります。したがって、これらの値を のid列として設定しますDT2。間隔を見つけて を取得したらid、それは簡単です。xandを設定する代わりに、 andをキーとしてtime設定し、マージを行います。xid

注:DT1$time値が 0 であると仮定すると、その間隔は 0 になります。したがって、4 つの一意の値 (0:3) が得られます。その場合、DT2 も time = 0 の値にした方がよい場合があります。ここで注意したいのは、この点だけです。お任せします。

于 2013-03-30T00:19:26.213 に答える