2016-10-24 2 views
0

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

правила данных:

  1. столбце Состояние содержит только «0» и «1»
  2. тайм-штамп, который hasnt был записан в таблице же с его следующей ближайшей tiemstamp в таблице.
  3. колонна Дата всегда увеличивают по времени :)

Например, простой ввод:

enter image description here

создать данные с кодом ниже:

dd <- data.table(date = c("2015-07-01 00:00:02", "2015-07-01 00:00:04", "2015-07-01 00:00:08"), 
      status = c(0,1,0)) 

выставленный на продажу:

enter image description here

мое решение:

  1. рассчитать разницу во времени для каждых двух строках, а затем сохранить в новой колонке под названием time_diff
  2. вставки новой строки в петле на основе time_diff

он может работать, но проблема заключается в том, что время вычисления слишком велико, так как столько циклов. Я думаю, что может быть простым решением для этого случая

Любой помощи или предложение была бы весьма признателен :)

спасибо!

+0

В вашем описании 7/1/2015 0:00:05 имеет статус 1 , потому что его ближайшая отметка времени равна 0:00:04, и она равна 1. Или это должно быть только шаг за шагом? –

+0

на вопрос, но 7/1/2015 0:00:05 не был записан во входной таблице, а следующая ближайшая временная метка - 7/1/2015 0:00:08 на основе входной таблицы, поэтому 7/1/2015 0:00:05 имеет статус 0 :) – ZAWD

ответ

3

Вот еще одна идея

library(dplyr) 
library(tidyr) 
library(lubridate) 

dd %>% 
    mutate(date = ymd_hms(date)) %>% 
    complete(date = seq(floor_date(min(date), "day"), max(date), 1)) %>% 
    fill(status, .direction = "up") 

Что дает:

## A tibble: 9 × 2 
#     date status 
#    <dttm> <dbl> 
#1 2015-07-01 00:00:00  0 
#2 2015-07-01 00:00:01  0 
#3 2015-07-01 00:00:02  0 
#4 2015-07-01 00:00:03  1 
#5 2015-07-01 00:00:04  1 
#6 2015-07-01 00:00:05  0 
#7 2015-07-01 00:00:06  0 
#8 2015-07-01 00:00:07  0 
#9 2015-07-01 00:00:08  0 
+1

отличное решение, спасибо большое! – ZAWD

1

Один из способов сделать это быстрее, чтобы использовать zoo и merge два временных рядов (as shown in the SO answer):

  1. Первый построенный из ваших данных.
  2. Второй - это временный ряд с наблюдениями, которые начинаются и заканчиваются по вашему желанию.

Затем заполните NA с помощью слияния, используя na.locf. В коде:

## first convert your date column to date-time 
dd$date <- as.POSIXct(dd$date,format="%Y-%m-%d %H:%M:%S") 
## set dd as data frame 
setDF(dd) 
library(zoo) 
## construct zoo time series for your data 
dd.zoo <- zoo(dd[,-1],dd[,1]) 
## do the merge and use `na.locf` to fill in the NA's 
output <- na.locf(merge(dd.zoo, 
         zoo(,seq(as.POSIXct("2015-07-01 00:00:00",format="%Y-%m-%d %H:%M:%S"), 
           end(dd.zoo),by="sec")), all=TRUE), 
        fromLast=TRUE) 

Здесь, начало и конец временного ряда слиться является 2015-07-01 00:00:00 до конца ваших данных с помощью секунд. В общем, вы можете указать любые два момента времени. merge использует all=TRUE для выполнения внешнего соединения, где все наблюдения объединены в выход. Те, кто не находится в исходных данных, будут заполнены NA. Наконец, используйте na.locf с fromLast=TRUE, чтобы заменить NA с последним номером NA назад от последнего наблюдения.

Использование данных с dd преобразуется в кадр данных:

print(output) 
##2015-07-01 00:00:00 2015-07-01 00:00:01 2015-07-01 00:00:02 2015-07-01 00:00:03 
##     0     0     0     1 
##2015-07-01 00:00:04 2015-07-01 00:00:05 2015-07-01 00:00:06 2015-07-01 00:00:07 
##     1     0     0     0 
##2015-07-01 00:00:08 
##     0 

Обратите внимание, что output представляет собой серию zoo. Для того, чтобы преобразовать обратно в data.table:

output <- data.table(date=index(output),status=as.data.frame(output)$output) 
##     date status 
##1: 2015-07-01 00:00:00  0 
##2: 2015-07-01 00:00:01  0 
##3: 2015-07-01 00:00:02  0 
##4: 2015-07-01 00:00:03  1 
##5: 2015-07-01 00:00:04  1 
##6: 2015-07-01 00:00:05  0 
##7: 2015-07-01 00:00:06  0 
##8: 2015-07-01 00:00:07  0 
##9: 2015-07-01 00:00:08  0 
+0

привет, спасибо за ответ, но у меня есть ошибка: Ошибка в seq.POSIXt (as.POSIXct ("2015-07-01 00:00: 00 ", format ="% Y-% m-% d% H:% M:% S "),: 'to' должен быть объектом" POSIXt " – ZAWD

+0

@ZAWD: см. Мое редактирование, вам необходимо преобразовать данные в кадр данных. – aichao

+0

Привет, решил проблему :) Большое вам спасибо за подробное описание – ZAWD

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