2017-06-20 13 views
3

私は非エクイにby =.SDの機能を組み合わせたい参加:指定した列(結合後)の各グループの最初のn行を選択する方法は?

data.table - select first n rows within group

.EACHI in data.table

例データ:

tmp_dt1<- data.table(grp = c(1,2), time = c(0.2, 0.6, 0.4, 0.8, 0.25, 0.65)) 
tmp_dt2 <- data.table(grp = c(1,2), time_from = c(0.1, 0.5)) 
tmp_dt2 <- tmp_dt2[, time_to := time_from + 0.2] 

> tmp_dt1 
    grp time 
1: 1 0.20 
2: 2 0.60 
3: 1 0.40 
4: 2 0.80 
5: 1 0.25 
6: 2 0.65 
> tmp_dt2 
    grp time_from time_to 
1: 1  0.1  0.3 
2: 2  0.5  0.7 

、私の所望の出力がありますtmp_dt2で定義された範囲内にある各グループの最初の時間。しかし、私はチェイニングせずに、いくつかのトラブルbyを使用して、各grpから最初のn行を抽出を抱えてい

> tmp_dt1[tmp_dt2, .(grp, time = x.time, time_from, time_to), on = .(grp, time >= time_from, time <= time_to)] 
    grp time time_from time_to 
1: 1 0.20  0.1  0.3 
2: 1 0.25  0.1  0.3 
3: 2 0.60  0.5  0.7 
4: 2 0.65  0.5  0.7 

:私は、すべてのそのような時間を得ることができます。例として、n = 1は、所望の出力があるとき:

tmp_dt1[tmp_dt2, .(grp, time = x.time, time_from, time_to), 
     on = .(grp, time >= time_from, time <= time_to)][, .SD[1], by = grp] 

     grp time time_from time_to 
1: 1 0.2  0.1  0.3 
2: 2 0.6  0.5  0.7 

しかし、何かのように:

> tmp_dt1[tmp_dt2, .(time = x.time[1], time_from[1], time_to[1]), on = .(grp, time >= time_from, time <= time_to), by = grp] 
Error in `[.data.table`(tmp_dt1, tmp_dt2, .(time = x.time[1], time_from[1], : 
    object 'time_from' not found 

は動作しません。

使用して、.SDは近づくが、選択された列の面で私の結果の混乱終わりを与える:

tmp_dt1[tmp_dt2, .SD[1], on = .(grp, time >= time_from, time <= time_to), by = grp] 
    grp time 
1: 1 0.2 
2: 2 0.6 

私はチェーンでそれを行うにはしたくない理由があるためmemory issuesです。私はこの特定の問題をdata.tableパッケージで解決することにのみ関心があることに注意してください。

答えて

2

試しました

tmp_dt1[tmp_dt2, on=.(grp, time>=time_from, time<=time_to), 
    x.time, by=.EACHI] # or head(x.time, 2L) to get first 2 rows etc. 

hereのように、重複する列の名前を内部で処理するまで、自分で変更する必要があります。

+1

この回答と、 'x.'表記を説明する非常に役に立つリンクに感謝します – Alex

2

1つのオプションは、あなたがそれが一時的に格納するために奇妙に見えるにもかかわらず、元の連鎖アプローチよりも多くのメモリ効率的かもしれメモリ使用量に別のソリューションを最小限にしたい場合はmult= first

tmp_dt1[tmp_dt2, .(grp, time = x.time, time_from, time_to), mult = "first", 
      on = .(grp, time >= time_from, time <= time_to)] 
# grp time time_from time_to 
#1: 1 0.2  0.1  0.3 
#2: 2 0.6  0.5  0.7 
+0

「最初のn」はどうですか? – Alex

+0

@Alex 'mult'には' first'、 'last'、' all'のオプションしかありません。 [ここ](https://cran.r-project.org/web/packages/data.table/vignettes/datatable-keys-fast-subset.html)をチェックすることができます。一般的なケースについては、すでに回答があります。 – akrun

+0

ありがとう、最初のビッグデータテーブルの作成を避けてサブセット化する方法はありませんか? – Alex

1

を指定することです結果は変数になります(ただし、2つの列と1グループあたり最初のn行だけが含まれます)。チェーン化を使用します(ただし、元のデータのより小さいサブセット)。

n = 1  # parameter: first "n" rows per group 
selected.rows <- tmp_dt1[tmp_dt2, .(rownum = .I[1:n]), on = .(grp, time >= time_from, time <= time_to), by = grp] 
tmp_dt1[selected.rows$rownum][tmp_dt2, .(grp, time = x.time, time_from, time_to), on = .(grp, time >= time_from, time <= time_to)] 

2番目のケースの縮小サブセットであっても、結合ロジックを複製して2回参加する必要があります...

一時的な結果セットには、 (data.table.I記号を使用して)、元のデータテーブル内の一致」:

selected.rows 

    grp rownum 
1: 1  1 
2: 2  2 

私は意志より多くの時間を持っている場合、(...本当のビッグデータテーブルを使用して連鎖すると、このソリューションを比較するために素晴らしいことですプロフィールthis)

関連する問題