使用dplyr创建排名变量?

61

假设我有以下数据:

df = data.frame(name=c("A", "B", "C", "D"), score = c(10, 10, 9, 8))

我想添加一个新的列来显示排名。这是我的做法:

df %>% mutate(ranking = rank(score, ties.method = 'first'))
#   name score ranking
# 1    A    10       3
# 2    B    10       4
# 3    C     9       2
# 4    D     8       1

然而,我的期望结果是:

#   name score ranking
# 1    A    10       1
# 2    B    10       1
# 3    C     9       2
# 4    D     8       3

显然,rank并不符合我的意图。我应该使用哪个函数?

3个回答

96

看起来你正在寻找 "dplyr" 包中的 dense_rank 函数,不过需要以与 rank 函数正常使用相反的顺序应用它。

尝试这个:

df %>% mutate(rank = dense_rank(desc(score)))
#   name score rank
# 1    A    10    1
# 2    B    10    1
# 3    C     9    2
# 4    D     8    3

8
可能应该使用 desc(score),即使 -score 也可以。Hadley 已经提醒过我几次了。 - hrbrmstr
2
C的排名可以是3,D的排名可以是4吗? - Ignacio
8
请使用 min_rank 替代使用 dense_rank - jalapic
啊,谢谢。只是想说,在group_by()之外的项目中,将arrange(desc())放在dense_rank()之前是行不通的。这是我在尝试过程中发现的。 - phili_b

8

当你需要将排名应用于所有变量(而不仅仅是一个)时,可以使用其他解决方案。

df = data.frame(name = c("A","B","C","D"),
                score=c(10,10,9,8), score2 = c(5,1,9,2))

select(df, -name) %>% mutate_all(funs(dense_rank(desc(.))))

1
dplyr has desc(), you don't need inv_d. (It's nice because it works for many data types, not just numeric.) You also don't need to do this in separate steps, you can go all at once: mutate_all(df, funs(dense_rank(desc(.)))) - Gregor Thomas
funs()在dplyr 0.8.0中已被弃用。有什么替代方案吗? - user101089

0
@user101089 --- 你可以尝试这种替代的方法:
df = data.frame(name = c("A","B","C","D"),
                score=c(10,10,9,8), score2 = c(5,1,9,2))

df %>% mutate(rank_score = dense_rank(desc(score)), 
                  rank_score2 = dense_rank(desc(score2)))

1
谢谢您抽出时间回答这个问题,但是我还不清楚这个答案与现有的答案有什么不同。请编辑您的帖子,以明确说明此答案的不同之处/改进之处。 - jared_mamrot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接