问题描述
我有以下data.frame:
df<-data.frame(日期= c(1,1,1,1,2,2,2,2,3,3,3,3),id = c(4,4,2,4,1,2,3,1,2,2,1,1))
我想添加一个新列 grp
,该列针对每个日期对ID进行排名.领带应具有相同的值,但不应有遗漏的值.也就是说,如果有两个相等的最小值,则它们都应排在第1位,而下一个最小值应排在第2位.
因此,预期结果将如下所示.请注意,如上所述,分组是针对每个日期的,因此必须按日期对操作进行分组.
data.frame(date = c(1,1,1,1,2,2,2,2,2,3,3,3,3),id = c(4,4,2,4,1,2,3,1,2,2,1,1),grp = c(2,2,1,2,1,2,3,1,2,2,1,1))
我敢肯定有一种简单的方法可以做到这一点,但我还没有找到: tie.method
的所有选项都不以这种方式运行( data.table ::坦率的
也无济于事,因为它只会增加密集的排名).
我考虑过进行正常排名,然后使用 data.table :: rleid
,但是如果同一天中存在重复的值并由其他值分隔的情况,则无法正常工作.
我还考虑过按 date
和 id
进行分组,然后使用组ID,但是每天的最低值必须从等级1开始,这样就不会了"也不行.
我发现的唯一功能性解决方案是每天创建另一个具有唯一 ids
的表,然后将该表连接到该表:
suppressPackageStartupMessages(library(dplyr))df<-data.frame(date = c(1,1,1,1,2,2,2,2,2,3,3,3,3),id = c(4,4,2,4,1,2,3,1,2,2,1,1))不重复<-df%&%;%通过...分组(日期)%&%;%清楚的(ID)%&%;%变异(grp =等级(id))df<-df%&%;%left_join(独特)%>%print()#>通过= c("date","id")加入#>日期id grp#>1 1 4 2#>2 1 4 2#>3 1 2 1#>4 1 4 2#>5 2 1 1#>6 2 2 2#>7 2 3 3#>8 2 1 1#>9 3 2 2#>10 3 2 2#>11 3 1 1#>12 3 1 1
However, this seems quite inelegant and convoluted for what seems like a simple operation, so I'd rather see if other solutions are available.
Curious to see data.table
solutions if available, but unfortunately the solution must be in dplyr
.
We can use dense_rank
library(dplyr)
df %>%
group_by(date) %>%
mutate(grp = dense_rank(id))
# A tibble: 12 x 3
# Groups: date [3]
# date id grp
# <dbl> <dbl> <int>
# 1 1 4 2
# 2 1 4 2
# 3 1 2 1
# 4 1 4 2
# 5 2 1 1
# 6 2 2 2
# 7 2 3 3
# 8 2 1 1
# 9 3 2 2
#10 3 2 2
#11 3 1 1
#12 3 1 1
Or with frank
library(data.table)
setDT(df)[, grp := frank(id, ties.method = 'dense'), date]
这篇关于分组的无密度等级,无遗漏值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!