Я считаю, что это решает вашу проблему:
library(tidyr)
na_inds_begin <- as.numeric((is.na(df$begin)))
na_inds_end <- as.numeric((is.na(df$end)))
na_diffs_lead <- c(0, diff(na_inds_begin))
na_diffs_lag <- c(diff(na_inds_end), 0)
first_nas <- na_inds_begin == 1 & na_diffs_lead > 0
first_nas[1] <- na_inds_begin[1] == 1
last_nas <- na_inds_end == 1 & na_diffs_lag < 0
last_nas[length(last_nas)] <- na_inds_end[length(na_inds_end)] == 1
df$begin[first_nas] <- df$date_time[first_nas]
df$end[last_nas] <- df$date_time[last_nas]
df$begin[first_nas] <- df$date_time[first_nas]
df$end[last_nas] <- df$date_time[last_nas]
df <-
df %>%
fill(begin, .direction = "down") %>%
fill(end, .direction = "up")
Сначала мы находим первые NA
в каждой группе NA
s в begin
, и последние NA
в каждой группе NA
с в end
. Нам также нужно обработать случаи, когда первый элемент в begin
или последний элемент в end
равны NA
. Затем мы заменяем только те элементы с желаемыми заменами. Наконец, мы заполняем остаток каждой группы вниз на begin
и вверх на end
.
Это результат:
> df
# A tibble: 5 x 4
individ_id date_time begin end
<chr> <dttm> <dttm> <dttm>
1 NOS_4214433 2017-11-22 09:01:49 2017-11-21 11:54:59 2017-11-22 09:07:27
2 NOS_4214433 2017-11-22 09:06:49 2017-11-21 11:54:59 2017-11-22 09:07:27
3 NOS_4214433 2017-11-22 09:11:49 2017-11-22 09:11:49 2017-11-22 09:16:49
4 NOS_4214433 2017-11-22 09:16:49 2017-11-22 09:11:49 2017-11-22 09:16:49
5 NOS_4214433 2018-01-24 12:12:18 2018-01-24 12:08:28 2018-01-25 09:33:10
Редактировать: я обновил пример кода, чтобы он соответствовал случаю, когда begin
и end
имеют разные индексы NA
или первый / последние элементы NA
.