我有一个不规则的时间序列,数据集中存在空白。此外,数据被分组。滞后函数我已经能够通过观察找到滞后(因此他们找到数据集中的先前记录),但我想指定一个时间变量并通过匹配滞后时间计算滞后。这个问题:R lag/lead irregular time series data正在做类似的事情。但是,我无法使用zoo
解决方案(我有某种程序包不兼容,根本无法使用zoo
)并且未能成功地将data.table
解决方案变为某种程度灵活地用作滞后量作为输入的函数和分组数据的容量。
测试数据:
testdf <- data.frame(group = c(1,1,1,1,1,2,2,2,2,2),
counter = c(1,2,3,5,6,7,8,9,11,12),
xval = seq(100, 1000, 100))
lagamount <- 1
输出应为矢量:NA 100 200 NA 400 NA 600 700 NA 900
这就是我现在正在使用的内容:
library(dplyr)
testout <- group_by(testdf, group) %>%
mutate(testout = function(x) which((testdf$counter - x) == lagamount))
这给了我一个数据类型错误,某些东西(未指定)不是矢量。
有没有办法让这个建筑工作?或者,我怎么能滞后于具有分组变量的不规则时间序列?
答案 0 :(得分:4)
在dplyr
内执行此操作的唯一方法是在不使用do
的情况下,首先将隐式缺失值显式化,然后将其过滤掉。
提供一个变异的向量,并使用ifelse
(或者可能是新的dplyr::if_else
)来检查滞后是否是你想要的。例如:
library(tidyr)
lagamount <- 2
testout <- group_by(testdf, group) %>%
complete(group, counter = min(counter):max(counter)) %>%
mutate(testout = if_else(counter - lag(counter, lagamount) == lagamount,
lag(xval, lagamount),
NA_real_)) %>%
filter(!is.na(xval))
产地:
Source: local data frame [10 x 4]
Groups: group [2]
group counter xval testout
<dbl> <dbl> <dbl> <dbl>
1 1 1 100 NA
2 1 2 200 NA
3 1 3 300 100
4 1 5 400 300
5 1 6 500 NA
6 2 7 600 NA
7 2 8 700 NA
8 2 9 800 600
9 2 11 900 800
10 2 12 1000 NA
答案 1 :(得分:0)
当我将上述答案转换为函数时,我最终必须明确地展开扩展并删除if_else中的严格数据类型。这是最终形式。
getlag <- function(timevar, valuevar, laglength){
df1 <- data.frame(counter = timevar, value = valuevar, indf = 1)
alltimes <- data.frame(counter = seq(min(timevar), max(timevar)))
df2 <- merge(alltimes, df1, all.x = TRUE)
df2 <- df2 %>%
mutate(lagvals = ifelse(counter - lag(counter, laglength) == laglength,
lag(value, laglength),
NA_real_)) %>%
filter(!is.na(indf))
return(df2$lagvals)
}
测试用例是:
testout <- group_by(testdf, group) %>%
mutate(testout = getlag(counter, xval, 1))
答案 2 :(得分:0)
现在在 collapse::flag
(以及 fdiff
和 fgrowth
)中提供了一个有效的解决方案。创建数据时需要确保时间变量为整数,否则会在内部转换为因子,在这种情况下消除不规则性。
testdf <- data.frame(group = c(1,1,1,1,1,2,2,2,2,2),
counter = as.integer(c(1,2,3,5,6,7,8,9,11,12)),
xval = seq(100, 1000, 100))
lagamount <- 1
然后我们可以写:
library(collapse)
settransform(testdf, L_xval = flag(xval, lagamount, group, counter))
testdf
#> group counter xval L_xval
#> 1 1 1 100 NA
#> 2 1 2 200 100
#> 3 1 3 300 200
#> 4 1 5 400 NA
#> 5 1 6 500 400
#> 6 2 7 600 NA
#> 7 2 8 700 600
#> 8 2 9 800 700
#> 9 2 11 900 NA
#> 10 2 12 1000 900
由 reprex package (v0.3.0) 于 2021 年 7 月 10 日创建
您还可以选择使用管道生成一系列滞后和超前(或特定滞后/超前订单):
testdf |> gby(group) |> flag(-1:3, counter)
#> group counter F1.xval xval L1.xval L2.xval L3.xval
#> 1 1 1 200 100 NA NA NA
#> 2 1 2 300 200 100 NA NA
#> 3 1 3 NA 300 200 100 NA
#> 4 1 5 500 400 NA 300 200
#> 5 1 6 NA 500 400 NA 300
#> 6 2 7 700 600 NA NA NA
#> 7 2 8 800 700 600 NA NA
#> 8 2 9 NA 800 700 600 NA
#> 9 2 11 1000 900 NA 800 700
#> 10 2 12 NA 1000 900 NA 800
#>
#> Grouped by: group [2 | 5 (0)]
由 reprex package (v0.3.0) 于 2021 年 7 月 10 日创建
或者使用 settransformv
进行就地修改:
settransformv(testdf, "xval", flag, -1:3, group, counter, apply = FALSE)
testdf
#> group counter xval F1.xval L1.xval L2.xval L3.xval
#> 1 1 1 100 200 NA NA NA
#> 2 1 2 200 300 100 NA NA
#> 3 1 3 300 NA 200 100 NA
#> 4 1 5 400 500 NA 300 200
#> 5 1 6 500 NA 400 NA 300
#> 6 2 7 600 700 NA NA NA
#> 7 2 8 700 800 600 NA NA
#> 8 2 9 800 NA 700 600 NA
#> 9 2 11 900 1000 NA 800 700
#> 10 2 12 1000 NA 900 NA 800
由 reprex package (v0.3.0) 于 2021 年 7 月 10 日创建
fdiff
和 fgrowth
的工作方式类似,也支持迭代和计算。您也可以将这些函数应用于不规则的时间序列(没有面板 ID),那么您需要指定 t = counter
。所有函数都可以应用于向量/时间序列、矩阵/xts、数据框/数据表/小标题,如果您正在寻找面向对象的方法,还支持plm面板系列和数据框。
更多信息,请访问:https://sebkrantz.github.io/collapse/reference/time-series-panel-series.html