Вы можете использовать match
для получения индекса первой 1 в каждом id
и за исключением замены всего на 0.
Это можно сделать с помощью dplyr
:
library(dplyr)
df %>%
group_by(id) %>%
mutate(treatment_year = replace(treated, -match(1L, treated), 0L))
#Can also use :
#mutate(treatment_year = +(row_number() == match(1L, treated)))
# id year treated treatment_year
# <int> <int> <int> <int>
#1 1 2000 0 0
#2 1 2001 0 0
#3 1 2002 1 1
#4 1 2003 1 0
#5 1 2004 1 0
база R:
df$treatment_year <- with(df, ave(treated, id, FUN = function(x)
replace(x, -match(1L, x), 0L)))
и data.table
:
library(data.table)
setDT(df)[, treatment_year := replace(treated, -match(1L, treated), 0L), id]
Объяснение того, как это работает.
match
возвращает первый индекс соответствия. Рассмотрим этот пример
x <- c(0, 0, 1, 1, 1)
match(1, x)
#[1] 3
В 3-й позиции мы находим первую 1. Добавляя к ней -
, мы игнорируем этот индекс и replace
все остальные значения с 0.
replace(x, -match(1, x), 0)
#[1] 0 0 1 0 0
Если x
всегда будет иметь значения 1/0, а x
всегда будет иметь хотя бы одну единицу, мы также можем использовать which.max
вместо match
.
which.max(x)
#[1] 3