r - 基于多个列计算排名,具有优先规则

标签 r dplyr data.table ranking rank

<分区>

我有这样一个数据框

df <- expand.grid(0:1, 0:1, 0:1, 0:1)
df
   Var1 Var2 Var3 Var4
1     0    0    0    0
2     1    0    0    0
3     0    1    0    0
4     1    1    0    0
5     0    0    1    0
6     1    0    1    0
7     0    1    1    0
8     1    1    1    0
9     0    0    0    1
10    1    0    0    1
11    0    1    0    1
12    1    1    0    1
13    0    0    1    1
14    1    0    1    1
15    0    1    1    1
16    1    1    1    1

我正在尝试根据 Var1、Var2、Var3、Var4 上的某些条件创建一个 Rank

排名优先顺序由变量决定

  • Var1 列具有最高优先级,如果它的值为 1,则它的排名更高
  • Var2Var3Var4
  • 有更高的偏好
  • Var1Var2Var3Var4
  • 有更高的优先级
  • Var3Var4 没有偏好,仅用作排名的计数

如果任何行的 Var3Var4 计数相同,则它们以相同的数字排名。

我的期望输出

   Var1 Var2 Var3 Var4 rank
1     0    0    0    0   12
2     1    0    0    0    6
3     0    1    0    0    9
4     1    1    0    0    3
5     0    0    1    0   11
6     1    0    1    0    5
7     0    1    1    0    8
8     1    1    1    0    2
9     0    0    0    1   11
10    1    0    0    1    5
11    0    1    0    1    8
12    1    1    0    1    2
13    0    0    1    1   10
14    1    0    1    1    4
15    0    1    1    1    7
16    1    1    1    1    1

我正在尝试手动执行此操作,但效率不高

df %>%
  mutate(rank = case_when(
    Var1 == 1 & Var2 == 1 & Var3 == 1 & Var4 == 1~ "1",
    Var1 == 1 & Var2 == 1 & Var3 == 1 & Var4 == 0~ "2",
    TRUE                                     ~ ""
  ))

我想将逻辑应用于更大的数据集。有没有一种有效的方法来做到这一点?有人可以指出我正确的方向吗?

最佳答案

frankfrankv in data.table接受向量、列表、data.frames 或 data.tables 作为输入”,这在这里很有用。

首先,frankv。它有一个 cols 参数,其中可以在字符向量中指定要排名的列 - 如果有许多需要以编程方式生成的列名,则很方便。它还有一个简洁的 order 参数。

library(data.table)
setDT(df)
df[ , Var34 := Var3 + Var4]
cols = c("Var1", "Var2", "Var34")
df[ , r := frankv(.SD, cols, order = -1L, ties.method = "dense")]
df[ , Var34 := NULL]

#     Var1 Var2 Var3 Var4  r
#  1:    0    0    0    0 12
#  2:    1    0    0    0  6
#  3:    0    1    0    0  9
#  4:    1    1    0    0  3
#  5:    0    0    1    0 11
#  6:    1    0    1    0  5
#  7:    0    1    1    0  8
#  8:    1    1    1    0  2
#  9:    0    0    0    1 11
# 10:    1    0    0    1  5
# 11:    0    1    0    1  8
# 12:    1    1    0    1  2
# 13:    0    0    1    1 10
# 14:    1    0    1    1  4
# 15:    0    1    1    1  7
# 16:    1    1    1    1  1

frank 便于交互使用:

df[ , r := frank(.SD, -Var1, -Var2, -Var34, ties.method = "dense")]

相关答案:How to emulate SQLs rank functions in R? ; Rank based on several variables

关于r - 基于多个列计算排名,具有优先规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62820438/

相关文章:

r - 改变每一个可能的列组合

r - 试图识别 Landsat 图像中的断点 - 为什么 BFAST 会错过明显的断点?

R dplyr 逐行获取 which.min 的名称

r - 当矢量化不可行时,在数据框中迭代行的 tidyverse 方法是什么?

r - 在 R 中使用粘贴文本中的上标(对于多个值的向量)

r - Mann-Whitney U 的 p 值为 1 - 伪影?

r - 使用 ifelse 改变具有多个条件的新列时如何处理或忽略 NA(已解决)

rbind `data.tables`并保留 key

r - 理解R中data.table的引用属性

r - 计算不包括当前值的平均值