Как вставлять новые строки для отсутствующих данных с интервалами, которые могут отличаться на несколько минут в R

#r #time-series

Вопрос:

Я хотел бы вставлять строки, когда в наборе данных датчика глюкозы с интервалом в 5 минут отсутствуют данные. Мне удалось выполнить это с помощью пакета tsibble, но в данных могут быть временные сдвиги, например, датчик записывает значение в 4 минуты вместо 5. Это приводит к тому, что вставленные метки времени становятся несинхронизированными на протяжении оставшейся части кадра данных.

Есть ли способ выполнить это за промежуток времени, который должен составлять 5 минут, но может составлять от 4 до 6 минут? Набор данных также включает в себя несколько различных идентификаторов.

Конечная цель состоит в том, чтобы заполнить недостающие пробелы в данных на основе заданных критериев (т. е. Максимальное заполнение

Репрекс наклеен ниже.

 library(tsibble, warn.conflicts = FALSE) #gt; Warning: package 'tsibble' was built under R version 4.1.1  Data lt;- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), gl = c(125L, 133L, 132L, 130L, 133L, 135L, 166L, 161L, 67L, 66L, 67L, 69L, 67L),  time = structure(list(sec = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),  min = c(42L, 47L, 51L, 56L, 6L, 11L, 11L, 16L, 2L, 17L, 22L, 27L, 32L),  hour = c(9L, 9L, 9L, 9L, 10L, 10L, 11L, 11L, 0L, 0L, 0L, 0L, 0L),  mday = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L),  mon = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L),  year = c(121L, 121L, 121L, 121L, 121L, 121L, 121L, 121L, 121L, 121L, 121L, 121L,121L),  wday = c(6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 0L, 0L, 0L, 0L,0L),  yday = c(92L, 92L, 92L, 92L, 92L, 92L, 92L, 92L, 93L, 93L,93L, 93L, 93L),  isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L, 0L, 0L)),  class = c("POSIXlt", "POSIXt"), tzone = "GMT"),  dif = structure(c(NA, 5, 4, 5, 10, 5, 60, 5, NA, 15, 5, 5, 5),  units = "mins", class = "difftime")),  class = c("grouped_df", "tbl_df", "tbl", "data.frame"),  row.names = c(NA, -13L), groups = structure(list(id = 1:2, .rows = structure(list(1:8, 9:13),  ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))),  class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -2L), .drop = TRUE))  x lt;- new_interval(minute = 5)  tsdata lt;- build_tsibble(Data, key = id, index = time, interval = x) tsdata lt;- fill_gaps(tsdata, .full = FALSE)   

Ответ №1:

Вероятно, это не окончательный ответ на то, что вы ищете, но это может помочь вам начать получать то, что вы хотите..

 library(data.table) library(zoo) # Split to list by id L lt;- split(DT, by = "id") # Interpolate gl based on time ans lt;- lapply(L, function(x) {  # build time series by minute  temp lt;- data.table::data.table(  id = unique(x$id),   time = seq(min(x$time), max(x$time), by = 60))  # join in measured data  temp[x, gl_measured := i.gl, on = .(time)]  # imterpolate gl-values  temp[, gl_approx := zoo::na.approx(gl_measured)]  }) # Bind list together again final lt;- data.table::rbindlist(ans)