基于索引值(时间点)而非观察次数R的时间序列数据帧滚动子集
我有一个带有一个时间刻度和多个时间序列的数据帧。我想以动态滚动的方式将其子集,窗口宽度设置为10年。因为时间序列不是等距采样的,所以窗口中的行数会随着数据帧的滚动而变化。 计算应基于时间值,而不是观察次数 例如,在以下data.frame中:基于索引值(时间点)而非观察次数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
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