Для полноты картины, вот решение, которое использует data.table
.
ОП предоставил точки данных для каждого месяца с 2015 по 2017 год. Он не определил день месяца, к которому относятся значения. Кроме того, он не уточнил, какой тип интерполяции он ожидает.
Итак, приведенные данные выглядят следующим образом (только v1
показано для простоты):
Обратите внимание, что месячное значение намеренно было присвоено первому дню месяца.
Существует различных способов для интерполяции данных. Мы рассмотрим два из них.
Кусочно-постоянная интерполяция
Поскольку указывается только одна точка данных в месяц, мы можем смело предположить, что значение является репрезентативным для каждого дня соответствующего месяца:
(нанесено с geom_step()
)
Для интерполяции используется базовая функция R approx()
. approx()
применяется ко всем столбцам значений v1
, v2
, v3
с помощью lapply()
.
Но сначала нам нужно превратить год-месяц в полную дату (включая день). Первый день месяца был выбран сознательно. Теперь точки данных в df1
относятся к датам с 2015-01-01 по 2017-12-01. Обратите внимание, что для 2017-12-31 или 2018-01-01 нет заданного значения.
library(data.table)
library(magrittr)
# create date (assuming the 1st of month)
setDT(df1)[, date := as.IDate(paste(Year, Month, 1, sep = "-"))]
# create sequence of days covering the whole period
ds <- seq(as.IDate("2015-01-01"), as.IDate("2017-12-31"), by = "1 day")
# perform interpolation
cols = c("v1", "v2", "v3")
results <- df1[, c(.(date = ds), lapply(.SD, function(y)
approx(x = date, y = y, xout = ds, method = "constant", rule = 2)$y)),
.SDcols = cols]
results
date v1 v2 v3
1: 2015-01-01 15072.73 2524.102 17596.83
2: 2015-01-02 15072.73 2524.102 17596.83
3: 2015-01-03 15072.73 2524.102 17596.83
4: 2015-01-04 15072.73 2524.102 17596.83
5: 2015-01-05 15072.73 2524.102 17596.83
---
1092: 2017-12-27 17002.14 3328.890 20331.03
1093: 2017-12-28 17002.14 3328.890 20331.03
1094: 2017-12-29 17002.14 3328.890 20331.03
1095: 2017-12-30 17002.14 3328.890 20331.03
1096: 2017-12-31 17002.14 3328.890 20331.03
Указав rule = 2
, approx()
было приказано использовать последние заданные значения (значения на 2017-12-01) для завершения последовательности до 2017-12-31.
Результат может быть нанесен поверх данных точек.
кусочно-линейная интерполяция
Для рисования сегмента линии необходимо указать две точки. Чтобы нарисовать отрезки для 36 интервалов (месяцев), нам нужно 37 точек данных. К сожалению, ОП дала только 36 точек данных. Нам понадобится дополнительная точка данных на 2018-01-01, чтобы нарисовать линию за последний месяц.
Один из вариантов в этом случае - предположить, что значения за последний месяц являются постоянными. Это то, что approx()
делает, когда указаны method = "linear"
и rule = 2
.
library(data.table)
library(magrittr)
# create date (assuming the 1st of month)
setDT(df1)[, date := as.IDate(paste(Year, Month, 1, sep = "-"))]
# create sequence of days covering the whole period
ds <- seq(as.IDate("2015-01-01"), as.IDate("2017-12-31"), by = "1 day")
# perform interpolation
cols = c("v1", "v2", "v3")
results <- df1[, c(.(date = ds), lapply(.SD, function(y)
approx(x = date, y = y, xout = ds, method = "linear", rule = 2)$y)),
.SDcols = cols]
results
date v1 v2 v3
1: 2015-01-01 15072.73 2524.102 17596.83
2: 2015-01-02 15078.43 2526.462 17604.89
3: 2015-01-03 15084.14 2528.822 17612.96
4: 2015-01-04 15089.84 2531.182 17621.02
5: 2015-01-05 15095.54 2533.542 17629.08
---
1092: 2017-12-27 17002.14 3328.890 20331.03
1093: 2017-12-28 17002.14 3328.890 20331.03
1094: 2017-12-29 17002.14 3328.890 20331.03
1095: 2017-12-30 17002.14 3328.890 20331.03
1096: 2017-12-31 17002.14 3328.890 20331.03
В образце набора данных значения на 2016 и 2017 годы довольно плоские. В любом случае, постоянная интерполяция за последний месяц не бросается в глаза.