R - преобразование (период) длинноформатных временных рядов в широкоформатные часовые. - PullRequest
0 голосов
/ 07 мая 2018

Я хотел бы преобразовать следующий фрейм данных в широкоформатные часовые серии с нулевым заполнением, если значение отсутствует. По сути, я хочу преобразовать фрейм данных с начальным / конечным периодом в часовую серию:

   structure(list(AffectedAssetMask = structure(c(1L, 1L, 2L, 3L, 
    3L, 3L, 4L, 5L, 5L, 5L, 5L, 5L, 5L), .Label = c("A_1", "A_2", 
    "A_3", "A_4", "A_5"), class = "factor"), EventStart = structure(c(1525737600, 
    1525723200, 1525982400, 1525694400, 1525651200, 1525636800, 1525723200, 
    1525662000, 1525658400, 1525654800, 1525651200, 1525662000, 1525662000
    ), class = c("POSIXct", "POSIXt"), tzone = "Europe/Rome"), EventStop = structure(c(1525748399, 
    1525737599, 1526155199, 1525723199, 1525694399, 1525651199, 1525809599, 
    1525665599, 1525661999, 1525658399, 1525654799, 1525665599, 1525665599
    ), class = c("POSIXct", "POSIXt"), tzone = "Europe/Rome"), UnavailableCapacity = c(150.95, 
    154.742, 115, 172.342, 198.163, 172.342, 115, 197, 281, 330, 
    340, 197, 197)), row.names = c(NA, -13L), class = "data.frame")

выход:

AffectedAssetMask EventStart EventStop UnavailableCapacity
A_1 2018-05-08 02:00:00 2018-05-08 04:59:59 150.950
A_1 2018-05-07 22:00:00 2018-05-08 01:59:59 54.742
A_2 2018-05-10 22:00:00 2018-05-12 21:59:59 115.000
A_3 2018-05-07 14:00:00 2018-05-07 21:59:59 172.342
A_3 2018-05-07 02:00:00 2018-05-07 13:59:59 198.163
A_3 2018-05-06 22:00:00 2018-05-07 01:59:59 172.342
A_4 2018-05-07 22:00:00 2018-05-08 21:59:59 115.000
A_5 2018-05-07 05:00:00 2018-05-07 05:59:59 197.000
A_5 2018-05-07 04:00:00 2018-05-07 04:59:59 281.000
A_5 2018-05-07 03:00:00 2018-05-07 03:59:59 330.000
A_5 2018-05-07 02:00:00 2018-05-07 02:59:59 340.000
A_5 2018-05-07 05:00:00 2018-05-07 05:59:59 197.000
A_5 2018-05-07 05:00:00 2018-05-07 05:59:59 197.000

Последние две записи не являются моей ошибкой, но иногда данные содержат двойные записи с одинаковым значением, но я думаю, что с помощью "уникального" я должен иметь возможность отфильтровать их.

больше информации о данных:

> str(df1)
'data.frame':   13 obs. of  4 variables:
 $ AffectedAssetMask  : Factor w/ 5 levels "A_1","A_2","A_3",..: 1 1 2 3 3 3 4 5 5 5 ...
 $ EventStart         : POSIXct, format: "2018-05-08 02:00:00" "2018-05-07 22:00:00" "2018-05-10 22:00:00" "2018-05-07 14:00:00" ...
 $ EventStop          : POSIXct, format: "2018-05-08 04:59:59" "2018-05-08 01:59:59" "2018-05-12 21:59:59" "2018-05-07 21:59:59" ...
 $ UnavailableCapacity: num  151 155 115 172 198 ...

Мне нужны данные в широкоформатном стиле, и вместо того, чтобы период EventStart / EventStop представлял собой почасовой индекс с одинаковым значением для каждого часа, и если он не содержит ноль в качестве значения.

Чтобы преобразовать его в широкий формат:

library(reshape2)

#cast long-format data into wide-format
dcast(df1,  EventStart + EventStop ~ AffectedAssetMask, value.var = "UnavailableCapacity", fun.aggregate = mean)

Формат в порядке, но вместо EventStart / EventStop мне нужна ежечасная непрерывная серия с нулем в качестве «заливки».

Я могу создать пустой фрейм данных в желаемом формате:

  startPeriod<-as.POSIXct(strptime("01/05/2018 00:00:00", "%d/%m/%Y %H:%M:%S"))
  endPeriod<-as.POSIXct(strptime("30/05/2018 00:00:00", "%d/%m/%Y %H:%M:%S"))
  #create monthly hourly sequence
  dataseq <- seq(startPeriod,endPeriod,by = 3600)
  list<-unique(df1$AffectedAssetMask)
  NROW<-as.numeric(length(dataseq))
  OverallDataFrame<-as.data.frame(matrix(0,NROW,length(list)))
  names(OverallDataFrame)<-list
  rownames(OverallDataFrame) <- dataseq

Целевая таблица вывода должна выглядеть примерно так:

                      A_1 A_2 A_3     A_4 A_5
2018-05-06 18:00:00   0   0   0       0   0
2018-05-06 19:00:00   0   0   0       0   0
2018-05-06 20:00:00   0   0   0       0   0
2018-05-06 21:00:00   0   0   0       0   0
2018-05-06 22:00:00   0   0 172.342   0   0
2018-05-06 23:00:00   0   0 172.342   0   0
2018-05-06 00:00:00   0   0 172.342   0   0
2018-05-07 01:00:00   0   0 172.342   0   0
2018-05-07 02:00:00   0   0 198.163  340  0
2018-05-07 03:00:00   0   0 198.163   0   330
2018-05-07 04:00:00   0   0 198.163   0   281
2018-05-07 05:00:00   0   0 198.163   0   197

CSV-файл, из которого поступают данные, составляет около 8-9 мегабайт, цикл for занимает слишком много времени. Некоторые люди предлагают fuzzyjoin и fuzzy_left_join с параметром «match_fun», другие - функцию, чтобы проверить, находится ли индекс в интервале, к сожалению, я немного потерян.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...