dplyr v0.7.6按日分组排名失效问题排查与解决
解决dplyr 0.7.6里分组排名失效的坑
是不是碰到了dplyr 0.7.6版本里的这个糟心问题?明明写了按日期分组算排名的代码,结果group_by(CREATIONDATE_DAY)根本没生效,出来的是全局排名而非每日分组的排名?
问题还原
你当时运行的代码是这样的:
dates <- sample(seq(from=as.POSIXct("2019-03-12",tz="UTC"),to=as.POSIXct("2019-03-20",tz="UTC"),by = "day"),size = 100,replace=TRUE) group <- sample(c("A","B","C"),100,TRUE) df <- data.frame(CREATIONDATE_DAY = dates,GROUP = group) # 统计每日每组的出现次数 dfMod <- df %>% group_by(CREATIONDATE_DAY,GROUP) %>% dplyr::summarise(COUNT = n()) %>% ungroup() # 按日期分组,按COUNT倒序计算排名 dfMod <- dfMod %>% group_by(CREATIONDATE_DAY) %>% mutate(rank = rank(-COUNT, ties.method ="min"))
就像你提到的,比如2019-03-16那天COUNT=4的组本该排第1,COUNT=3的组排第2,但实际得到的却是全局排名,完全不符合预期。
问题根源
这其实是dplyr 0.7.6版本的一个已知bug——当分组后用mutate()调用rank()函数时,分组的上下文没有被正确识别,导致rank()直接忽略了分组条件,按整个数据集来计算排名了。
解决办法
最简单直接的方案就是把dplyr升级到最新的稳定版本。官方在后续版本里已经修复了这个分组计算的bug,升级之后再跑这段代码,group_by(CREATIONDATE_DAY)就会正常工作,rank()会在每个日期的分组里独立计算排名,完全符合你的预期。
效果验证
升级后重新执行代码,你会看到每个日期分组内的rank列都正确按照-COUNT的顺序,用ties.method="min"的规则生成排名,比如2019-03-16的COUNT=4组排名为1,COUNT=3组排名为2,和你想要的结果一致。
内容的提问来源于stack exchange,提问作者Kilian
相关产品推荐
相关产品推荐

