23

特定の列に同じ値を持つ行の各グループから 1 行を除くすべての行を削除して、データ フレームを折りたたもうとしています。つまり、各グループの最初の行です。

たとえば、これを変換したい

> d = data.frame(x=c(1,1,2,4),y=c(10,11,12,13),z=c(20,19,18,17))
> d
  x  y  z
1 1 10 20
2 1 11 19
3 2 12 18
4 4 13 17

これに:

    x  y  z
1   1 11 19
2   2 12 18
3   4 13 17

現在これを行うために集計を使用していますが、データが増えるとパフォーマンスが許容できなくなります。

> d.ordered = d[order(-d$y),]
> aggregate(d.ordered,by=list(key=d.ordered$x),FUN=function(x){x[1]})

ここと同じ関数引数で分割/非分割を試みましたが、非分割は行番号の重複について不平を言います。

可能性はありますか?rleの長さベクトルを各実行を開始する行のインデックスに変換するRイディオムはありますか?それを使用して、データフレームからそれらの行を取り出すことができますか?

4

4 に答える 4

31

多分duplicated()助けることができます:

R> d[ !duplicated(d$x), ]
  x  y  z
1 1 10 20
3 2 12 18
4 4 13 17
R> 

Shucks を編集します。気にしないでください。これは、繰り返しの各ブロックの最初を選択します。最後が必要でした。したがって、 plyrを使用した別の試みは次のとおりです。

R> ddply(d, "x", function(z) tail(z,1))
  x  y  z
1 1 11 19
2 2 12 18
3 4 13 17
R> 

ここでplyrは、一意のサブセットを見つけ、それらをループし、提供された関数を適用するという大変な作業を行いzますtail(z, 1)

于 2010-04-13T02:19:35.750 に答える
14

Dirkが提供したものに少し追加するだけです...最後の行を選択するために使用できる引数がありますduplicatedfromLast

d[ !duplicated(d$x,fromLast=TRUE), ]
于 2010-04-13T06:00:54.127 に答える
14

これはdata.table、大規模なデータセットに対して時間とメモリを効率的に使用できるソリューションです。

library(data.table)
DT <- as.data.table(d)           # convert to data.table
setkey(DT, x)                    # set key to allow binary search using `J()`
DT[J(unique(x)), mult ='last']   # subset out the last row for each x
DT[J(unique(x)), mult ='first']  # if you wanted the first row for each x
于 2012-09-19T06:54:59.437 に答える