R中按组的代码序列:组内重复出现的值
我想根据三列的组合来编码一个数字序列:ID、year和location。我想按顺序计算一个人在一个地方度过的年数。在位置改变的那一年,序列应该重新开始,因此,即使一个人回到他们以前去过的地方,序列也应该重新开始 带有序列的df应如下所示:R中按组的代码序列:组内重复出现的值,r,dplyr,time-series,sequencing,R,Dplyr,Time Series,Sequencing,我想根据三列的组合来编码一个数字序列:ID、year和location。我想按顺序计算一个人在一个地方度过的年数。在位置改变的那一年,序列应该重新开始,因此,即使一个人回到他们以前去过的地方,序列也应该重新开始 带有序列的df应如下所示: ID yr loc seq 1 1990 A 1 1 1991 A 2 1 1992 B 1 1 1993 B 2 1 1994 B 3 2 1990 B 1 2 1991 B 2 2 1992 A 1 2 1993 B 1 2 1994 B 2 3 1990
ID yr loc seq
1 1990 A 1
1 1991 A 2
1 1992 B 1
1 1993 B 2
1 1994 B 3
2 1990 B 1
2 1991 B 2
2 1992 A 1
2 1993 B 1
2 1994 B 2
3 1990 C 1
3 1991 C 2
3 1992 C 3
3 1993 B 1
3 1994 C 1
你对如何在R中编码这个有什么想法吗 在
data.table
中,我们有rleid
函数,这使它在这里变得简单
library(data.table)
setDT(df)[, seq1 := seq_len(.N), .(ID, rleid(loc))]
df
# ID yr loc seq seq1
# 1: 1 1990 A 1 1
# 2: 1 1991 A 2 2
# 3: 1 1992 B 1 1
# 4: 1 1993 B 2 2
# 5: 1 1994 B 3 3
# 6: 2 1990 B 1 1
# 7: 2 1991 B 2 2
# 8: 2 1992 A 1 1
# 9: 2 1993 B 1 1
#10: 2 1994 B 2 2
#11: 3 1990 C 1 1
#12: 3 1991 C 2 2
#13: 3 1992 C 3 3
#14: 3 1993 B 1 1
#15: 3 1994 C 1 1
我们可以在dplyr
中使用rleid
和base R方法来获得预期的输出
library(dplyr)
df %>%
group_by(ID, grp = data.table::rleid(loc)) %>%
mutate(seq1 = row_number())
或在R基中:
df$seq1 <- with(df, ave(yr, ID, data.table::rleid(loc), FUN = seq_along))
数据
df <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L,
3L, 3L, 3L, 3L, 3L), yr = c(1990L, 1991L, 1992L, 1993L, 1994L,
1990L, 1991L, 1992L, 1993L, 1994L, 1990L, 1991L, 1992L, 1993L,
1994L), loc = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 2L,
2L, 3L, 3L, 3L, 2L, 3L), .Label = c("A", "B", "C"), class = "factor"),
seq = c(1L, 2L, 1L, 2L, 3L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 3L,
1L, 1L)), class = "data.frame", row.names = c(NA, -15L))
df使用dplyr的方式:
library(dplyr)
df %>%
group_by(ID, idx = cumsum(+(loc != lag(loc, default = first(loc))))) %>%
mutate(seq = row_number()) %>%
ungroup() %>% select(-idx)
输出:
# A tibble: 15 x 4
ID yr loc seq
<int> <int> <fct> <int>
1 1 1990 A 1
2 1 1991 A 2
3 1 1992 B 1
4 1 1993 B 2
5 1 1994 B 3
6 2 1990 B 1
7 2 1991 B 2
8 2 1992 A 1
9 2 1993 B 1
10 2 1994 B 2
11 3 1990 C 1
12 3 1991 C 2
13 3 1992 C 3
14 3 1993 B 1
15 3 1994 C 1
#一个tible:15 x 4
ID yr loc seq
1 1990 A 1
2 1 1991 A 2
3 1 1992 B 1
4 1 1993 B 2
5 1 1994 B 3
6 2 1990 B 1
7 2 1991 B 2
8 2 1992 A 1
9 2 1993 B 1
10 2 1994 B 2
11 3 1990 C 1
12 3 1991 C 2
13 3 1992 C 3
14 3 1993 B 1
15 3 1994 C 1
在base R
中,我们可以将rle
与ave
df$seq <- with(df, ave(yr, ID, with(rle(as.character(loc)),
rep(seq_along(values), lengths)), FUN = seq_along))
df$seq
#[1] 1 2 1 2 3 1 2 1 1 2 1 2 3 1
df$seq,也在data.table中,使用setDT(df)[,seq2:=rowid(ID,rleid(loc))]
df$seq <- with(df, ave(yr, ID, with(rle(as.character(loc)),
rep(seq_along(values), lengths)), FUN = seq_along))
df$seq
#[1] 1 2 1 2 3 1 2 1 1 2 1 2 3 1
df <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L,
3L, 3L, 3L, 3L, 3L), yr = c(1990L, 1991L, 1992L, 1993L, 1994L,
1990L, 1991L, 1992L, 1993L, 1994L, 1990L, 1991L, 1992L, 1993L,
1994L), loc = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 2L,
2L, 3L, 3L, 3L, 2L, 3L), .Label = c("A", "B", "C"), class = "factor"),
seq = c(1L, 2L, 1L, 2L, 3L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 3L,
1L, 1L)), class = "data.frame", row.names = c(NA, -15L))