如何在R中一次按两列对行进行排名?

Posted

技术标签:

【中文标题】如何在R中一次按两列对行进行排名?【英文标题】:How to rank rows by two columns at once in R? 【发布时间】:2015-01-31 08:13:09 【问题描述】:

这是根据列 v2 进行排名的代码:

x <- data.frame(v1 = c(2,1,1,2), v2 = c(1,1,3,2))
x$rank1 <- rank(x$v2, ties.method='first')

但我真的想根据 v2 和/然后 v1 进行排名,因为在 v2 中有联系。不使用 RPostgreSQL 怎么办?

【问题讨论】:

【参考方案1】:

试试这个:

x <- data.frame(v1 = c(2,1,1,2), v2 = c(1,1,3,2))

# The order function returns the index (address) of the desired order 
# of the examined object rows
orderlist<- order(x$v2, x$v1)

# So to get the position of each row in the index, you can do a grep

x$rank<-sapply(1:nrow(x), function(x) grep(paste0("^",x,"$"), orderlist ) )
x

# For a little bit more general case
# With one tie

x <- data.frame(v1 = c(2,1,1,2,2), v2 = c(1,1,3,2,2))

x$rankv2<-rank(x$v2)
x$rankv1<-rank(x$v1)

orderlist<- order(x$rankv2, x$rankv1)  
orderlist

#This rank would not be appropriate
x$rank<-sapply(1:nrow(x), function(x) grep(paste0("^",x,"$"), orderlist ) )

#there are ties
grep(T,duplicated(x$rankv2,x$rankv1) )

# Example for only one tie

makeTieRank<-mean(x[which(x[,"rankv2"] %in% x[grep(T,duplicated(x$rankv2,x$rankv1) ),][,c("rankv2")] &
        x[,"rankv1"] %in% x[grep(T,duplicated(x$rankv2,x$rankv1) ),][,c("rankv1")]),]$rank)

x[which(x[,"rankv2"] %in% x[grep(T,duplicated(x$rankv2,x$rankv1) ),][,c("rankv2")] &
          x[,"rankv1"] %in% x[grep(T,duplicated(x$rankv2,x$rankv1) ),][,c("rankv1")]),]$rank<-makeTieRank
x

【讨论】:

【参考方案2】:

这里我们创建一个数字序列,然后重新排序它,就好像它是在有序数据附近创建的一样:

x$rank <- seq.int(nrow(x))[match(rownames(x),rownames(x[order(x$v2,x$v1),]))]

或者:

x$rank <- (1:nrow(x))[order(order(x$v2,x$v1))]

甚至:

x$rank <- rank(order(order(x$v2,x$v1)))

【讨论】:

【参考方案3】:

order 有效,但要处理数据帧,还请查看 plyrdplyr 包。

> arranged_x <- arrange(x, v2, v1)

【讨论】:

由于您使用的是dplyr,您还可以添加对mutate的调用以添加排名编号,如arranged_x &lt;- arrange(x, v2, v1) %&gt;% mutate(rank = 1:n())【参考方案4】:

怎么样:

within(x, rank2 <- rank(order(v2, v1), ties.method='first'))

#   v1 v2 rank1 rank2
# 1  2  1     1     2
# 2  1  1     2     1
# 3  1  3     4     4
# 4  2  2     3     3

【讨论】:

首先,ties.method 不需要,order 不会有联系。其次,这个数据失败了:x &lt;- data.frame(v1 = c(2,3,1,2,1), v2 = c(1,1,3,2,1)),所以这是错误的。 order(order(x)) = rank(x) 禁止绑定,但一般rank(order(x)) 不会。如果您有疑问,请尝试一些示例。我已编辑您的答案以使用正确的版本。 ***.com/a/61647053/3371472 如何处理领带?即,如果两行具有相同的 v1 和 v2。

以上是关于如何在R中一次按两列对行进行排名?的主要内容,如果未能解决你的问题,请参考以下文章

按两列对数据框进行排序(有条件)[重复]

按两列对 MySQL 表排序

如何在R中按两列分组

熊猫按多列排名

RDLC 在多列上排序

使用 Doctrine 按多列排序