在数据框中创建一个新列:组内索引(不在组之间唯一)

4

我有一个包含两列的数据框:第一列包含每个个体所属的组,第二列包含个体的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 很棒!)。
非常感谢任何帮助!
3个回答

4
你可以在这里使用新的rleid函数(从开发版本v >= 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 <= 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

@DavidArenburg 不错的选择。我忘记了as.numeric(factor)的方法。不知道rleid - akrun
@akrun 的 rleid 函数是 Arun 在一周前新添加的五个函数之一。 - David Arenburg

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

您可以按照这里的说明安装它。

2

使用基本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

数据表版本将是:
setDT(df)[, Ineed := cumsum(!duplicated(indiv)), group][]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接