R语言如何获取列表或向量中数值元素的相对排名
你需要实现的是稠密排名逻辑:取值相同的元素返回相同排名,排名按取值大小连续递增,不受原数值间隔、并列元素数量影响,不会出现排名跳号。
优先方案:dplyr实现
dplyr内置了现成的稠密排名函数dense_rank(),写法最简洁,直接调用即可得到你要的结果:
library(dplyr) # 构造示例数据 Example1 <- data.frame(Element = c(1,1,1,2,1,3,1)) # 计算稠密排名 Example1$dense_rank_res <- dense_rank(Example1$Element)
运行后返回的结果如下,完全匹配示例图里的黄色列输出:
Element dense_rank_res 1 1 1 2 1 1 3 1 1 4 2 2 5 1 1 6 3 3 7 1 1
如果需要按分组计算组内排名,直接搭配group_by()使用即可:
# 示例:按group_col分组,计算每组内Element的稠密排名 df <- df %>% group_by(group_col) %>% mutate(dense_rank_res = dense_rank(Element))
如果需要降序排名,直接对列取反传入即可:dense_rank(desc(Element))。
基础R实现(无需加载第三方包)
你之前调用内置rank()得到的结果不符合预期,是因为rank()默认的并列处理规则是ties.method = "average",会给并列值返回平均排位,所以才会出现3、6、7这类跳号的结果。
基础R不需要依赖任何扩展包,一行代码就能实现稠密排名:
Example1 <- data.frame(Element = c(1,1,1,2,1,3,1)) Example1$dense_rank_res <- match(Example1$Element, sort(unique(Example1$Element)))
返回结果和dplyr方案完全一致。如果需要降序排名,给排序参数加decreasing = TRUE即可:
# 降序稠密排名 match(Example1$Element, sort(unique(Example1$Element), decreasing = TRUE))
附R中常用排名规则的对应实现,避免混淆:
- 稠密排名(同值同名次,无跳号):
dplyr::dense_rank()/ 基础Rmatch(x, sort(unique(x)))- 跳跃排名(同值同名次,并列占坑有跳号,如两个并列第1后下一个为第3):
dplyr::min_rank()/ 基础Rrank(x, ties.method = "min")- 顺序排名(同值也按出现顺序分配不同名次,无并列):
dplyr::row_number()/ 基础Rrank(x, ties.method = "first")
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

