R语言中如何调整众数计算结果实现等值项排名区分
问题描述
现有代码基于Method1、Method2、Method3、Method4四列逐行计算众数,生成Mode列标识方案优先级(取值越小方案越优,Mode=1为最优)。但运行后发现备选方案10和12的众数取值均为2,出现同值无法区分次优方案的问题,需要实现具备完全区分度的类排名效果。
初始实现代码如下:
database<-structure(list(Alternatives = c(3, 4, 5, 6, 7, 8, 9, 10, 11, 12), Method1 = c(1L, 10L, 7L, 8L, 9L, 6L, 5L, 3L, 4L, 2L), Method2 = c(1L, 8L, 6L, 7L, 10L, 9L, 4L, 2L, 3L, 5L), Method3 = c(1L, 10L, 7L, 8L, 9L, 6L, 4L, 2L, 3L, 5L), Method4 = c(1L, 9L, 6L, 7L, 10L, 8L, 5L, 3L, 4L, 2L)), class = "data.frame", row.names = c(NA, 10L)) ModeFunc <- function(Vec) { tmp <- sort(table(Vec),decreasing = TRUE) Nms <- names(tmp) if(max(tmp) > 1) { as.numeric(Nms[1]) } else NA} output <- database |> rowwise() |> mutate(Mode = ModeFunc(c_across(Method1:Method4))) |> data.frame()
初始运行得到的输出存在重复众数:
> output Alternatives Method1 Method2 Method3 Method4 Mode 1 3 1 1 1 1 1 2 4 10 8 10 9 10 3 5 7 6 7 6 6 4 6 8 7 8 7 7 5 7 9 10 9 10 9 6 8 6 9 6 8 6 7 9 5 4 4 5 4 8 10 3 2 2 3 2 9 11 4 3 3 4 3 10 12 2 5 5 2 2
实现思路
核心逻辑是在众数排序的基础上增加平局打破规则,生成无重复的连续排名:
- 一级排序规则:保持原有逻辑,按
Mode列升序排列,值越小优先级越高 - 平局处理规则:可以根据业务需求选择,比如取四个方法得分的行均值作为二级排序键(均值越小优先级越高),如果不需要额外业务规则,直接按行的原始顺序分配连续排名即可
可以直接用R内置的rank()函数实现,通过ties.method参数指定平局时的排名规则,示例代码如下:
output$Rank <- (nrow(output) + 1) - rank(-output$Mode, ties.method = "last") output|> arrange(Mode)
运行后得到无重复值的排名结果:
Alternatives Method1 Method2 Method3 Method4 Mode Rank 1 3 1 1 1 1 1 1 2 10 3 2 2 3 2 2 3 12 2 5 5 2 2 3 4 11 4 3 3 4 3 4 5 9 5 4 4 5 4 5 6 5 7 6 7 6 6 6 7 8 6 9 6 8 6 7 8 6 8 7 8 7 7 8 9 7 9 10 9 10 9 9 10 4 10 8 10 9 10 10
如果需要更贴合业务的平局判定,可以把二级排序指标(比如行均值、最高频值的出现次数、次高频值大小等)传入rank()的排序输入中,自定义排序优先级。
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

