I have a data.table to which I want to add a countdown until a value of 1 appears in the flag
column.
dt = structure(list(date = structure(19309:19318, class = c("IDate",
"Date")), flag = c(0, 0, 0, 0, 0, 1, 0, 0, 0, 1)), class = c("data.table",
"data.frame"), row.names = c(NA, -10L), .internal.selfref = <pointer: 0x55af7de49cb0>)
> dt
date flag
1: 2022-11-13 0
2: 2022-11-14 0
3: 2022-11-15 0
4: 2022-11-16 0
5: 2022-11-17 0
6: 2022-11-18 1
7: 2022-11-19 0
8: 2022-11-20 0
9: 2022-11-21 0
10: 2022-11-22 1
Here is the expected output
date flag countdown
1: 2022-11-13 0 5
2: 2022-11-14 0 4
3: 2022-11-15 0 3
4: 2022-11-16 0 2
5: 2022-11-17 0 1
6: 2022-11-18 1 0
7: 2022-11-19 0 3
8: 2022-11-20 0 2
9: 2022-11-21 0 1
10: 2022-11-22 1 0
A data.table solution is preferred.
CodePudding user response:
A data.table solution is not only preferred but also beautiful.
library(data.table)
dt = structure(list(date = structure(19309:19318, class = c("IDate",
"Date")), flag = c(0, 0, 0, 0, 0, 1, 0, 0, 0, 1)), class = c(
"data.frame"), row.names = c(NA, -10L))
setDT(dt)
dt[, countdown := rev(1:.N), by=rleid(flag)][flag==1, countdown:=0 ]
dt
#> date flag countdown
#> 1: 2022-11-13 0 5
#> 2: 2022-11-14 0 4
#> 3: 2022-11-15 0 3
#> 4: 2022-11-16 0 2
#> 5: 2022-11-17 0 1
#> 6: 2022-11-18 1 0
#> 7: 2022-11-19 0 3
#> 8: 2022-11-20 0 2
#> 9: 2022-11-21 0 1
#> 10: 2022-11-22 1 0
Created on 2022-11-07 with reprex v2.0.2
edit
dt[, countdown := .N:1 * !flag, by=rleid(flag)]
for brevity.
CodePudding user response:
Another data.table
option
> cbind(dt, dt[, .(countdonwn = .N - seq(.N)), rev(cumsum(rev(flag)))][, 2])
date flag countdonwn
1: 2022-11-13 0 5
2: 2022-11-14 0 4
3: 2022-11-15 0 3
4: 2022-11-16 0 2
5: 2022-11-17 0 1
6: 2022-11-18 1 0
7: 2022-11-19 0 3
8: 2022-11-20 0 2
9: 2022-11-21 0 1
10: 2022-11-22 1 0