web-dev-qa-db-ja.com

Rのグループ内でランク付けする方法は?

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でこれを行う方法を誰かが知っていますか?データフレーム内の指定された変数のグループ内でランク付けできる場所はどこですか?

ご協力いただきありがとうございます!

19
Saul Feliz

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
12
cdeterman

(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
21
T. Himmel

これは、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
2

ベース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は、各グループのプライマリ値とタイブレーカー値の両方を提供します。

2
A. Webb

df %>% group_by(customer_name) %>% arrange(customer_name,desc(order_values)) %>% mutate(rank2=rank(order_values))

1
Spandan Pan