【问题标题】:R-ranking values of a column by grouping, conditional to another variable通过分组对列的值进行 R 排序,以另一个变量为条件
【发布时间】:2016-10-07 17:12:31
【问题描述】:

我有这样一个数据框(df):

group col1 col2  
x      a    22    
x      a    23  
x      b    16  
x      b    18  
y      a    11  
y      a    12  
y      a    16  
y      a    45  
y      b    24  

期望的输出是:

group col1 col2 rank 
x      a    22  1  
x      a    23  2
x      b    16  0
x      b    18  0
y      a    11  1
y      a    12  2
y      a    16  3
y      a    45  4
y      b    24  0

即,

  • 按组和 col1 排序 col2
  • 当 col1="b" 时排名为 0
  • col2 的值从小到大排序

如何使用 R 来做到这一点?我会很高兴得到任何帮助。非常感谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以试试

    library(dplyr)
     df %>%
        group_by(group, col1) %>% 
        mutate(rank=replace(min_rank(col2), col1=='b',0) )
    #    group col1 col2 rank
    #1     x    a   22    1
    #2     x    a   23    2
    #3     x    b   16    0
    #4     x    b   18    0
    #5     y    a   11    1
    #6     y    a   12    2
    #7     y    a   16    3
    #8     y    a   45    4
    #9     y    b   24    0
    

    如果您不希望在出现平局时排名之间出现差距,请将min_rank 替换为dense_rank

    或者,而不是replace

     res <- df %>% 
              group_by(group, col1) %>% 
              mutate(rank=(col1!='b')*min_rank(col2))
    
     as.data.frame(res) #would be `data.frame`
     #    group col1 col2 rank
     #1     x    a   22    1
     #2     x    a   23    2
     #3     x    b   16    0
     #4     x    b   18    0
     #5     y    a   11    1
     #6     y    a   12    2
     #7     y    a   16    3
     #8     y    a   45    4
     #9     y    b   24    0
    

    【讨论】:

    • 我无法将“df”作为数据框。如何将其作为数据框获取?
    • @orcim 你可以做as.data.frame(res)。更新了帖子
    • df 是数据框,但缺少“rank”列
    • @orcim 我得到了所有的列,检查as.data.frame(res)的输出如果你需要更新df,然后将结果分配给df &lt;- df%&gt;% group_by..而不是res &lt;- ..
    • 我无法管理,我不知道为什么。当我运行代码时,我会在输出中看到排名列。但是当我想起“df”时,排名列不见了。
    【解决方案2】:

    或者使用data.tablev>= 1.9.5

    library(data.table)
    setDT(df)[, rank := frank(col2, ties.method = "dense"),
                 by = .(group, col1)][col1 == "b", rank := 0L][]
    
    #    group col1 col2 rank
    # 1:     x    a   22    1
    # 2:     x    a   23    2
    # 3:     x    b   16    0
    # 4:     x    b   18    0
    # 5:     y    a   11    1
    # 6:     y    a   12    2
    # 7:     y    a   16    3
    # 8:     y    a   45    4
    # 9:     y    b   24    0
    

    或者像@Arun 建议的那样,如果您先将b 设置为零,则可以跳过一个分组步骤

    dt[, rank := 0L][col1 != "b", rank := frank(col2, ties.method="dense"), by=group][]
    

    【讨论】:

      【解决方案3】:

      baseR:

      df$rank<-ave(df$col2,df[,1:2],FUN=rank)*(df$col1!="b")
      

      【讨论】:

        猜你喜欢
        • 2020-04-01
        • 2023-04-01
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        • 1970-01-01
        • 2016-10-21
        • 1970-01-01
        • 2017-08-20
        相关资源
        最近更新 更多