我需要在新列中获得排名,该列为非零值以及零和重复值给出排名。
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))
答案 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]