首页 > 解决方案 > 通过另一列用组推断

问题描述

我有一堆时间序列数据,我想按组应用从一个到另一个结尾的百分比变化。我在下面有一个简化的示例,但我必须为数百个时间序列对执行此操作。

这是我迄今为止最好的尝试,但它只计算一个值,其余NA的是

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))

谢谢!

标签: r

解决方案


几乎可以肯定有一种更好的方法可以做到这一点,但我创建了一个单独的 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(),你可以用它来查找每个组的第一个观察值。一旦你有了它,你就可以从你用来外推的数据中计算出累积百分比变化,并将其应用于你想要外推的数据点。


推荐阅读