【问题标题】:Ranking based on multiple conditions基于多个条件的排名
【发布时间】:2016-09-23 18:07:23
【问题描述】:

我有一个如下所示的数据集 (nm),其中前三列显示用户是否正在使用该产品,即 1(是)或 0(不是)。接下来的三列显示了喜欢 A_TT 对应于 A_TT_1.1 的产品的百分比是多少:

nm

A_TT  B_TT  C_TT  A_TT_1.1  B_TT_2.1  C_TT_3.1
0      0     1     0.06     0.84       0.89
1      1     0     0.92     0.83       0.94
0      1     0     0.09     0.9        0.13
1      0     1     0.87     0.05       0.9
0      0     0     0.13     0.11       0.14

我想在数据集(nm)中添加两列,即 Rank1 和 Rank2,它在以下两个条件下排名前两个百分比:

a) 仅在前三列中值为“零”时选择和排名
b) 在排名列中,它应该返回其列名。

最终的输出应该是:

nm

A_TT    B_TT    C_TT    A_TT_1.1    B_TT_2.1    C_TT_3.1   Rank 1   Rank 2
0         0      1       0.06        0.84       0.89      B_TT_2.1  A_TT_1.1
1         1      0       0.92        0.83       0.94      C_TT_3.1  NONE
0         1      0       0.09        0.9        0.13      C_TT_3.1  A_TT_1.1
1         0      1       0.87        0.05       0.9       B_TT_2.1  NONE
0         0      0       0.13        0.11       0.14      C_TT_3.1  A_TT_1.1

我尝试了很多选项,但没有任何效果。提前感谢您提供解决方案。

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以通过 apply 指定 MARGIN = 1 来循环遍历行来做到这一点

    nm[paste0("Rank", 1:2)] <-  t(apply(nm, 1, FUN = function(x)  {
                             i1 <- !x[1:3] #logical index giving TRUE for 0
                             x1 <- x[4:6][i1] #subset elements 4:6 based on i1
                             names(x1[order(-x1)])[1:2] #order the 'x1', extract names
                              }))
    nm
    #  A_TT B_TT C_TT A_TT_1.1 B_TT_2.1 C_TT_3.1    Rank1    Rank2
    #1    0    0    1     0.06     0.84     0.89 B_TT_2.1 A_TT_1.1
    #2    1    1    0     0.92     0.83     0.94 C_TT_3.1     <NA>
    #3    0    1    0     0.09     0.90     0.13 C_TT_3.1 A_TT_1.1
    #4    1    0    1     0.87     0.05     0.90 B_TT_2.1     <NA>
    #5    0    0    0     0.13     0.11     0.14 C_TT_3.1 A_TT_1.1
    

    注意:最好将NA 作为缺失值而不是“NONE”,因为使用函数is.na/complete.cases/na.rm/na.omit 等更容易删除这些值。

    【讨论】:

      【解决方案2】:

      这是另一个尝试:

      x <- df[,1:3]
      y <- df[,4:6]
      y[x==1] <- NA
      z <- t(apply(y,1,function(x) colnames(y)[order(x, decreasing = T, na.last = T)]))[,1:2]
      z[rowSums(!x)==1, 2] <- NA
      df[,c("Rank1","Rank2")] <- z
      
       # A_TT B_TT C_TT A_TT_1.1 B_TT_2.1 C_TT_3.1    Rank1    Rank2
      # 1    0    0    1     0.06     0.84     0.89 B_TT_2.1 A_TT_1.1
      # 2    1    1    0     0.92     0.83     0.94 C_TT_3.1     <NA>
      # 3    0    1    0     0.09     0.90     0.13 C_TT_3.1 A_TT_1.1
      # 4    1    0    1     0.87     0.05     0.90 B_TT_2.1     <NA>
      # 5    0    0    0     0.13     0.11     0.14 C_TT_3.1 A_TT_1.1
      

      【讨论】:

        猜你喜欢
        • 2021-07-25
        • 1970-01-01
        • 2020-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 1970-01-01
        相关资源
        最近更新 更多