我在R中有一个df
,用于跟踪个人加班是单身(0),已婚(1)还是已离婚(99)的状态。
ID <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5)
STATUS <- c("0", "0", "0", "1", "1", "1", "99", "99", "1", "0", "1")
df <- data.frame(ID, STATUS)
df
我想创建一个新变量,用于标记个人首次离婚(STATUS = 99)以及该点之后的任何行。例如,在STATUS
列下,ID 1在三个时期中是单身,然后在三个时期中离婚,然后又重新结婚。 “标志”列标记每个ID
出现的前99个和该行之后的所有事件。
最终产品应类似于:
ID STATUS FLAG
1 0 0
1 0 0
1 0 0
1 1 0
1 1 0
1 1 0
1 99 1
1 99 1
1 1 1
5 0 0
5 1 0
答案 0 :(得分:4)
我们可以按组使用cummax
df$FLAG <- with(df, ave(STATUS, ID, FUN = function(x) cummax(x == 99)))
df
# ID STATUS FLAG
#1 1 0 0
#2 1 0 0
#3 1 0 0
#4 1 1 0
#5 1 1 0
#6 1 1 0
#7 1 99 1
#8 1 99 1
#9 1 1 1
#10 5 0 0
#11 5 1 0
答案 1 :(得分:2)
使用dplyr
的一种可能性:
df %>%
group_by(ID) %>%
mutate(flag = ifelse(row_number() >= min(which(STATUS == 99)), 1, 0))
ID STATUS flag
<dbl> <fct> <dbl>
1 1. 0 0.
2 1. 0 0.
3 1. 0 0.
4 1. 1 0.
5 1. 1 0.
6 1. 1 0.
7 1. 99 1.
8 1. 99 1.
9 1. 1 1.
10 5. 0 0.
11 5. 1 0.
或使用dplyr
和tidyr
:
df %>%
group_by(ID) %>%
mutate(flag = ifelse(STATUS != 99, NA, 1)) %>%
fill(flag) %>%
mutate(flag = replace_na(flag, 0))
或者@markus在dplyr
中做了什么:
df %>%
group_by(ID) %>%
mutate(flag = cummax(STATUS == 99))
或使用基数R:
df$flag <- ave(df$STATUS, df$ID, FUN = function(x) ifelse(1:nrow(df) >= min(which(x == 99)), 1, 0))
ID STATUS flag
1 1 0 0
2 1 0 0
3 1 0 0
4 1 1 0
5 1 1 0
6 1 1 0
7 1 99 1
8 1 99 1
9 1 1 1
10 5 0 0
11 5 1 0