根据 R 中的另一个排序列值对数据框列进行排序

数据挖掘 r dplyr
2022-03-12 05:58:43

我有一个基于一列(数字列)排序的数据框来分配排名。如果此列值为零,则基于另一个字符列排列数据框,用于那些在数字列中具有零值的行。

但是要给出排名,我必须考虑 var2,这就是我根据 var2 排序的原因,如果这些行的 var2 中有任何相同的值,我必须考虑 var3 来给出排名。请查看数据框 2 和 3 行,var2 值是相同的,在这种情况下我必须考虑 var3 来给出排名。如果 var2 为零,我必须按字母顺序对 var1 列(字符列)进行排序并给出排名。如果 var2 是 NA 没有排名。请参考下面给出的数据框。

下面,数据帧根据 var2 列降序排序,但如果 var2 为零,则 var2 也包含零我必须根据 var1 对 var2 中为零的行对数据帧进行排序。我需要按 var1 对 var2 为零的行进行排序,然后按 var1 的字母顺序排列 NA。

    example:
    #      var1    var2    var3    rank
    # 1     c      556      45       1
    # 2     a      345      35       3
    # 3     f      345      64       2
    # 4     b      134      87       4
    # 5     z       0       34       5
    # 6     d       0       32       6
    # 7     c       0       12       7
    # 8     a       0       23       8
    # 9     e      NA      
    # 10    b      NA       

below is my code 
df <- data.frame(var1=c("c","a","f","b","z","d", "c","a", "e", "b", "ad", "gf", "kg", "ts", "mp"), var2=c(134, NA,345, 200, 556,NA, 345, 200, 150, 0, 25,10,0,150,0), var3=c(65,'',45,34,68,'',73,12,35,23,34,56,56,78,123))

# To break the tie between var3 and var2 
orderdf <- df[order(df$var2, df$var1, decreasing = TRUE), ] 

#assigning rank 
rankdf <- orderdf %>% mutate(rank = ifelse(is.na(var2),'', seq(1:nrow(orderdf))))

如果 var2 值为零(对于那些 var2 值为零的行),则预期的输出是按字母顺序对 var1 进行排序。

    expected output:
    #      var1    var2    var3    rank
    # 1     c      556      45       1
    # 2     a      345      35       3
    # 3     f      345      64       2
    # 4     b      134      87       4
    # 5     a       0       34       5
    # 6     c       0       32       6
    # 7     d       0       12       7
    # 8     z       0       23       8
    # 9     b      NA      
    # 10    e      NA       
2个回答

您可以简单地按两列排列:

library(dplyr)

df %>%
   arrange(desc(var2),var1)

编辑:

为了阐明为什么这样做,在您的示例中,只需按 var2 降序排列 df 就已经将所有 0 和 NA 值放在底部(因为 NA 的“价值”小于 0)。然而,由于这些行都具有相同的值,它们的顺序将是“随机的”,因为我们没有指定 tie 方法。通过为排列提供第二列,我们按照第二个标准 var1 对所有平局进行排序。

这实际上也会重新排列具有重复 var2 值的行,但这应该是一个奖励。

除了@Fnguyen 很好的答案。

如果您熟悉 SQL,则可以使用以下sqldf库并获得相同的结果

library(sqldf)
df <- data.frame(var1=c("c","a","f","b","z","d", "c","a", "e", "b", "ad", "gf", "kg", "ts", "mp"), var2=c(134, NA,345, 200, 556,NA, 345, 200, 150, 0, 25,10,0,150,0), var3=c(65,'',45,34,68,'',73,12,35,23,34,56,56,78,123))
sqldf("SELECT * FROM df ORDER BY var2 desc, var1 desc")

OUTPUT:
   var1 var2 var3
1     z  556   68
2     f  345   45
3     c  345   73
4     b  200   34
5     a  200   12
6    ts  150   78
7     e  150   35
8     c  134   65
9    ad   25   34
10   gf   10   56
11   mp    0  123
12   kg    0   56
13    b    0   23
14    d   NA     
15    a   NA