R在组内创建ID

时间:2014-04-21 12:36:47

标签: r

我有以下数据集:

df<-structure(list(IDFAM = c("2010 7599 2996 1", "2010 7599 3071 1", 
"2010 7599 3071 1", "2010 7599 3660 1", "2010 7599 4736 1", "2010 7599 6235 1", 
"2010 7599 6299 1", "2010 7599 9903 1", "2010 7599 11013 1", 
"2010 7599 11778 1", "2010 7599 11778 1", "2010 7599 12248 1", 
"2010 7599 13127 1", "2010 7599 14261 1", "2010 7599 16280 1", 
"2010 7599 16280 1", "2010 7599 16280 1", "2010 7599 16280 1", 
"2010 7599 16280 1", "2010 7599 17382 1"), AGED = c(45L, 47L, 
24L, 46L, 46L, 44L, 43L, 43L, 43L, 16L, 43L, 46L, 44L, 47L, 43L, 
16L, 20L, 18L, 18L, 43L)), .Names = c("IDFAM", "AGED"), row.names = c("5614", 
"5748", "5753", "6864", "8894", "11761", "11884", "18738", "20896", 
"22351", "22353", "23267", "24939", "27072", "30946", "30947", 
"30949", "30950", "30952", "33034"), class = "data.frame")

我想为具有相同IDFAM值的每个观测值分配一个ID,范围从1到n,其中n是具有相同值IDFAM的观测数。这将产生下表:

IDFAM              AGED     ID
2010 7599 2996 1    45       1
2010 7599 3071 1    47       1
2010 7599 3071 1    24       2
2010 7599 3660 1    46       1
2010 7599 4736 1    46       1
2010 7599 6235 1    44       1
2010 7599 6299 1    43       1
2010 7599 9903 1    43       1
2010 7599 11013 1   43       1
2010 7599 11778 1   16       1
2010 7599 11778 1   43       2
2010 7599 12248 1   46       1
2010 7599 13127 1   44       1
2010 7599 14261 1   47       1
2010 7599 16280 1   43       1
2010 7599 16280 1   16       2
2010 7599 16280 1   20       3
2010 7599 16280 1   18       4
2010 7599 16280 1   18       5
2010 7599 17382 1   43       1

我该怎么做?感谢。

2 个答案:

答案 0 :(得分:17)

有几种方法。

在基数R中,使用ave

with(df, ave(rep(1, nrow(df)), IDFAM, FUN = seq_along))
#  [1] 1 1 2 1 1 1 1 1 1 1 2 1 1 1 1 2 3 4 5 1

使用“data.table”包,使用sequence(.N)

library(data.table)
DT <- as.data.table(df)
DT[, ID := sequence(.N), by = IDFAM]

使用“dplyr”包,请尝试:

df %>% group_by(IDFAM) %>% mutate(count = sequence(n()))

或(根据评论中Hadley的建议):

df %>% group_by(IDFAM) %>% mutate(count = row_number(IDFAM))

更新

由于这似乎是相对频繁的要求,因此我的“splitstackshape”包中已将此功能添加为函数(getanID)。它基于上面的“data.table”方法。

library(splitstackshape)
getanID(df, id.vars = "IDFAM")
#                 IDFAM AGED .id
#  1:  2010 7599 2996 1   45   1
#  2:  2010 7599 3071 1   47   1
#  3:  2010 7599 3071 1   24   2
#  4:  2010 7599 3660 1   46   1
#  5:  2010 7599 4736 1   46   1
#  6:  2010 7599 6235 1   44   1
#  7:  2010 7599 6299 1   43   1
#  8:  2010 7599 9903 1   43   1
#  9: 2010 7599 11013 1   43   1
# 10: 2010 7599 11778 1   16   1
# 11: 2010 7599 11778 1   43   2
# 12: 2010 7599 12248 1   46   1
# 13: 2010 7599 13127 1   44   1
# 14: 2010 7599 14261 1   47   1
# 15: 2010 7599 16280 1   43   1
# 16: 2010 7599 16280 1   16   2
# 17: 2010 7599 16280 1   20   3
# 18: 2010 7599 16280 1   18   4
# 19: 2010 7599 16280 1   18   5
# 20: 2010 7599 17382 1   43   1

答案 1 :(得分:2)

使用dplyr 0.5,您可以使用group_indices功能。虽然它不支持mutate,但以下方法很简单:

df$id <- df %>% group_indices(IDFAM)