2012-04-01 12 views
14

すべて:特定の列のランキングを分割する方法は?

私はfollow.Iのようなデータフレームを持っているが、私はこのようなグローバルな順位を行うことができます知っている:

dt <- data.frame(
    ID = c('A1','A2','A4','A2','A1','A4','A3','A2','A1','A3'), 
    Value = c(4,3,1,3,4,6,6,1,8,4) 
); 
> dt 
    ID Value 
1 A1  4 
2 A2  3 
3 A4  1 
4 A2  3 
5 A1  4 
6 A4  6 
7 A3  6 
8 A2  1 
9 A1  8 
10 A3  4 
dt$Order <- rank(dt$Value,ties.method= "first") 
> dt 
    ID Value Order 
1 A1  4  5 
2 A2  3  3 
3 A4  1  1 
4 A2  3  4 
5 A1  4  6 
6 A4  6  8 
7 A3  6  9 
8 A2  1  2 
9 A1  8 10 
10 A3  4  7 

しかし、どのように、私は特定のIDの順位を設定する代わりにすることができますグローバルランクオーダー。これをどうすればいいのですか? T-SQLでは、これを次の構文で行うことができます。

RANK() OVER ([ <partition_by_clause> ] <order_by_clause>) 

何か考えてください。

答えて

4

私の方法だけど、おそらく良いです。決してランクを使わず、それについても知ってはいけません。ありがとう、役に立つかもしれない。

#Your Data 
dt <- data.frame(
    ID = c('A1','A2','A4','A2','A1','A4','A3','A2','A1','A3'), 
    Value = c(4,3,1,3,4,6,6,1,8,4) 
) 
dt$Order <- rank(dt$Value,ties.method= "first") 

#My approach 
dt$id <- 1:nrow(dt) #needed for ordering and putting things back together 
dt <- dt[order(dt$ID),] 
dt$Order.by.group <- unlist(with(dt, tapply(Value, ID, function(x) rank(x, 
    ties.method = "first")))) 
dt[order(dt$id), -4] 

収量:

ID Value Order Order.by.group 
1 A1  4  5    1 
2 A2  3  3    2 
3 A4  1  1    1 
4 A2  3  4    3 
5 A1  4  6    2 
6 A4  6  8    2 
7 A3  6  9    2 
8 A2  1  2    1 
9 A1  8 10    3 
10 A3  4  7    1 

EDIT:

あなたはデータの元の順序を維持する気にしないのであれば、これは少ないコードで動作します:

dt <- dt[order(dt$ID),] 
dt$Order.by.group <- unlist(with(dt, tapply(Value, ID, function(x) rank(x, 
    ties.method= "first")))) 

    ID Value Order.by.group 
1 A1  4    1 
5 A1  4    2 
9 A1  8    3 
2 A2  3    2 
4 A2  3    3 
8 A2  1    1 
7 A3  6    2 
10 A3  4    1 
3 A4  1    1 
6 A4  6    2 
+0

でこれを書き直すことができます。ありがとう、タイラー。 – RobinMin

13

多くのオプションがあります。

library(data.table) 
DT <- data.table(dt,key = "ID") 
DT[,transform(.SD,Order = rank(Value,ties.method = "first")),by = ID] 
     ID Value Order 
[1,] A1  4  1 
[2,] A1  4  2 
[3,] A1  8  3 
[4,] A2  3  2 
[5,] A2  3  3 
[6,] A2  1  1 
[7,] A4  1  1 
[8,] A4  6  2 
[9,] A3  6  2 
[10,] A3  4  1 

かで:data.tableパッケージを使用して

library(plyr) 
ddply(dt,.(ID),transform,Order = rank(Value,ties.method = "first")) 
    ID Value Order 
1 A1  4  1 
2 A1  4  2 
3 A1  8  3 
4 A2  3  2 
5 A2  3  3 
6 A2  1  1 
7 A3  6  2 
8 A3  4  1 
9 A4  1  1 
10 A4  6  2 

やパフォーマンスが問題に(つまり、非常に大きなデータ)の場合:plyrパッケージからddplyを使用して

そのすべての詳細は、ベースRソリューションを使用してsplitlapplydo.callrbind

do.call(rbind,lapply(split(dt,dt$ID),transform, 
       Order = rank(Value,ties.method = "first"))) 
+0

おかげで、あなたを、joran:

setDT(dt) dt[, Order := rank(Value, ties.method = "first"), by = "ID"] dt <- as.data.frame(dt)

所望の出力を与えます。 – RobinMin

+2

いつものように素敵な答え。 data.tableから最高のパフォーマンスを引き出すには、できれば '.SD'を避けるのが最善です。これは大容量のdata.tables(最初にパッケージを使用する可能性が最も高い場所です)では速くなければなりません: 'DT < - data.table(dt、key = c(" ID "、" Value "))); –

+0

私はあなたのdata.tableソリューションを実装しようとしていますが、ランクはすべての行に対して1にすぎません。私はあなたのコードを、変数名を変更するだけの言葉でほとんど単語を使用しています。私が作る可能性のあるエラーのアイデアはありますか?あなたがコードを見ることができないので、難しい質問ですが、私は繰り返し質問をしたくありませんでした。 – Kory

6

ここにいくつかのアプローチがあります:

aveこれは、同じIDを持つ値の各セットを取り、そのようなセットごとに個別にランクを適用します。パッケージは使用されません。

Rank <- function(x) rank(x, ties.method = "first") 
transform(dt, rank = ave(Value, ID, FUN = Rank)) 

与える:上記溶液は、元の行の順序を維持すること

ID Value rank 
1 A1  4 1 
2 A2  3 2 
3 A4  1 1 
4 A2  3 3 
5 A1  4 2 
6 A4  6 2 
7 A3  6 2 
8 A2  1 1 
9 A1  8 3 
10 A3  4 1 

注意。もしそれが望めばそれを後でソートすることができます。 RPostgreSQL

# see FAQ #12 on the sqldf github home page for info on sqldf and PostgreSQL 
# https://cran.r-project.org/web/packages/sqldf/README.html 

library(RPostgreSQL) 
library(sqldf) 

sqldf('select 
      *, 
      rank() over (partition by "ID" order by "Value") rank 
     from "dt" 
') 

sqldfは、このソリューションでは、行を並べ替えます。それはあなたのサンプル解決策がそれをしたのでOKですが(ただし、シーケンス番号の列をdtに追加せず、適切なorder by節を追加して結果を順序番号の順に並べ替える場合)。

+0

これはずいぶん前からのことでしたが、あなたの最初の方法について詳しく説明できますか?それは私のテーブルのすべてのエントリのために私に1のランクを与えているようです。私は2番目にグループ化したい列と、ここにあるように最初の引数にランクを付けたい列のみを持っています。 – Kory

+0

私はいくつかの説明と出力を追加しました。 –

0

data.tableパッケージを使用できます。

ID Value Order 
1 A1  4  1 
2 A2  3  2 
3 A4  1  1 
4 A2  3  3 
5 A1  4  2 
6 A4  6  2 
7 A3  6  2 
8 A2  1  1 
9 A1  8  3 
10 A3  4  1 
関連する問題