我的实际数据集由每个id
的重复测量组成,其中测量的数量可能因人而异。一个简单的例子是:
dat <- data.frame(id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L))
dat
## id
## 1 1
## 2 1
## 3 1
## 4 1
## 5 1
## 6 1
## 7 2
## 8 2
## 9 3
## 10 3
## 11 3
我正在尝试按dat
变量顺序编号id
行。结果应该是:
dat
## id s
## 1 1 1
## 2 1 2
## 3 1 3
## 4 1 4
## 5 1 5
## 6 1 6
## 7 2 1
## 8 2 2
## 9 3 1
## 10 3 2
## 11 3 3
你会怎么做?我尝试使用id
选择每个duplicated()
的最后一行,但这可能不是这样,因为它适用于整个列。
答案 0 :(得分:10)
使用ave()
。第一项是您要将该功能应用于的项目;其他项目是您的分组变量,FUN
是您要应用的功能。有关详细信息,请参阅?ave
。
transform(dat, s = ave(id, id, FUN = seq_along))
# id s
# 1 1 1
# 2 1 2
# 3 1 3
# 4 1 4
# 5 1 5
# 6 1 6
# 7 2 1
# 8 2 2
# 9 3 1
# 10 3 2
# 11 3 3
如果您有大型数据集或使用data.table
包,则可以使用“.N
”,如下所示:
library(data.table)
DT <- data.table(dat)
DT[, s := 1:.N, by = "id"]
## Or
## DT[, s := sequence(.N), id][]
或者,您可以使用rowid
,如下所示:
library(data.table)
setDT(dat)[, s := rowid(id)][]
# id s
# 1: 1 1
# 2: 1 2
# 3: 1 3
# 4: 1 4
# 5: 1 5
# 6: 1 6
# 7: 2 1
# 8: 2 2
# 9: 3 1
# 10: 3 2
# 11: 3 3
为了完整起见,这是“tidyverse”方法:
library(tidyverse)
dat %>%
group_by(id) %>%
mutate(s = row_number(id))
## # A tibble: 11 x 2
## # Groups: id [3]
## id s
## <int> <int>
## 1 1 1
## 2 1 2
## 3 1 3
## 4 1 4
## 5 1 5
## 6 1 6
## 7 2 1
## 8 2 2
## 9 3 1
## 10 3 2
## 11 3 3
答案 1 :(得分:3)
dat <- read.table(text = "
id
1
1
1
1
1
1
2
2
3
3
3",
header=TRUE)
data.frame(
id = dat$id,
s = sequence(rle(dat$id)$lengths)
)
给出:
id s
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
6 1 6
7 2 1
8 2 2
9 3 1
10 3 2
11 3 3
答案 2 :(得分:1)
使用tapply
但不优雅ave
cbind(dat$id,unlist(tapply(dat$id,dat$id,seq_along)))
[,1] [,2]
11 1 1
12 1 2
13 1 3
14 1 4
15 1 5
16 1 6
21 2 1
22 2 2
31 3 1
32 3 2
33 3 3