Экстраполировать с группами по другому столбцу - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть куча данных временных рядов, и я хочу применить процентное изменение от одного до конца другого, по группам. У меня есть упрощенный пример ниже, но я должен сделать это для сотен пар временных рядов.

Пока это моя лучшая попытка, но она рассчитывает только одно значение, а остальные * NA 's

dplyr::mutate(dummydata, newtimeseries = ifelse(date > date_to_start_interp, dplyr::lag(value_to_interp, 1) * (value_to_use/ dplyr::lag(value_to_use, 1)), value_to_interp))

Переменные: category: группирующая переменная для набора наблюдений date: дата наблюдений value_to_interp: значения, которые необходимо экстраполировать value_to_use: значения, которые я хочу использовать для экстраполяции (опять же, используя процентное изменение периода к периоду) date_to_start_interp: дата начала экстраполяции (ПРИМЕЧАНИЕ: в некоторых случаях я хочу перезаписать данные в столбце value_to_interp, поэтому эта дата важна)

Данные:

dummydata <- structure(list(category = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L), .Label = c("A", "B"), class = "factor"), date = structure(c(14610, 
14641, 14669, 14700, 14730, 14761, 14791, 14822, 14853, 14883, 
14914, 14944, 14610, 14641, 14669, 14700, 14730, 14761, 14791, 
14822, 14853, 14883, 14914, 14944), class = "Date"), value_to_interp = c(1, 
2, 3, 4, 5, 6, 7, 8, 9, 10, NA, NA, 2, 4, 6, 8, 10, 12, 18, NA, 
NA, NA, NA, NA), value_to_use = c(5, 10, 15, 20, 25, 30, 35, 
40, 45, 50, 55, 60, 100, 95, 105, 90, 110, 85, 115, 80, 120, 
75, 125, 70), date_to_start_interp = structure(c(14914, 14914, 
14914, 14914, 14914, 14914, 14914, 14914, 14914, 14914, 14914, 
14914, 14761, 14761, 14761, 14761, 14761, 14761, 14761, 14761, 
14761, 14761, 14761, 14761), class = "Date")), row.names = c(NA, 
-24L), class = c("tbl_df", "tbl", "data.frame"))


#DESIRED OUTCOME

dummydata_desiredoutcome <- structure(list(category = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L), .Label = c("A", "B"), class = "factor"), date = structure(c(14610, 
14641, 14669, 14700, 14730, 14761, 14791, 14822, 14853, 14883, 
14914, 14944, 14610, 14641, 14669, 14700, 14730, 14761, 14791, 
14822, 14853, 14883, 14914, 14944), class = "Date"), value_to_interp = c(10, 
11, 12, 13, 14, 15, 16, 17, 18, 19, 20.9, 22.8, 1, 2, 3, 4, 5, 
3.863636364, 5.227272727, 3.636363636, 5.454545455, 3.409090909, 
5.681818182, 3.181818182), value_to_use = c(5L, 10L, 15L, 20L, 
25L, 30L, 35L, 40L, 45L, 50L, 55L, 60L, 100L, 95L, 105L, 90L, 
110L, 85L, 115L, 80L, 120L, 75L, 125L, 70L), date_to_start_interp = structure(c(14914, 
14914, 14914, 14914, 14914, 14914, 14914, 14914, 14914, 14914, 
14914, 14914, 14761, 14761, 14761, 14761, 14761, 14761, 14761, 
14761, 14761, 14761, 14761, 14761), class = "Date")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -24L))

Спасибо!

1 Ответ

0 голосов
/ 06 февраля 2020

Почти наверняка есть лучший способ сделать это, но я создал отдельный df, который отфильтровал наблюдения, которые нужно экстраполировать:

dummydata_extrapolateforward <- dplyr::filter(dummydata, date >= date_to_start_interp)

Поскольку я использовал >= в приведенном выше filter у меня было несколько групп с одним наблюдением, которое я хотел экстраполировать, используя несколько других наблюдений.

Итак, я использовал функции first() и last() из dplyr создать кумулятивное вычисление процентного изменения, которое затем будет применено к первому наблюдению.

dplyr::mutate(value_to_interp = dplyr::first(value_to_interp) * value_to_use / dplyr::first(value_to_use))

Затем я просто сделал еще один filter(), чтобы вывести те же наблюдения из основного df и сделал rbind() для рекомбинации.

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

TL; DR: dplyr() имеет функцию под названием first(), которую вы можно использовать, чтобы найти первое наблюдение каждой группы. Получив это, вы можете рассчитать совокупное процентное изменение на основе данных, которые вы используете для экстраполяции, и применить их к точке данных, которую вы хотите экстраполировать.

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