1

我有不平衡的面板数据,其中包含一个二进制变量,指示事件是否发生。我想控制时间依赖性,所以我想创建一个变量来指示自上次事件以来经过的年数。数据按 dyad-year 组织。

这是一个可重现的示例,其中包含我想要实现的向量。谢谢!

   id year onset time_since_event
1   1 1989     0                1
2   1 1990     0                2
3   1 1991     1                0
4   1 1992     0                1
5   1 1993     0                2
6   2 1989     0                1
7   2 1990     1                0
8   2 1991     0                1
9   2 1992     1                0
10  3 1991     0                1
11  3 1992     0                2

˚

id <- c(1,1,1,1,1,2,2,2,2,3,3)
year <- c(1989,1990,1991,1992,1993,1989,1990,1991,1992,1991,1992)
onset <- c(0,0,1,0,0,0,1,0,1,0,0)
time_since_event<-c(1,2,0,1,2,1,0,1,0,1,2) #what I want to create
df <- data.frame(cbind(id, year, onset,time_since_event))
4

1 回答 1

1

我们可以使用data.table. 将 'data.frame' 转换为 'data.table' ( setDT(df),使用 'onset' 列创建运行长度 id 分组变量 ('ind') rleid。按 'ind' 和 'id' 列分组,我们分配'time_since_event' 列作为行序列,其中 'onset' 不等于 1。在下一步中,将 'NA' 元素替换为 0。

library(data.table)#v1.9.6+
setDT(df)[, ind:=rleid(onset)][onset!=1, time_since_event:=1:.N , 
     by = .(ind, id)][is.na(time_since_event), time_since_event:= 0]

df
#     id year onset ind time_since_event
# 1:  1 1989     0   1                1
# 2:  1 1990     0   1                2
# 3:  1 1991     1   2                0
# 4:  1 1992     0   3                1
# 5:  1 1993     0   3                2
# 6:  2 1989     0   3                1
# 7:  2 1990     1   4                0
# 8:  2 1991     0   5                1
# 9:  2 1992     1   6                0
#10:  3 1991     0   7                1
#11:  3 1992     0   7                2

或者它可以做得很紧凑。按rleid(onset)和 'id' 列分组,我们否定 'onset'(使 0 变为 TRUE 和 1 FALSE),乘以行序列 ( 1:.N) 并将其分配 ( :=) 为 'time_since_event' 列。

setDT(df)[,time_since_event := 1:.N *!onset, by = .(rleid(onset), id)]
df
#    id year onset time_since_event
# 1:  1 1989     0                1
# 2:  1 1990     0                2
# 3:  1 1991     1                0
# 4:  1 1992     0                1
# 5:  1 1993     0                2
# 6:  2 1989     0                1
# 7:  2 1990     1                0
# 8:  2 1991     0                1
# 9:  2 1992     1                0
#10:  3 1991     0                1
#11:  3 1992     0                2

或者我们可以使用dplyr. 我们按 'id' 和创建的另一个变量分组(通过取 'onset' ( diff) 中相邻元素的差异,创建逻辑索引 ( !=0) 和cumsum索引)。在 中mutate,我们将行序列 ( row_number()) 与否定的 'onset' 相乘(就像之前一样),并使用 . 删除 'ind' 列select

library(dplyr)
df %>% 
    group_by(id, ind= cumsum(c(TRUE, diff(onset)!=0))) %>% 
    mutate(time_since_event= (!onset) *row_number()) %>%
    ungroup() %>%
    select(-ind) 
#     id  year onset time_since_event
#   (dbl) (dbl) (dbl)            (int)
#1      1  1989     0                1
#2      1  1990     0                2
#3      1  1991     1                0
#4      1  1992     0                1
#5      1  1993     0                2
#6      2  1989     0                1
#7      2  1990     1                0
#8      2  1991     0                1
#9      2  1992     1                0
#10     3  1991     0                1
#11     3  1992     0                2

数据

df <- data.frame(id, year, onset)
于 2015-10-31T15:17:57.073 回答