我有一个如下数据集:
id age mod
1 1 1
1 5 0
1 6 1
1 7 1
1 9 1
2 3 0
2 4 1
我想先创建该变量,并仅在mod的每个情节的首次出现时为其赋予true值(每个情节在mod == 1时开始)。情节可以定义为mod == 1的一系列(或独立的一天),其中年龄增加1或年龄增加2。换句话说,如果age == 2和mod == 1,则age ==在3和mod == 0且age == 4和mod == 1的情况下,2-4岁仍处于同一系列中,因为它们彼此之间仍相距2天之内。
因此理想情况下,最终数据集应如下所示:
id age mod first
1 1 1 TRUE
1 5 0 FALSE
1 6 1 TRUE
1 7 1 FALSE
1 9 1 FALSE
2 3 0 FALSE
2 4 1 TRUE
我尝试在data.table中使用lag语句,但未成功。
答案 0 :(得分:0)
简单的条件是mod[i]==1 & mod[i-1]==0
。也就是说,如果一行的mod
值为1,而上一行的mod
值为0,则将其标记为first
。
这应该有效:
d = read.table(text='id age mod
1 1 1
1 5 0
1 6 1
1 7 1
1 9 1
2 3 0
2 4 1', header=T)
d$first[1] = (d$mod[1]==1)
d$first[2:nrow(d)] = (d$mod[2:nrow(d)]==1 & d$mod[1:nrow(d)-1]==0)
答案 1 :(得分:0)
我相信这应该符合您的条件。可能可以在冗长而复杂的单行代码中完成此操作,但我认为为了清晰起见,将其分为多个步骤将达到相同的目的,而不会对性能造成重大影响。
library(data.table)
## Note - I added a couple more sample rows here
DT <- fread("id age mod
1 1 1
1 5 0
1 6 1
1 7 1
1 9 1
2 3 0
2 4 1
3 1 1
3 5 0
3 9 1
3 10 1")
## Create a column to track jumps in age
DT[, agejump := age - shift(age, n = 1L, fill = NA, type = "lag") > 2L, by = .(id)]
## Create a column to define continued sequences
DT[, continued := mod == 1 & shift(mod, n = 1L, fill = NA, type = "lag") == 1L, by = .(id)]
## backfill the first row of NA's for each id for both variables with FALSE
DT[DT[, .I[1], by = .(id)]$V1, c("agejump","continued") := FALSE]
## define first
DT[,first := (mod == 1 & continued == FALSE | mod == 1 & continued == TRUE & agejump == TRUE)]
print(DT)
# id age mod agejump continued first
# 1: 1 1 1 FALSE FALSE TRUE
# 2: 1 5 0 TRUE FALSE FALSE
# 3: 1 6 1 FALSE FALSE TRUE
# 4: 1 7 1 FALSE TRUE FALSE
# 5: 1 9 1 FALSE TRUE FALSE
# 6: 2 3 0 FALSE FALSE FALSE
# 7: 2 4 1 FALSE FALSE TRUE
# 8: 3 1 1 FALSE FALSE TRUE
# 9: 3 5 0 TRUE FALSE FALSE
# 10: 3 9 1 TRUE FALSE TRUE
# 11: 3 10 1 FALSE TRUE FALSE