【问题标题】:How to rank numeric data by rows in a dataframe in r?如何在r中的数据框中按行对数字数据进行排名?
【发布时间】:2021-09-20 16:19:33
【问题描述】:

我有一个将近 5000 列的数据框。这里是数据框的sn-p

df= data.frame(a=c(13,17,19,7,9),
           b=c(1,3,50,NA,3),
           c=c(NA,NA,NA,NA,9))

我想对数据框单元格的值进行排名 w.r.t.行

预期输出

df= data.frame(a=c(1,1,2,1,1),
               b=c(2,2,1,NA,2),
               c=c(NA,NA,NA,NA,1))

【问题讨论】:

  • 嗨,可以看到每个变量的最高值在我们的预期输出中总是排名为 1。但是,为什么您希望为 a 和 b 列中的所有较低等级(和不同)值分配相同的等级 (2)?您是否只对排名最高的行感兴趣?
  • 你试过什么没用?
  • 在获得每个排名后,我必须进行一些百分位运算,因此我不仅想要第一名,而是应该按顺序对行进行排名@scrameri
  • 我已经尝试过 t(apply(-df,1,rank)) 并且它正在工作但无法消除 NA .. 它也在排名 NA'S @camille

标签: r dplyr tidyr


【解决方案1】:

我们可以使用pmap 循环遍历每一行(与rowwise 相比会更快)并应用dense_rank

library(purrr)
library(dplyr)
df %>% 
    pmap_dfr(~ setNames(dense_rank(-c(...)), names(c(...))))

-输出

# A tibble: 5 x 3
      a     b     c
  <int> <int> <int>
1     1     2    NA
2     1     2    NA
3     2     1    NA
4     1    NA    NA
5     1     2     1

或者更快的选择可能是使用来自collapsedapply

library(collapse)
library(data.table)
dapply(df, MARGIN = 1, FUN = frank, ties.method = 'dense', na.last = "keep")
  a  b  c
1 2  1 NA
2 2  1 NA
3 1  2 NA
4 1 NA NA
5 2  1  2

【讨论】:

  • frank() 来自哪里?我想知道如何使用ties.method = "dense" 参数。
  • @Skaqqs 不好意思,是来自data.table,collapse 很多函数都是以f开头的,所以我忘了是来自data.table
  • 知道了,谢谢。我喜欢这个答案!
【解决方案2】:
df <- data.frame(a=c(13,17,19,7,9), b=c(1,3,50,NA,3), c=c(NA,NA,NA,NA,9))
apply(X = -df, MARGIN = 1, FUN = rank, ties.method = "min", na.last = "keep")
#>   [,1] [,2] [,3] [,4] [,5]
#> a    1    1    2    1    1
#> b    2    2    1   NA    3
#> c   NA   NA   NA   NA    1

转置

t(apply(X = -df, MARGIN = 1, FUN = rank, ties.method = "min", na.last = "keep"))
#>      a  b  c
#> [1,] 1  2 NA
#> [2,] 1  2 NA
#> [3,] 2  1 NA
#> [4,] 1 NA NA
#> [5,] 1  3  1

注意关系的行为与您预期的不同,例如,第五行。

【讨论】:

    【解决方案3】:
    df= data.frame(a=c(13,17,19,7,9),
                   b=c(1,3,50,NA,3),
                   c=c(NA,NA,NA,NA,9))
    
    library(tidyverse)
    out <- df %>% 
      rowwise() %>% 
      transmute(res = list(dense_rank(-c_across(a:c)))) %>% 
      unnest_wider(res) 
    
    names(out) <- names(df)
    out
    #> # A tibble: 5 x 3
    #>       a     b     c
    #>   <int> <int> <int>
    #> 1     1     2    NA
    #> 2     1     2    NA
    #> 3     2     1    NA
    #> 4     1    NA    NA
    #> 5     1     2     1
    

    reprex package (v2.0.1) 于 2021-09-20 创建

    【讨论】:

      猜你喜欢
      • 2016-07-28
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 2020-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多