Если у вас достаточно памяти, вы можете взять полный набор идентификаторов х лет и отфильтровать с помощью скользящего соединения:
res <- DT[
CJ(ID, Start_year = seq.int(min(Start_year), 2015L)),
on=.(ID, Start_year),
roll=TRUE,
nomatch=0
]
setnames(res, "Start_year", "Year")[]
CJ
принимает «перекрестное соединение» вектора идентификаторов и лет,Если вы не используете последнюю версию data.table, вам может потребоваться назвать оба аргумента (т.е. CJ(ID = ID, Start_year = seq.int(min(Start_year), 2015L))
).
Комментарий .ОП говорит, что подход @markus уже сводит операцию к секундам, поэтому, возможно, дальнейшее улучшение не требуется ... Кроме того, я не совсем уверен, что есть какие-то обстоятельства, при которых мой подход будет быстрее.