计算类别中重复值的列的等级

时间:2018-12-27 16:53:24

标签: r

我需要在新列中获得排名,该列为非零值以及零和重复值给出排名。

Data Frame - 

Category    Value
A       0.105
A       0.104
A       0
A       0
A       0
B       0.206
B       0.105
B       0.104
B       0
B       0

我需要的是-

    Category    Value   Rank 
    A            0.105  1
    A            0.104  2
    A            0      3
    A            0      4
    A            0      5
    B            0.206  1
    B            0.105  2
    B            0.104  3
    B            0      4
    B            0      5

我用它来生成序列,但没有给出正确的值。请客气,我只是从R开始。

df是我的数据框

df$newRank <- with(df, ave(Category, Category, Value, FUN = seq_along))

3 个答案:

答案 0 :(得分:1)

dplyr::row_number()是一种排名函数,可以给相等的数字不同的排名。例如,row_number(c(1, 1, 2, 2, 3))将产生1 2 3 4 5。但是,它给出最小编号等级1,第二最小编号等级2,依此类推。因此,在您的情况下,我进行了一次转换以反转幅度,即在排名之前使最小的数字最大。

library(dplyr)

df %>% group_by(Category) %>%
       mutate(Rank = row_number(max(Value) - Value))

# # A tibble: 10 x 3
# # Groups:   Category [2]
#    Category Value  Rank
#    <fct>    <dbl> <int>
#  1 A        0.105     1
#  2 A        0.104     2
#  3 A        0         3
#  4 A        0         4
#  5 A        0         5
#  6 B        0.206     1
#  7 B        0.105     2
#  8 B        0.104     3
#  9 B        0         4
# 10 B        0         5

with()within()方法

within(df, Rank <- ave(Value, Category, FUN = function(x){
  return(dplyr::row_number(max(x) - x))
}))

(请在R文档中查找with()within()之间的区别)


数据

df <- structure(list(Category = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L),
                .Label = c("A", "B"), class = "factor"),
                Value = c(0.105, 0.104, 0, 0, 0, 0.206, 0.105, 0.104, 0, 0)),
                class = "data.frame", row.names = c(NA, -10L))

答案 1 :(得分:1)

使用data.table

dt=as.data.table(df)
dt=dt[order(Category,-Value),]
dt[,`:=`(Rank=seq_along(Value)),by=Category]

答案 2 :(得分:0)

在我看来,使用 data.table 中的 rleid 是最好的选择 - 您会得到一个排名,其中相同的值获得相同的排名。

# create a ranking variable, either by group or not, equal values has same ranking, using rleid()
df <- structure(list(category = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L),
                .Label = c("A", "B"), class = "factor"),
                value = c(0.105, 0.104, 0, 0, 0, 0.206, 0.105, 0.104, 0, 0)),
                class = "data.frame", row.names = c(NA, -10L))
dt <- as.data.table(df)
dt <- dt[, .SD[sample(.N, .N)]] # reorder the rows to mimic unordered case
dt <- dt[order(category, -value),]
# without grouping
dt[, rank :=  rleid(value)]
# with grouping
dt[, rank :=  rleid(value), by=category]

rleid 不能同时使用两个变量进行分组,所以要小心 - 如果这是你需要的,你必须在使用 rleid 之前自己创建一个包含这两个变量的组合的新变量().

如果你希望排名不同,即使分组内value的值相同,使用data.table中的.N特殊函数(这里需要提前排序):

# with equal rank to the same groups, using 1:.N
df <- structure(list(category = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L),
                .Label = c("A", "B"), class = "factor"),
                value = c(0.105, 0.104, 0, 0, 0, 0.206, 0.105, 0.104, 0, 0)),
                class = "data.frame", row.names = c(NA, -10L))
dt <- as.data.table(df)
dt <- dt[, .SD[sample(.N, .N)]] # reorder the rows to mimic unordered case

dt <- dt[order(category, -value),]
dt[, rank :=  1:.N, by=category]