How to get ranks with no gaps when there are ties among values?

后端 未结 8 1252
感情败类
感情败类 2020-12-03 14:26

When there are ties in the original data, is there a way to create a ranking without gaps in the ranks (consecutive, integer rank values)? Suppose:

x <-           


        
相关标签:
8条回答
  • 2020-12-03 15:02

    Modified crayola solution but using match instead of merge:

    x_unique <- unique(x)
    x_ranks <- rank(x_unique)
    x_ranks[match(x,x_unique)]
    

    edit

    or in a one-liner, as per @hadley 's comment:

    match(x, sort(unique(x)))
    
    0 讨论(0)
  • 2020-12-03 15:08

    Another function that does this, but it seems inefficient. There is no for loop, but I doubt it is more efficient than Sacha's suggestion!

    x=c(1,1,2,3,4,5,8,8)
    fancy.rank <- function(x) {
        x.unique <- unique(x)
        d1 <- data.frame(x=x)
        d2 <- data.frame(x=x.unique, rank(x.unique))
        merge(d1, d2, by="x")[,2]
    }
    
    fancy.rank(x)
    
    [1] 1 1 2 3 4 5 6 6
    
    0 讨论(0)
  • 2020-12-03 15:12

    try to think about another way

    x <-  c(10,10,10,5,5,20,20)
    as.numeric(as.factor(x))
    [1] 2 2 2 1 1 3 3
    
    0 讨论(0)
  • 2020-12-03 15:14

    If you don't mind leaving base-R:

    library(data.table)
    frank(x, ties.method = "dense")
    [1] 2 2 2 1 1 3 3
    

    data:

    x <-  c(10, 10, 10, 5, 5, 20, 20)
    
    0 讨论(0)
  • 2020-12-03 15:16

    What about sort()?

    x <- c(1,1,2,3,4,5)
    sort(x)
    
    > sort(x) 
    [1] 1 1 2 3 4 5
    
    0 讨论(0)
  • 2020-12-03 15:18

    I can think of a quick function to do this. It's not optimal with a for loop but it works:)

    x=c(1,1,2,3,4,5,8,8)
    
    foo <- function(x){
        su=sort(unique(x))
        for (i in 1:length(su)) x[x==su[i]] = i
        return(x)
    }
    
    foo(x)
    
    [1] 1 1 2 3 4 5 6 6
    
    0 讨论(0)
提交回复
热议问题