Как сделать столбец временного интервала на основе столбца метки времени?

У меня есть таблица данных с отметками времени в столбце 1 и событиями в столбце 2. Метки времени имеют формат Y-m-d H:M:OS3 (например, "2019-09-26 07:29:22,778").

Я хотел бы добавить новый столбец со значениями временного интервала разницы между отметкой времени 2 и отметкой времени 1, затем 3 к 1 и т. Д. Например:

timestamp                  event           diff in sec
2019-09-26 07:29:22,778    X                   
2019-09-26 07:29:23,918    Y               1.140
2019-09-26 07:29:25,118    Z               2.340
.
.

person VGF    schedule 04.10.2019    source источник
comment
Добро пожаловать в StackOverflow! Прочтите информацию о как задать хороший вопрос и как задать воспроизводимый пример. Это поможет другим людям помочь вам.   -  person JBGruber    schedule 04.10.2019


Ответы (3)


In base:

dt1$timediff <- cumsum(c(0, difftime(tail(dt1$timestamp,-1), head(dt1$timestamp,-1))))

или используя data.table:

library(data.table)

dt1[ , timediff := cumsum(c(0, diff(as.numeric(timestamp))))][]
#>                  timestamp event timediff
#> 1: 2019-09-26 07:29:22.778     X     0.00
#> 2: 2019-09-26 07:29:23.917     Y     1.14
#> 3: 2019-09-26 07:29:25.118     Z     2.34

Еще одно dplyr решение, основанное на ответе akrun:

library(dplyr)
dt1 %>%
  mutate(difftime = difftime(timestamp, timestamp[1], unit = 'sec'))

Данные: N.B: я использую data.table для чтения данных.

fread(text="date time  event
 2019-09-26 07:29:22.778    X                   
 2019-09-26 07:29:23.918    Y               
 2019-09-26 07:29:25.118    Z") -> dt1

dt1$timestamp <- as.POSIXct(paste(dt1$date, dt1$time), format="%Y-%m-%d %H:%M:%OS")

dt1 <- dt1[,4:3]
person M--    schedule 04.10.2019

Вот решение с dplyr. Я предположил, что вам нужна разница во времени с первого события. В противном случае ответ @akrun с lag() будет правильным.

library(dplyr)
df %>% 
  mutate(start = min(timestamp)) %>% 
  mutate(diff = timestamp - start)
#>             timestamp             event               start      diff
#> 1 2019-09-26 07:29:22                 X 2019-09-26 07:29:22 0.00 secs
#> 2 2019-09-26 07:29:23                 Y 2019-09-26 07:29:22 1.14 secs
#> 3 2019-09-26 07:29:25                 Z 2019-09-26 07:29:22 2.34 secs

данные

df <- structure(list(timestamp = structure(c(1569479362.778, 1569479363.918, 
                                                 1569479365.118), class = c("POSIXct", "POSIXt"), tzone = ""), 
                         event = c("X", "Y", "Z")), row.names = c(NA, 
                                                                                  -3L), class = "data.frame")
person JBGruber    schedule 04.10.2019
comment
Спасибо. Поскольку мне все еще не удается найти правильный формат, я хотел бы спросить вас, как вы поступите с входным текстовым файлом, который выглядит именно так: 2019-09-26 17: 54: 24,406 [218] ИНФОРМАЦИЯ - [1] - Событие X 26.09.2019 17: 54: 24,431 [207] ИНФОРМАЦИЯ - [1] - Событие Y 26.09.2019 17: 54: 24,438 [218] ИНФОРМАЦИЯ - [1] - Событие Z - person VGF; 10.10.2019
comment
Я думаю, вам следует задать новый вопрос, в котором ваши требования будут немного яснее. Я не знаю, к чему вы клоните, и, похоже, ваша первоначальная проблема решена. - person JBGruber; 10.10.2019

Мы можем использовать difftime

library(dplyr)
library(lubridate)
df1 %>%
   mutate(timestamp = ymd_hms(timestamp),
          diffinsec = cumsum(as.numeric(difftime(timestamp, 
       lag(timestamp, default = timestamp[1]), unit = 'sec'))))
person akrun    schedule 04.10.2019
comment
Как мне обернуть его as.numeric? В моих руках это приводит к целочисленным значениям для столбца diff в секундах, однако я также хотел бы получить миллисекунды (например, 2340 секунд). - person VGF; 06.10.2019
comment
Нет, это символьные столбцы, только новый diffinsec является числовым. Как бы вы читали файл данных, сохраняя неизменным формат метки времени и? В качестве альтернативы, как бы вы преобразовали столбцы 1 и 2 в числовые столбцы? - person VGF; 07.10.2019
comment
@ W.H.G. Хотя непонятно. Если вы хотите преобразовать столбцы с 1 по 2 в числовые df1 %>% mutate_at(1:2, as.numeric) %>% - person akrun; 07.10.2019
comment
Хорошо, спасибо. Но как мне получить значения в разнице в секундах, которые включают миллисекунды (например, 2340 секунд)? - person VGF; 08.10.2019
comment
Здесь мы использовали unit как sec, и если вы отметите ?difftime, параметр единиц включает только c("auto", "secs", "mins", "hours", "days", "weeks"), поэтому вам, возможно, придется преобразовать его в миллисекунды, выполнив затем некоторые арифметические операции. - person akrun; 08.10.2019