在数据框中添加排名列

15

这似乎是一个非常常见的任务,但我在Google或SO中找不到解决方案。我想根据“order.scores”应用于“dat”的顺序向“dat1”添加名为“rank”的列。我尝试使用row.names(),但行名称是基于“dat”,而不是“dat1”。我还尝试了“dat$rank < -rank(dat1)”,但这会产生错误消息。

fname<-c("Joe", "Bob", "Bill", "Tom", "Sue","Sam","Jane","Ruby")
score<-c(500, 490, 500, 750, 550, 500, 210, 320)
dat<-data.frame(fname,score)
order.scores<-order(dat$score,dat$fname)
dat1<-dat[order.scores,]

5
你是否在寻找 dat$rank <- rank(dat$score) 的代码? - josliber
不完全是这样。我的主要排序是dat$score,但我的次要(决胜者)排序是fname。因此,比尔排在乔的前面,而乔又排在山姆的前面,即使他们的分数都相同。这是您查看'dat1'时看到的排序顺序。如果我尝试'dat1 $ rank <- rank(dat1 $ score)',比尔,乔和萨姆都会得到排名5。 - user3614783
7个回答

15

您可以按照以下方式从排序计算排名:

dat$rank <- NA
dat$rank[order.scores] <- 1:nrow(dat)
dat
#   fname score rank
# 1   Joe   500    5
# 2   Bob   490    3
# 3  Bill   500    4
# 4   Tom   750    8
# 5   Sue   550    7
# 6   Sam   500    6
# 7  Jane   210    1
# 8  Ruby   320    2

不错。我也没有意识到在分配值之前必须创建一个空的等级列。非常感谢。 - user3614783
使用 dat$rank[order(-dat$scores)] <- 1:nrow(dat) 解决了问题。如果这是个打字错误,请为下一个做修改。 :) - Augustin Riedinger
2
@AugustinRiedinger 我使用了原始帖子中定义的 order.scores,因此您需要从那里运行代码才能使我的代码正常工作。 - josliber
1
好的,我的错误。我不知道用点符号创建列。 - Augustin Riedinger

9

尝试:

## dat, dat1, and order.scores as defined
dat <- data.frame(fname=c("Joe", "Bob", "Bill", "Tom", "Sue","Sam","Jane","Ruby"),
                  score=c(500, 490, 500, 750, 550, 500, 210, 320))
order.scores <- order(dat$score)
dat1 <- dat[order.scores,]
dat1$rank <- rank(dat1$score)
dat1
##    fname score rank
##  7  Jane   210    1
##  8  Ruby   320    2
##  2   Bob   490    3
##  3  Bill   500    5
##  1   Joe   500    5
##  6   Sam   500    5
##  5   Sue   550    7
##  4   Tom   750    8

这显示了基于 $score 的等级关系。如果您不希望在 $rank 中产生并列的情况,则可以直接使用 dat1$rank <- 1:nrow(dat1),因为它们已经按顺序排列。


5
你可以使用dplyr中的arrange和mutate功能:
library(dplyr)
dat <- arrange(dat, desc(score)) %>%
          mutate(rank = 1:nrow(dat))
dat

2

您可以使用:

dat$Rank <-  rank(dat$score)
dat$Rank

1
感谢您提供这段代码片段,它可能会在短期内提供一些有限的帮助。一个适当的解释将极大地提高其长期价值,通过展示为什么这是一个好的问题解决方案,使其对未来有类似问题的读者更有用。请编辑您的答案,添加一些解释,包括您所做的假设。 - Shawn C.
这并没有解决最初的要求,即主排序应该是“分数”,次要排序应该是“名字”。 “排名”字段应对应于2级排序产生的位置。 不应有任何平局。 - user3614783

1
你可以这样做:
 dat$rank <- order(order.scores)
  dat$rank
 #[1] 5 3 4 8 7 6 1 2

0
给定数据框 dat:
  fname score
  Joe   500
  Bob   490
  Bill  500
  Tom   750
  Sue   550
  Sam   500
  Jane  210
  Ruby  320

我们也可以如下使用 dplyr,它将最小值 210 分配给 smallest 值的 lowest 排名。
ranks = dat %>%
  mutate(ranks = order(order(score)))

输出结果如下:

fname score ranks
  Joe   500     4
  Bob   490     3
 Bill   500     5
  Tom   750     8
  Sue   550     7
  Sam   500     6
 Jane   210     1
 Ruby   320     2

如果需要相反的情况,即在这种情况下应将等级 1 分配给最高值,即 750,则代码将稍作更改,如下所示:

ranks = dat %>%
  mutate(ranks = order(order(score, decreasing = T)))

在这种情况下,输出将如下所示:

fname score ranks
Joe   500     3
Bob   490     6
Bill  500     4
Tom   750     1
Sue   550     2
Sam   500     5
Jane  210     8
Ruby  320     7

-1
通常,Rank可以应用于查找列数据中数字值的最小到最高值。
例如:薪水是一列,它有4位数到5位数的薪水,然后通过应用rank函数来确定排名!
简单理解-薪水之间的排名。
df['Salary'].rank(ascending = False).astype(int)

问题是关于R语言的,但你用Python进行了回答。 - camille

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