Вычисление даты из ряда последовательных временных данных (R)

#r #date #time-series #lubridate

#r #Дата #временные ряды #lubridate

Вопрос:

У меня есть столбец последовательного времени (часы, минуты, секунды) с неравными интервалами, который длится несколько дней.

Например:

 library(lubridate)    
df <- data.frame(Data  = c(1:10),
                     Time = hms(c("10:00:00","15:38:44","22:12:37",
                                  "23:59:00","00:07:28","04:56:00",
                                  "08:01:25","12:10:54","16:08:43",
                                  "20:44:44")))
 

Я хочу создать новый столбец с комбинированной датой и временем, предполагая, что первая точка данных была взята 01.01.2020 в 10:00:00. Так, например, точка данных 8 получит «02.01.2020 12:10:54».

Мои попытки решить эту проблему не стоили публикации здесь, есть ли у кого-нибудь какие-либо предложения?

Большое спасибо!

Комментарии:

1. #добавить дату: df$date <- rep(«даты», 10) #объединить дату и время в новом столбце: df $newCol <- вставить (df $date, df $Time, sep = » «)

Ответ №1:

Это немного сложно, но вот решение:

 require(tidyverse)    
require(lubridate)

dataf <- tibble(Data  = c(1:16),
                 Time = hms(c("10:00:00","15:38:44","22:12:37",
                              "23:59:00","00:07:28","04:56:00",
                              "08:01:25","12:10:54","16:08:43",
                              "20:44:44","00:07:28","04:56:00",
                              "08:01:25","12:10:54","16:08:43",
                              "20:44:44")))

dataf_2 <- dataf %>% 
  mutate(Data = Data   1,
         Time_n = as.numeric(Time)) %>% 
  select(Data, Time_n)

dataf %>%
  left_join(dataf_2, by = c("Data")) %>%
  replace_na(list(Time_n = 0)) %>% 
  mutate(starting_date = dmy("01/01/2020")) %>% 
  mutate(change_day = if_else(as.numeric(Time) >= Time_n, 0, 1)) %>% 
  arrange(Data) %>% 
  mutate(cumsum=cumsum(change_day),
         t = paste(hour(Time), minute(Time), second(Time))) %>% 
  mutate(final_date = ymd_hms(paste(starting_date   days(cumsum), t))) %>% 
  select(Data, Time, final_date)
 

Это приведет к такому результату:

 # A tibble: 16 x 3
    Data Time        final_date         
   <dbl> <Period>    <dttm>             
 1     1 10H 0M 0S   2020-01-01 10:00:00
 2     2 15H 38M 44S 2020-01-01 15:38:44
 3     3 22H 12M 37S 2020-01-01 22:12:37
 4     4 23H 59M 0S  2020-01-01 23:59:00
 5     5 7M 28S      2020-01-02 00:07:28
 6     6 4H 56M 0S   2020-01-02 04:56:00
 7     7 8H 1M 25S   2020-01-02 08:01:25
 8     8 12H 10M 54S 2020-01-02 12:10:54
 9     9 16H 8M 43S  2020-01-02 16:08:43
10    10 20H 44M 44S 2020-01-02 20:44:44

 

Комментарии:

1. Большое вам спасибо, это очень многообещающе! Он почти работает, но терпит неудачу, когда есть два или более одинаковых времени. Возможно ли решить это с помощью вашего решения? Пример: dataf <- tibble(Data = c(1:16), Time = hms(c("10:00:00","15:38:44","22:12:37", "23:59:00","00:07:28","04:56:00", "08:01:25","12:10:54","16:08:43", "20:44:44","00:07:28","04:56:00", "04:56:00","12:10:54","16:08:43", "20:44:44")))

2. Вы правы. Просто замените if_else(как.numeric(Time) > Time_n, 0, 1) на if_else(как.numeric(Time) >= Time_n, 0, 1). Я редактирую ответ

Ответ №2:

Это должно сработать:

 df %>% 
  mutate(
    lag = lag(Time),
    diff = Time - lag,
    add_days = if_else(is.na(diff), 0, if_else(diff < 0, 1, 0)),
    add_days_cum = cumsum(add_days),
    date = ymd("2020-01-01")   days(add_days_cum)   Time
  )
 

Комментарии:

1. Спасибо за вашу помощь! К сожалению, при запуске вашего кода я получаю следующее сообщение об ошибке: «Ошибка при инициализации (значение, …): попытка получить слот «год» из объекта (класс «Период»), который не является объектом S4″

2. Это кажется странным. Для меня это работает с R 4.0.3 и lubridate 1.7.9.2, используя ваш пример набора данных. Пожалуйста, убедитесь, что никакие другие пакеты не загружены, чтобы не было конфликтов имен.

3. Я использовал RStudio Cloud для тестирования этого решения, и оно отлично работало — очень элегантно, спасибо. Кажется, у меня есть некоторые проблемы с моей установкой R.