3

次のデータフレームGがある場合:

z    type   x   
1     a     4
2     a     5 
3     a     6
4     b     1
5     b     0.9
6     c     4

私は取得しようとしています:

z    type   x   y
3     a     6   3
2     a     5   2
1     a     4   1
4     b     1   2
5     b     0.9 1
6     c     4   1

typeつまり、 vector に基づいてfactor のレベル内でデータ フレーム全体を並べ替えたいとしますx。各レベルの長さを取得a = 3 b=2 c=1し、新しい vector で減少するように番号を付けyます。

私の出発点は現在sort()

tapply(y, x, sort)

最初に sapply を使用して最初にすべてを分割するのが最善でしょうか?

4

2 に答える 2

7

この猫の皮を剥ぐ方法はたくさんあります。ベース R とベクトル化されたコードを 2 つのステップで使用する 1 つのソリューションを次に示します ( は使用しませんapply)。

  1. orderと を使用してデータを並べ替えるxtfrm
  2. と を使用rlesequenceてシーケンスを生成します。

データを複製します。

dat <- read.table(text="
z    type   x   
1     a     4
2     a     5 
3     a     6
4     b     1
5     b     0.9
6     c     4
", header=TRUE, stringsAsFactors=FALSE)

2 行のコード:

r <- dat[order(dat$type, -xtfrm(dat$x)), ]
r$y <- sequence(rle(r$type)$lengths)

結果:

r
  z type   x y
3 3    a 6.0 1
2 2    a 5.0 2
1 1    a 4.0 3
4 4    b 1.0 1
5 5    b 0.9 2
6 6    c 4.0 1

への呼び出しorderは少し複雑です。1 つの列を昇順で並べ替え、2 つ目の列を降順で並べ替えているため、ヘルパー関数を使用しますxtfrm。詳細?xtfrmについては を参照してください。また、 にも記載されてい?orderます。

于 2012-04-25T17:31:20.777 に答える
4

私はアンドリーの方が好きです:

dat <- read.table(text="z    type   x   
1     a     4
2     a     5 
3     a     6
4     b     1
5     b     0.9
6     c     4", header=T)

3 行のコード:

dat <- dat[order(dat$type), ]
x <- by(dat, dat$type, nrow)
dat$y <- unlist(sapply(x, function(z) z:1))

アンドリーが言及したコメントに適応するように、応答を編集しました。これは機能しますが、Andrie のルートではなくこのルートに行った場合は、おかしなことになります。

于 2012-04-25T17:35:30.657 に答える