OK、このデータフレームを確認してください...
customer_name order_dates order_values
1 John 2010-11-01 15
2 Bob 2008-03-25 12
3 Alex 2009-11-15 5
4 John 2012-08-06 15
5 John 2015-05-07 20
タイブレーカーでの最後の注文日を使用して、最高注文値を名前で、最大注文日でランク付けする注文変数を追加するとします。したがって、最終的にはデータは次のようになります。
customer_name order_dates order_values ranked_order_values_by_max_value_date
1 John 2010-11-01 15 3
2 Bob 2008-03-25 12 1
3 Alex 2009-11-15 5 1
4 John 2012-08-06 15 2
5 John 2015-05-07 20 1
全員の単一の注文が1になり、その後のすべての注文が値に基づいてランク付けされ、タイブレーカーが最後の注文日が優先されます。この例では、Johnの2012年8月6日の注文は2010年11月1日の後に注文されたため、#2のランクになります。 2015年5月7日の注文は最大だったので1です。したがって、その注文が20年前に行われたとしても、それはジョンの最高の注文値だったので、それは#1ランクになるはずです。
Rでこれを行う方法を誰かが知っていますか?データフレーム内の指定された変数のグループ内でランク付けできる場所はどこですか?
ご協力いただきありがとうございます!
dplyr
を使用すると、これをかなりきれいに行うことができます
library(dplyr)
df %>%
group_by(customer_name) %>%
mutate(my_ranks = order(order(order_values, order_dates, decreasing=TRUE)))
Source: local data frame [5 x 4]
Groups: customer_name
customer_name order_dates order_values my_ranks
1 John 2010-11-01 15 3
2 Bob 2008-03-25 12 1
3 Alex 2009-11-15 5 1
4 John 2012-08-06 15 2
5 John 2015-05-07 20 1
(cdetermanによる)最高評価の回答は実際には正しくありません。順序関数は、現在の順序での値のランクではなく、1番目、2番目、3番目などのランク付けされた値の場所を提供します。
顧客名でグループ化して、最大のものから順にランク付けする簡単な例を見てみましょう。値を確認できるように手動ランキングを含めました
> df
customer_name order_values manual_rank
1 John 2 5
2 John 5 2
3 John 9 1
4 John 1 6
5 John 4 3
6 John 3 4
7 Lucy 4 4
8 Lucy 9 1
9 Lucy 6 3
10 Lucy 2 6
11 Lucy 8 2
12 Lucy 3 5
Cdetermanによって提案されたコードを実行すると、次の不正なランクが表示されます。
> df %>%
+ group_by(customer_name) %>%
+ mutate(my_ranks = order(order_values, decreasing=TRUE))
Source: local data frame [12 x 4]
Groups: customer_name [2]
customer_name order_values manual_rank my_ranks
<fctr> <dbl> <dbl> <int>
1 John 2 5 3
2 John 5 2 2
3 John 9 1 5
4 John 1 6 6
5 John 4 3 1
6 John 3 4 4
7 Lucy 4 4 2
8 Lucy 9 1 5
9 Lucy 6 3 3
10 Lucy 2 6 1
11 Lucy 8 2 6
12 Lucy 3 5 4
Orderは、データフレームを降順または昇順に並べ替えるために使用されます。実際に必要なのは、order関数を2回実行することです。2次関数を使用すると、必要な実際のランクが得られます。
> df %>%
+ group_by(customer_name) %>%
+ mutate(good_ranks = order(order(order_values, decreasing=TRUE)))
Source: local data frame [12 x 4]
Groups: customer_name [2]
customer_name order_values manual_rank good_ranks
<fctr> <dbl> <dbl> <int>
1 John 2 5 5
2 John 5 2 2
3 John 9 1 1
4 John 1 6 6
5 John 4 3 3
6 John 3 4 4
7 Lucy 4 4 4
8 Lucy 9 1 1
9 Lucy 6 3 3
10 Lucy 2 6 6
11 Lucy 8 2 2
12 Lucy 3 5 5
これは、ave
およびrank
を使用して実現できます。 ave
は適切なグループをrank
に渡します。 rank
からの結果は、要求された順序のために逆になります:
with(x, ave(as.numeric(order_dates), customer_name, FUN=function(x) rev(rank(x))))
## [1] 3 1 1 2 1
ベースR
では、少し扱いにくいとこれを行うことができます
transform(df,rank=ave(1:nrow(df),customer_name,
FUN=function(x) order(order_values[x],order_dates[x],decreasing=TRUE)))
customer_name order_dates order_values rank 1 John 2010-11-01 15 3 2 Bob 2008-03-25 12 1 3 Alex 2009-11-15 5 1 4ジョン2012-08-06 15 2 5ジョン2015-05-07 20 1
ここで、order
は、各グループのプライマリ値とタイブレーカー値の両方を提供します。
df %>% group_by(customer_name) %>% arrange(customer_name,desc(order_values)) %>% mutate(rank2=rank(order_values))