R中按组的代码序列:组内重复出现的值

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、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 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))