2016-12-02 2 views
1

Я хотел бы суммировать сегменты значений, которые попадают в один и тот же временной интервал. Любое значение, которое возникает после 6 часов предыдущего значения, я хочу в новом сегменте. Я также хотел бы рассчитать часов в каждом сегменте, а также максимальное и среднее значение для каждого сегмента.Суммирующие значения по заданным сегментам дат

Вот пример данных:

Date <- c("1954-10-07", "1954-10-07", "1954-10-07", "1954-10-07", "1954-10-07", "1954-10-07", "1954-10-11", "1954-10-11", "1954-10-11", "1954-10-12", "1954-10-13") 
Time <- c("0:00", "1:00", "4:00", "13:00", "14:00", "15:00", "9:00","10:00", "11:00", "23:00", "0:00") 
DateTime <- paste(Date, Time) 
Value <- c(0.1, 0.2, 0.1, 0.02, 0.2, 1.1, 0.2, 0.3, 0.4, 0.1, 0.05) 
df <- data.frame(Date, Time, DateTime, Value) 

df 
Date  Time  DateTime  Value 
1954-10-07 0:00 1954-10-07 0:00 0.10 
1954-10-07 1:00 1954-10-07 1:00 0.20 
1954-10-07 4:00 1954-10-07 4:00 0.10 
1954-10-07 13:00 1954-10-07 13:00 0.02 
1954-10-07 14:00 1954-10-07 14:00 0.20 
1954-10-07 15:00 1954-10-07 15:00 1.10 
1954-10-11 9:00 1954-10-11 9:00 0.20 
1954-10-11 10:00 1954-10-11 10:00 0.30 
1954-10-11 11:00 1954-10-11 11:00 0.40 
1954-10-12 23:00 1954-10-12 23:00 0.10 
1954-10-13 0:00 1954-10-13 0:00 0.05 

Желаемый результат:

IntervalStart  IntervalEnd ValueSum ValueMax ValueMedian HoursinSegment 
1954-10-07 0:00 1954-10-07 4:00 0.4  0.2  0.1   4 
1954-10-07 13:00 1954-10-07 14:00 1.32  1.10  0.2   3 
1954-10-11 9:00 1954-10-11 10:00 0.5  0.30  0.25   1 
1954-10-12 23:00 1954-10-13 0:00 0.15  0.1  0.75   1 

Хитрость Я думаю, это в штампами времени, я думаю, потому что некоторые значения попадают в следующий день, но все еще в течение 6 часов после предыдущего значения. Спасибо за помощь!

ответ

2

Я думаю, что это то, что вы ищете:

library(data.table) 
setDT(df)[,DateTime := as.POSIXct(sprintf("%s:00", DateTime))] 

df[, Grp := cumsum(c(0, difftime(DateTime[-1], head(DateTime, -1), units = "h")) > 6)] 

df[,.(Start = min(DateTime), 
     End = max(DateTime), 
     Min = min(Value), 
     Max = max(Value), 
     Median = median(Value), 
     Span = difftime(max(DateTime), min(DateTime), "h")), 
    by = "Grp"] 
# Grp    Start     End Min Max Median Span 
# 1: 0 1954-10-07 00:00:00 1954-10-07 04:00:00 0.10 0.2 0.100 4 hours 
# 2: 1 1954-10-07 13:00:00 1954-10-07 15:00:00 0.02 1.1 0.200 2 hours 
# 3: 2 1954-10-11 09:00:00 1954-10-11 11:00:00 0.20 0.4 0.300 2 hours 
# 4: 3 1954-10-12 23:00:00 1954-10-13 00:00:00 0.05 0.1 0.075 1 hours 

  • setDT(df)[,DateTime := as.POSIXct(... преобразует df в data.table и преобразует DateTime столбец POSIXct
  • df[, Grp := cumsum(c(0, difftime(... создает группировку идентификаторов на основе описанное выше, то есть когда DateTime[i] - DateTime[i - 1] больше 6 часов, начинается новая группировка
  • df[,.(Start = min(DateTime), ... вычисляет агрегаты для каждого Grp
+0

Спасибо! Это замечательно и работает с данными выше, но не с моим большим, реальным набором данных. Кажется, он сокращает время окончания даты начала и окончания, а переменная Span просто говорит «0 секунд» для всего. Может быть, что-то с моим форматированием даты? Я использую 'x $ Date <- as.Date (x $ Date, format ="% m /% d /% Y ")' – kslayerr

+0

Это не будет работать с полем 'Date', потому что этот класс не хранит информацию о часовом компоненте метки времени. Вам нужно будет использовать тип 'POSIXct', поэтому я использую' as.POSIXct (sprintf ("% s: 00", DateTime)) 'выше. – nrussell

+0

А, я вижу. Каков наилучший способ форматирования столбца «Дата» с помощью 'POSITXct', чтобы он не был однозначным форматом? Это ошибка, которую я получаю, если я ее не определяю. Мои даты организованы m/d/y – kslayerr

Смежные вопросы