使用R中的两列对数据框进行排名

ranking dataframe using two columns in R

我是 R 的新手,我很难尝试使用 R 中的两列对数据框进行排名。 数据是这样的形式。

A B
1 1
2 1
2 1
4 4
5 3

我希望结果的形式为

A B Rank
1 1 1
2 1 2
2 1 2
4 4 5
5 3 4

以B排在第一位,如果B中有相等的值,则以A排序。 我认为我的问题非常类似于 How to rank rows by two columns at once in R? 我尝试了这个问题的答案,但这对我不起作用。

我能想到的最简单的方法是使用 dplyr 中一个名为 arrange 的函数首先按 B 排序,然后按 A 排序,创建排名作为列的顺序,然后用原来的顺序重新排列安排来模拟你的输出。

要重复相同条目的排名,我们可以添加 ifelse 语句查看前一行并在该行具有相同的 A 和 B 值时保持排名。

这是这样的:

df <- data.frame(A = c(1,2,2,4,5),
                 B = c(1,1,1,4,3))

library(tidyverse)
df %>%
    arrange(B,A) %>%
    mutate(Rank = 1:n(),
           Rank = ifelse(A == lag(A, default = 0) & B == lag(B, default = 0), 
                         lag(Rank), Rank)) %>%
    arrange(A,B)
#>   A B Rank
#> 1 1 1    1
#> 2 2 1    2
#> 3 2 1    2
#> 4 4 4    5
#> 5 5 3    4

reprex package (v2.0.1)

创建于 2022-01-07

你可以做的是对 B 和 A 进行排序,给它一个组 ID,然后根据这个组 ID 进行排名

数据

dt <- structure(list(A = c(1L, 2L, 2L, 4L, 5L), B = c(1L, 1L, 1L, 4L, 
3L)), row.names = c(NA, -5L), class = c("data.frame"
))

data.table

library(data.table)
setDT(dt)

setorder(dt, B, A)
dt[, Rank := .GRP, by = .(A, B)][, Rank := rank(Rank, ties.method = "min")]

dt
   A B Rank
1: 1 1    1
2: 2 1    2
3: 2 1    2
4: 5 3    4
5: 4 4    5

dyplr

library(dplyr)

dt %>% 
  arrange(B, A) %>%
  group_by(B, A) %>%
  mutate(Rank = cur_group_id()) %>%
  ungroup() %>%
  mutate(Rank = rank(Rank, ties.method = "min"))

# A tibble: 5 x 3
      A     B  Rank
  <int> <int> <int>
1     1     1     1
2     2     1     2
3     2     1     2
4     5     3     4
5     4     4     5

您可以使用 data.table::frankdplyr::min_rank:

data.table::frank

dt$Rank <- frank(dt, B, A, ties.method = "min")
dt
  A B Rank
1 1 1    1
2 2 1    2
3 2 1    2
4 4 4    5
5 5 3    4

dplyr::min_rank

mutate(dt, Rank = min_rank(paste(B,A)))
  A B Rank
1 1 1    1
2 2 1    2
3 2 1    2
4 4 4    5
5 5 3    4

数据

dt <- data.frame(A = c(1,2,2,4,5), B = c(1,1,1,4,3))

也许这个基础 R 选项可以提供帮助

transform(
  df,
  Rank = rank(A[order(B, A)], ties.method = "min")
)

这给出了

  A B Rank
1 1 1    1
2 2 1    2
3 2 1    2
4 4 4    5
5 5 3    4