I need a variable "minus_180_days"/(counter) to be numbered in ascending order:
the first time you visit,
if the second time has elapsed less than 180 days (compared to the previous visit for the patient); if the 180-day criterion is not met, a 1 must also appear on that second visit;
if in the third visit less than 180 days have elapsed with the previous one (visit "2"), if the criterion of 180 days is not met, 1 in that third visit, etc
Data
pacient <- c(10,10,10,10,10,11,11,12,12,12,13, 13, 15, 14); pacient
date <- as.Date(c("01/01/2018","02/05/2018", "04/06/2018", "10/11/2019", "05/12/2018", "02/01/2018", "06/08/2018", "01/01/2018", "03/01/2018", "06/03/2018", "05/08/2018", "05/08/2019", "05/07/2019", "08/07/2017"), format = "%d/%m/%Y"); date
DF <- data.frame(pacient, date); DF
I have this code
DF <- DF %>%
group_by(pacient) %>%
arrange(date) %>%
mutate(days_visit = date - lag(date, default = first(date)))
days_visit <- as.integer(DF$days_visit)
DF <- DF[with(DF,order(pacient,date)),]
The output that I need (expected output)

A dplyr solution, updated to reflect @Gregor's useful comment:
DF2 <- DF %>%
group_by(pacient) %>%
arrange(pacient, date) %>%
mutate(days_visit = (date - lag(date, default = first(date))) %>% as.integer,
new_count = cumsum(days_visit > 180) + 1) %>%
group_by(pacient, new_count) %>%
mutate(vis_num = row_number(),
counter = case_when(vis_num == 1 ~ 1L,
days_visit < 180 ~ vis_num,
TRUE ~ 1L))
> DF
# A tibble: 14 x 5
# Groups: pacient [6]
pacient date days_visit vis_num counter
<dbl> <date> <int> <int> <int>
1 10 2018-01-01 0 1 1
2 10 2018-05-02 121 2 2
3 10 2018-06-04 33 3 3
4 10 2018-12-05 184 4 1
5 10 2019-11-10 340 5 1
6 11 2018-01-02 0 1 1
7 11 2018-08-06 216 2 1
8 12 2018-01-01 0 1 1
9 12 2018-01-03 2 2 2
10 12 2018-03-06 62 3 3
11 13 2018-08-05 0 1 1
12 13 2019-08-05 365 2 1
13 14 2017-07-08 0 1 1
14 15 2019-07-05 0 1 1
A bit more concise way (adapted from @Gregor) do this based on tidyverse, including the fix to an error pointed by @Gregor.
DF %>%
arrange(pacient, date) %>%
group_by(pacient) %>%
mutate(days_visit = as.integer(date - lag(date, default = first(date))) ,
less_180 = days_visit < 180,
counter = ave(less_180, cumsum(less_180 == 0), FUN = seq_along))
# A tibble: 17 x 5
# Groups: pacient [6]
pacient date days_visit less_180 counter
<dbl> <date> <int> <dbl> <dbl>
1 10 2018-01-01 0 1 1
2 10 2018-05-02 121 1 2
3 10 2018-06-04 33 1 3
4 10 2018-12-05 184 0 1
5 10 2019-11-10 340 0 1
6 10 2019-11-11 1 1 2
7 10 2019-11-12 1 1 3
8 10 2019-11-13 1 1 4
9 11 2018-01-02 0 1 1
10 11 2018-08-06 216 0 1
11 12 2018-01-01 0 1 1
12 12 2018-01-03 2 1 2
13 12 2018-03-06 62 1 3
14 13 2018-08-05 0 1 1
15 13 2019-08-05 365 0 1
16 14 2017-07-08 0 1 1
17 15 2019-07-05 0 1 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With