Замените NA в POSIXct ser ie соседними значениями - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть такой фрейм данных (но с гораздо большим количеством строк):

  individ_id           date_time               begin           end
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                <NA>                <NA>
4: NOS_4214433 2017-11-22 09:16:49                <NA>                <NA>
5: NOS_4214433 2018-01-24 12:12:18 2018-01-24 12:08:28 2018-01-25 09:33:10

, и я хочу заполнить NA в начале и конце столбцов первым NA date_time значение для столбца 'begin' и последнее значение date_time NA для столбца 'end', например:

    individ_id           date_time               begin                 end
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

Все данные даты и времени представлены в формате POSIX, и я хочу сохранить его сюда. У кого-нибудь есть идея решить эту проблему?

1 Ответ

3 голосов
/ 20 февраля 2020

Я считаю, что это решает вашу проблему:

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.

...