我有一个包含两列的数据框:第一列包含每个人所属的组,第二列包含个人ID。见下文:
df <- data.frame( group=c('G1','G1','G1','G1','G2','G2','G2','G2'),
indiv=c('indiv1','indiv1','indiv2','indiv2','indiv3',
'indiv3','indiv4','indiv4'))
group indiv
1 G1 indiv1
2 G1 indiv1
3 G1 indiv2
4 G1 indiv2
5 G2 indiv3
6 G2 indiv3
7 G2 indiv4
8 G2 indiv4
我想在数据框中创建一个新列(保留长格式),其中包含组中每个人的索引,即:
group indiv Ineed
1 G1 indiv1 1
2 G1 indiv1 1
3 G1 indiv2 2
4 G1 indiv2 2
5 G2 indiv3 1
6 G2 indiv3 1
7 G2 indiv4 2
8 G2 indiv4 2
我尝试过使用data.table .N或.GRP方法,但没有成功(顺便说一下,对data.table做了很好的工作!)。
非常感谢任何帮助!
答案 0 :(得分:4)
您可以在此处使用新的rleid
功能(来自开发版本v&gt; = 1.9.5)
setDT(df)[, Ineed := rleid(indiv), group][]
# group indiv Ineed
# 1: G1 indiv1 1
# 2: G1 indiv1 1
# 3: G1 indiv2 2
# 4: G1 indiv2 2
# 5: G2 indiv3 1
# 6: G2 indiv3 1
# 7: G2 indiv4 2
# 8: G2 indiv4 2
或者您可以转换为因子(为了创建唯一的组),然后将它们转换回数字(如果您使用CRAN稳定版本v&lt; = 1.9.4)
setDT(df)[, Ineed := as.numeric(factor(indiv)), group][]
# group indiv Ineed
# 1: G1 indiv1 1
# 2: G1 indiv1 1
# 3: G1 indiv2 2
# 4: G1 indiv2 2
# 5: G2 indiv3 1
# 6: G2 indiv3 1
# 7: G2 indiv4 2
# 8: G2 indiv4 2
答案 1 :(得分:4)
在1.9.5
(当前开发版本)中,导出函数frank
(和frankv
)。有了它,你可以这样做:
require(data.table) ## 1.9.5+
setDT(df)[, col := frank(indiv, ties.method="dense"), by=group]
df
# group indiv col
# 1: G1 indiv1 1
# 2: G1 indiv1 1
# 3: G1 indiv2 2
# 4: G1 indiv2 2
# 5: G2 indiv3 1
# 6: G2 indiv3 1
# 7: G2 indiv4 2
# 8: G2 indiv4 2
您可以按照here说明进行安装。
答案 2 :(得分:2)
使用base R
df$Ineed <- with(df, ave(as.numeric(indiv), group,
FUN=function(x) cumsum(!duplicated(x))))
df
# group indiv Ineed
#1 G1 indiv1 1
#2 G1 indiv1 1
#3 G1 indiv2 2
#4 G1 indiv2 2
#5 G2 indiv3 1
#6 G2 indiv3 1
#7 G2 indiv4 2
#8 G2 indiv4 2
data.table版本将是
setDT(df)[, Ineed := cumsum(!duplicated(indiv)), group][]