基于索引值(时间点)而非观察次数R的时间序列数据帧滚动子集

基于索引值(时间点)而非观察次数R的时间序列数据帧滚动子集,r,time-series,subset,rolling-computation,R,Time Series,Subset,Rolling Computation,我有一个带有一个时间刻度和多个时间序列的数据帧。我想以动态滚动的方式将其子集,窗口宽度设置为10年。因为时间序列不是等距采样的,所以窗口中的行数会随着数据帧的滚动而变化。 计算应基于时间值,而不是观察次数 例如,在以下data.frame中: time var1 var2 5262 -8.981 -0.011 5263.2 -8.993 -0.012 5264.4 -8.978 0.015 5265.6 -9.169 -0.191 5266.8 -8.897

我有一个带有一个时间刻度和多个时间序列的数据帧。我想以动态滚动的方式将其子集,窗口宽度设置为10年。因为时间序列不是等距采样的,所以窗口中的行数会随着数据帧的滚动而变化。 计算应基于时间值,而不是观察次数

例如,在以下data.frame中:

time    var1    var2
5262    -8.981  -0.011
5263.2  -8.993  -0.012
5264.4  -8.978  0.015
5265.6  -9.169  -0.191
5266.8  -8.897  0.272
5268    -9.024  -0.127
5269.2  -8.996  0.028
5270.46 -8.979  0.017
5271.84 -9.004  -0.025
5273.22 -9.01   -0.006
5274.6  -9.106  -0.096
5275.98 -8.971  0.135
5277.36 -8.996  -0.025
5278.74 -8.956  0.04
5280.12 -8.981  -0.025
5281.5  -8.982  -0.001
5282.88 -9.042  -0.06
5284.26 -9.091  -0.049
5285.64 -9.066  0.025
5287.02 -9.03   0.036
5288.4  -9.031  -0.001
5289.78 -9.028  0.003
5291.16 -9.164  -0.136
5294.72 -9.034  0.13
5297.3  -9.296  -0.262
5299.88 -9.097  0.199
5302.46 -8.995  0.102
5305.04 -9.084  -0.089
5307.62 -9.047  0.037
5310.2  -9.066  -0.019
5312.78 -9.07   -0.004
5315.36 -9  0.07
5317.94 -9.057  -0.057
5320.52 -9.219  -0.162
5323.1  -9.084  0.135
5325.68 -9.034  0.05
5328.26 -9.147  -0.113
5330.84 -9.169  -0.022
5333.42 -9.143  0.026
5336    -9.211  -0.068
5338.58 -9.061  0.15
5341.16 -9.1    -0.039
5343.74 -9.094  0.006
5346.32 -9.104  -0.01
5348.9  -9.089  0.015
5351.48 -9.127  -0.038
5354.06 -8.973  0.154
5356.64 -9.009  -0.036
5359.22 -8.966  0.043
5361.8  -8.996  -0.03
5364.38 -8.877  0.119
5366.96 -8.962  -0.085
5369.54 -8.902  0.06
5372.12 -8.915  -0.013
5374.7  -8.913  0.002
5377.28 -8.834  0.079
5379.86 -8.91   -0.076
5382.44 -8.742  0.168
5385.02 -8.877  -0.135
5387.6  -8.743  0.134
5390.18 -8.898  -0.155
5392.76 -8.77   0.128
5395.34 -8.97   -0.2
5397.92 -8.849  0.121
5400.5  -8.846  0.003
5403.08 -8.865  -0.019
5405.66 -8.865  0
5408.24 -8.876  -0.011
5410.82 -8.775  0.101
5413.4  -8.842  -0.067
5415.98 -8.821  0.021
5418.56 -8.85   -0.029
我之前所做的是对df进行子集设置,但使用以下代码参考行数并执行线性回归

data.column=2
time.column=1
length=dim(data)[1] 
window=10
adj_r_sqr=matrix(0,nrow=length,length(window_vekt))
colnames(adj_r_sqr)=window


    for(i in 1:(length-window)){
        x=data[i:(i+window),time.column]
        y=data[i:(i+window),data.column]  
        lmodel=lm(y~x)
        adj_r_sqr[i+floor(window/2)-1),which(window_vekt==window)]=summary(lmodel)$adj.r.squared}
但这并不能解释时间间隔的变化

我需要的是一个调整,根据第一列筛选数据帧,并在滚动中对其进行子集,以便子集覆盖所选窗口,如果该窗口中的行数小于5,则给出NA。 另一个问题可能是对数据进行子集,但不是滚动,而是再次使用时间变量以拼接的方式

以前我不仅设法提取了adj。r2,但p值和其他坡度也使用:

RMSE=sqrt(mean((summary(lmodel)$residuals)^2))
p_val_y=summary(lmodel)$coefficients[2,4]
p_val_intercept=summary(lmodel)$coefficients[1,4]
slope=coeff[i+summary(lmodel)$coefficients[2,1]
但对于旧的窗口,不幸的是,由于我的无能,我无法在@Uwe建议的查询中实现这些

可在以下链接上找到测试数据集:

滚动窗口 这可以通过聚合非等联接来解决,非等联接聚合了覆盖给定时间段的不同数量的行

library(data.table)
# define parameters
time_1 <- -10
time_2 <- 10
n_min <- 5L
# create helper columns
setDT(dat)[, `:=`(join = time, start = time + time_1, end = time + time_2)][
  # non-equi join and aggregate 
  dat, on = .(join >= start, join <= end), by = .EACHI, {
    lmodel <- lm(var1 ~ time)
    lsumm <- summary(lmodel)
    .(time = i.time, 
      N = .N, 
      adj_r_sqr = lsumm$adj.r.squared,
      RMSE = sqrt(mean(lsumm$residuals^2)),
      p_val_y = if (.N > 1) lsumm$coefficients[2,4] else NA_real_,
      p_val_intercept = lsumm$coefficients[1,4],
      slope = coef(lmodel)[2]
    )
  }]

编辑:OP已将发布到另一个样本数据集,该样本数据集遇到错误。原因是某些组大小太小,仅包含一个数据点,因此线性模型没有斜率

代码的更新版本捕获了这种情况,并防止了越界错误


前两列显示所涵盖的年份范围;如果不再需要,可以将其移除

N
是计算
lm()
时包含的行数。如果
N<5
,OP已请求返回
NA
。之后也可以这样做

# define parameters
time_1 <- -10
time_2 <- 10
n_min <- 5L
# coerce to data.table
result <- setDT(dat)[
  # create helper columns
  , `:=`(join = time, start = time + time_1, end = time + time_2)][
    # non-equi join and aggregate each interval 
    dat, on = .(join >= start, join <= end), by = .EACHI, {
      # do computations within interval
      lmodel <- lm(var1 ~ time)
      lsumm <- summary(lmodel)
      # create list of results, finally
      .(time = i.time, 
        N = .N, 
        adj_r_sqr = lsumm$adj.r.squared,
        RMSE = sqrt(mean(lsumm$residuals^2)),
        p_val_y = if (.N > 1) lsumm$coefficients[2,4] else NA_real_,
        p_val_intercept = lsumm$coefficients[1,4],
        slope = coef(lmodel)[2]
      )
    }]
# clean-up result
computed_cols <- setdiff(names(result), c(names(dat), "N"))
result[
  # remove join columns
  , -(1:2)][
    # put NA if too few data points
    N < n_min, (computed_cols) := NA][]
按固定间隔拆分 OP也要求

另一个问题可能是对数据进行子集划分,但不是在 滚动,而不是使用时间变量以拼接方式再次滚动


请问
窗口的定义是什么?@Uwe它应该只是窗口。事实上,我使用多个窗口选项运行它,并确定了一个向量(window_vect)来执行此操作,但在本例中它是不必要的。我可以“升级”它,以便在之后像那样运行-希望如此。:)@Uwe我添加了代码不幸失败的测试数据,并添加了一些附加注释。谢谢你抽出时间!该文件不包含列标题。这对我有用:
dat@Uwe抱歉,文件错了,它与这一个不兼容,这是我最近上传的扩展版本。它给出了lsumm$系数[2,4]中的错误
error(下标超出范围)
我试图扩展它,不仅提取adj r2,还提取斜率和p值,但您的提取方式对我来说并不熟悉。之前,我在原始帖子中添加了一个代码来引用它们。如果你能把我推荐到一个可以找到查询逻辑的地方,或者只是用一行我可以复制的代码来扩展它,那将非常有用。顺便问一下,是否可以将其放入for循环中,并在多个窗口中运行,因为目前我无法使用函数之外的变量调整时间窗口,例如time_1=-10;时间=10。非常感谢!是否可以以类似的方式不仅滚动而且切片数据…?添加了helper列,但之后两个代码都给出了一个错误:lsumm$系数中的错误[2,4]:下标超出边界。但是,如果我将#p#u val_y=lsumm$系数[2,4]或其他类似的行取出,它会给出:error in
[.data.table
(setDT(dat)[,
:=
(join=time,start=time+:LHS of:=似乎是列位置,但在[1,ncol]之外)范围。只能按名称添加新列。我也尝试了使用其他数据的脚本,但它给出了相同的错误,请在一小时内找到问题的附加集。如果您可以在代码中添加注释,描述哪一行引用了什么任务,我将很乐意尝试帮助解决此问题(当然是重要的一行)因此,我可以阅读相关内容,因为下一步将不仅仅是对片段进行线性建模,而是进行其他任何操作(绘制直方图、计算平均值或断点分析),并将结果提取到矩阵中。使用另一个testdata[最后的清理行没有删除与N对应的所有值
# define parameters
time_1 <- -10
time_2 <- 10
n_min <- 5L
# coerce to data.table
result <- setDT(dat)[
  # create helper columns
  , `:=`(join = time, start = time + time_1, end = time + time_2)][
    # non-equi join and aggregate each interval 
    dat, on = .(join >= start, join <= end), by = .EACHI, {
      # do computations within interval
      lmodel <- lm(var1 ~ time)
      lsumm <- summary(lmodel)
      # create list of results, finally
      .(time = i.time, 
        N = .N, 
        adj_r_sqr = lsumm$adj.r.squared,
        RMSE = sqrt(mean(lsumm$residuals^2)),
        p_val_y = if (.N > 1) lsumm$coefficients[2,4] else NA_real_,
        p_val_intercept = lsumm$coefficients[1,4],
        slope = coef(lmodel)[2]
      )
    }]
# clean-up result
computed_cols <- setdiff(names(result), c(names(dat), "N"))
result[
  # remove join columns
  , -(1:2)][
    # put NA if too few data points
    N < n_min, (computed_cols) := NA][]
       time  N     adj_r_sqr       RMSE     p_val_y p_val_intercept         slope
 1: 5262.00  9 -1.412484e-01 0.06749996 0.923658051      0.76541424  8.050483e-04
 2: 5263.20  9 -1.412484e-01 0.06749996 0.923658051      0.76541424  8.050483e-04
 3: 5264.40 10 -1.248329e-01 0.06411770 0.973340896      0.77035143  2.202740e-04
    ...
70: 5413.40  6 -1.689106e-01 0.03205016 0.626213128      0.38442443  1.915836e-03
71: 5415.98  5 -3.324952e-01 0.03383253 0.968080223      0.75067625  2.325581e-04
72: 5418.56  4            NA         NA          NA              NA            NA
       time  N     adj_r_sqr       RMSE     p_val_y p_val_intercept         slope
# define parameters
n_min <- 5L
t_len <- 20
# create "pretty" breaks 
breaks <- setDT(dat)[, seq(floor(min(time)/t_len)*t_len, max(time) + t_len, t_len)]
dat[, {
  lmodel <- lm(var1 ~ time)
  lsumm <- summary(lmodel)
  .(t_min = min(time),
    t_max = max(time),
    N = .N, 
    adj_r_sqr = lsumm$adj.r.squared,
    RMSE = sqrt(mean(lsumm$residuals^2)),
    p_val_y = if (.N > 1) lsumm$coefficients[2,4] else NA_real_,
    p_val_intercept = lsumm$coefficients[1,4],
    slope = coef(lmodel)[2]
  )
}, by = .(cut(time, breaks))]
                   cut   t_min   t_max  N   adj_r_sqr       RMSE    p_val_y p_val_intercept         slope
1: (5.26e+03,5.28e+03] 5262.00 5278.74 14 -0.08098718 0.06260179 0.87447674      0.52663574  0.0005619086
2:  (5.28e+03,5.3e+03] 5280.12 5299.88 12  0.33144858 0.06512008 0.02934449      0.06866916 -0.0087040163
3:  (5.3e+03,5.32e+03] 5302.46 5317.94  7 -0.19007362 0.03206618 0.84623551      0.69966581 -0.0005675526
4: (5.32e+03,5.34e+03] 5320.52 5338.58  8 -0.16348201 0.06360759 0.90221583      0.62280945  0.0005629384
5: (5.34e+03,5.36e+03] 5341.16 5359.22  8  0.54042068 0.03778046 0.02285248      0.01024298  0.0079272794
6: (5.36e+03,5.38e+03] 5361.80 5379.86  8  0.20369592 0.03803705 0.14585425      0.06090703  0.0043881506
7:  (5.38e+03,5.4e+03] 5382.44 5397.92  7  0.06865351 0.07101868 0.28355300      0.39287969 -0.0073920266
8:  (5.4e+03,5.42e+03] 5400.50 5418.56  8 -0.04065894 0.02837687 0.42672518      0.14267960  0.0016703581