如何在 R 中的组内排名?
How to rank within groups in R?
好的,检查这个数据框...
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 日之后下达的。 5/7/2015 订单是 1,因为它是最大的。所以,即使那个订单是20年前下的,它也应该是#1 Rank,因为这是约翰的最高订单价值。
有谁知道我如何在 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
这可以通过 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 John 2012-08-06 15 2
5 John 2015-05-07 20 1
其中 order
提供了每个组的主要值和决胜值。
评分最高的答案(来自 cdeterman)实际上是不正确的。 order 函数提供第 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 用于将数据帧重新排序为降序或升序。我们真正想要的是 运行 两次排序函数,二阶函数给我们我们想要的实际排名。
> 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
df %>%
group_by(customer_name) %>%
arrange(customer_name,desc(order_values)) %>%
mutate(rank2=rank(order_values))
类似于@t-himmel的回答,你可以用data.table获得排名。
dt[ , rnk := order(order(order_values, decreasing = TRUE)), customer_name ]
好的,检查这个数据框...
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 日之后下达的。 5/7/2015 订单是 1,因为它是最大的。所以,即使那个订单是20年前下的,它也应该是#1 Rank,因为这是约翰的最高订单价值。
有谁知道我如何在 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
这可以通过 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 John 2012-08-06 15 2 5 John 2015-05-07 20 1
其中 order
提供了每个组的主要值和决胜值。
评分最高的答案(来自 cdeterman)实际上是不正确的。 order 函数提供第 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 用于将数据帧重新排序为降序或升序。我们真正想要的是 运行 两次排序函数,二阶函数给我们我们想要的实际排名。
> 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
df %>%
group_by(customer_name) %>%
arrange(customer_name,desc(order_values)) %>%
mutate(rank2=rank(order_values))
类似于@t-himmel的回答,你可以用data.table获得排名。
dt[ , rnk := order(order(order_values, decreasing = TRUE)), customer_name ]