R 组内的组ID

R 组内的组ID,r,R,我想通过在组内编号来创建组ID。这里重要的一点是对组内的进行编号,而不是对组内的进行编号。在以下示例中,数据应按“x”和为每个唯一的“y”值创建的唯一ID编号进行分组 df <- data.frame(x=LETTERS[c(1:2, 1, 1:2, 1, 2)], y=LETTERS[c(1, 1, 2, 1, 1, 3, 3)] ) 期望的结果 x y ID A A 1 B A 1 A B 2 A A 1 B A 1 A C 3 B C 2

我想通过在组内编号来创建组ID。这里重要的一点是对组内的进行编号,而不是对组内的进行编号。在以下示例中,数据应按“x”和为每个唯一的“y”值创建的唯一ID编号进行分组

df <- data.frame(x=LETTERS[c(1:2, 1, 1:2, 1, 2)], y=LETTERS[c(1, 1, 2, 1, 1, 3, 3)] )
期望的结果

x y ID  
A A  1  
B A  1  
A B  2  
A A  1  
B A  1  
A C  3  
B C  2  

我喜欢data.table这样做,但欢迎所有解决方案。我对data.table的.GRP和.N以及seq_len(.N)进行了处理,但没有结果。由于这似乎是一项简单而相当普通的任务,我不敢相信现在还没有人问过,至少我没有找到它

使用
dplyr
,您可以执行以下操作:

df %>%
 group_by(x) %>%
 mutate(ID = cumsum(!duplicated(y)))

  x     y        ID
  <fct> <fct> <int>
1 A     A         1
2 B     A         1
3 A     A         1
4 A     B         2
5 B     A         1
数据相同。表可以是:

setDT(df)[, ID := cumsum(!duplicated(y)), by = x]
如果您需要先安排:

setorder(setDT(df), x, y)[, ID := cumsum(!duplicated(y)), by = x]

下面是一个包含
数据的解决方案。表

library("data.table")

df <- data.table(x=LETTERS[c(1:2, 1, 1:2, 1, 2)], y=LETTERS[c(1, 1, 2, 1, 1, 3, 3)] )
df[, ID:=as.numeric(as.factor(y)), x]
df
# > df
#    x y ID
# 1: A A  1
# 2: B A  1
# 3: A B  2
# 4: A A  1
# 5: B A  1
# 6: A C  3
# 7: B C  2
库(“data.table”)
df-df
#x y ID
#1:A 1
#2:B1
#3:a2
#4:A1
#5:B1
#6:A C 3
#7:B C 2

这是一个基本的R解决方案。请注意,它会打乱数据帧的顺序

do.call(rbind, lapply(split(df, df$x), function(i)cbind(i, ID = match(i$y, unique(i$y)))))

#    x y ID
#A.1 A A  1
#A.3 A A  1
#A.4 A B  2
#B.2 B A  1
#B.5 B A  1

非常好,我调整了MRE以包括您@tmfmnk指出的边缘案例。好吧,我最初的MRE是一个边缘案例,您使用arrange的解决方案更通用,更好地服务于每个人。感谢您的贡献,很抱歉造成误导。事实上,您的解决方案接受了我的初始MRE,并达到了所需的输出。然而,这是由于我最初的MRE的缺点。真正的要点是按“x”分组,然后标记“y”,这是您的解决方案无法解决的问题(请参阅我当前修订的MRE)。很好,这也很有效。@tmfmnk的解决方案还重新安排了我的数据帧,这对我来说很好,但感谢您指出这一点。
library("data.table")

df <- data.table(x=LETTERS[c(1:2, 1, 1:2, 1, 2)], y=LETTERS[c(1, 1, 2, 1, 1, 3, 3)] )
df[, ID:=as.numeric(as.factor(y)), x]
df
# > df
#    x y ID
# 1: A A  1
# 2: B A  1
# 3: A B  2
# 4: A A  1
# 5: B A  1
# 6: A C  3
# 7: B C  2
do.call(rbind, lapply(split(df, df$x), function(i)cbind(i, ID = match(i$y, unique(i$y)))))

#    x y ID
#A.1 A A  1
#A.3 A A  1
#A.4 A B  2
#B.2 B A  1
#B.5 B A  1