Поскольку вопрос был помечен data.table
, вот соответствующее решение, которое использует некоторую хитрую арифметику с NA
и логическими значениями:
library(data.table)
setDT(DT)[order(Date), NewColumn := {
yr <- year(lubridate::ymd(Date, truncated = 1L))
chg <- Value / shift(Value) - 1.0
NA^(yr - shift(yr) != 1L) * NA^(!abs(chg) > 0.01) * (sign(chg) / 2.0 + 0.5)
}, by = Name][]
Name Date Value NewColumn
1: A 2000-01 0.5 NA
2: A 2001-03 0.4 0
3: A 2002-02 1.0 1
4: A 2003-05 0.9 0
5: A 2004-06 0.9 NA
6: A 2006-03 0.4 NA
Хитрость заключается в том, чтобы использовать тот факт, что NA^0
равно 1, а NA^1
равно NA
, а FALSE
соответствует 0 и TRUE
равно 1, так что
NA^c(FALSE, TRUE)
возвращает
[1] 1 NA
Данные
library(data.table)
DT <- fread("Name Date Value
A 2000-01 0.5
A 2001-03 0.4
A 2002-02 1.0
A 2003-05 0.9
A 2004-06 0.9
A 2006-03 0.4 ")