如何按行在data.table中添加时间序列对象(ts)?

Gui*_*pos 5 r time-series data.table

我试图逐行存储ts对象.用于创建时间序列的月度数据(1980年和1981年的24个月值)在DT中按行顺序存储,因此我只想在DT中添加一列来存储每行的"ts"对象() .这是一个可重复的例子,我尝试了三种不同的选项,但它们似乎都没有像我预期的那样工作.

library(data.table)
DT <- data.table(ID=seq(1:10),
                 JAN_1980=rnorm(1:10),FEB_1980=rnorm(1:10),MAR_1980=rnorm(1:10),APR_1980=rnorm(1:10),MAY_1980=rnorm(1:10),JUN_1980=rnorm(1:10),JUL_1980=rnorm(1:10),AUG_1980=rnorm(1:10),SEP_1980=rnorm(1:10),OCT_1980=rnorm(1:10),NOV_1980=rnorm(1:10),DEC_1980=rnorm(1:10),JAN_1981=rnorm(1:10),FEB_1981=rnorm(1:10),MAR_1981=rnorm(1:10),APR_1981=rnorm(1:10),MAY_1981=rnorm(1:10),JUN_1981=rnorm(1:10),JUL_1981=rnorm(1:10),AUG_1981=rnorm(1:10),SEP_1981=rnorm(1:10),OCT_1981=rnorm(1:10),NOV_1981=rnorm(1:10),DEC_1981=rnorm(1:10))

# First attempt
DT[,TS_COL:=ts(.SD[,2:25,with=FALSE], start=c(1980,1), frequency=12)]

# Second
DT[,TS_COL:=ts(unlist(.SD[,2:25,with=FALSE]), start=c(1980,1), frequency=12)]

# Third
DT[,TS_COL:=list(list(list(ts(unlist(.SD[,2:25,with=FALSE]), start=c(1980,1), frequency=12))))]
Run Code Online (Sandbox Code Playgroud)

我希望能够以这种方式访问​​特定行的ts对象(还没有运气):

DT[1,TS_COL]
Run Code Online (Sandbox Code Playgroud)

...得到类似的东西(2年的月度数据):

             Jan         Feb         Mar         Apr         May         Jun         Jul         Aug         Sep         Oct         Nov         Dec
1980  2.13303849  0.74954206 -0.45112504  2.13558888  1.11883498 -0.39074470  1.77374480 -0.19513901  0.49920019 -1.12875185  0.45598049  1.97730211
1981  0.62764761 -0.86330094 -0.51585664  0.59677770 -0.71073980 -0.26208961 -0.38833227  1.39841244 -1.50490225 -0.72018921  1.06684672  0.07126184
Run Code Online (Sandbox Code Playgroud)

有关如何实现这一点的任何提示?

Mat*_*wle 8

我不记得曾经使用过ts()自己.我倾向于有不规则的时间序列存储长格式.单独的日期时间列,或单独的日期列和时间列(用于滚动到一天内的主要观察但不是前一天).然后我创建一个规则间隔的时间序列并将其连接到数据,或者使用which和找到窗口的开头和结尾,roll然后提取该窗口的子集.

那就是说,让我们试试吧ts().

请在您的问题中包含错误或警告消息.请参阅" 支持"页面上的 6项和第7项.你的例子不可复制; 即我得到以下警告,但你可能会得到一个不同的警告(你没有包含它,所以没有什么可以尝试重现).这个示例都不是最小的,因为我们不需要20个包围控制台输出的列.

DT[,TS_COL:=ts(.SD[,2:25,with=FALSE], start=c(1980,1), frequency=12)]
# Warning messages:
# 1: In `[.data.table`(DT, , `:=`(TS_COL, ts(.SD[, 2:25, with = FALSE],  :
# 24 column matrix RHS of := will be treated as one vector
# 2: In `[.data.table`(DT, , `:=`(TS_COL, ts(.SD[, 2:25, with = FALSE],  :
#  Supplied 240 items to be assigned to 10 items of column 'TS_COL' (230 unused)
Run Code Online (Sandbox Code Playgroud)

首先,让我们看一下手册. ?ts包含以下签名:

ts(data = NA,start = 1,end = numeric(),frequency = 1,deltat = 1,ts.eps = getOption("ts.eps"),class =,names =)

你正在使用第一个参数,data所以它说:

data:观察到的时间序列值的向量或矩阵.数据帧将通过data.matrix强制转换为数字矩阵.(另请参阅"详细信息".)

由于data.table继承自data.frame,因此它也是data.frame.因此data.table将被强制转换为矩阵.

再往下,我们看到矩阵的一些东西:

在矩阵情况下,假设矩阵数据的每列包含单个(单变量)时间序列.

现在让我们分解问题并检查它试图分配的RHS.只需移除TS_COL:=零件并再次运行即可返回RHS,以便我们查看它.

RHS = DT[,ts(.SD[,2:25,with=FALSE], start=c(1980,1), frequency=12)]
class(RHS)
# [1] "mts"    "ts"     "matrix"
dim(RHS)
# [1] 10 24
dim(DT)
# [1] 10 26
length(RHS)
# [1] 240
storage.mode(RHS)
# [1] "double"
Run Code Online (Sandbox Code Playgroud)

所以这是一个矩阵.而且更糟糕的是,double而不是integer.(回想一下,我们不喜欢Date在base中使用data.table,因为,奇怪的Date是,double而不是integer.)

您不能将矩阵存储为data.table中的列.data.table将矩阵视为内部的向量,警告消息(在本答案中如上所示)暗指.以下是警告信息:

24 column matrix RHS of := will be treated as one vector
Supplied 240 items to be assigned to 10 items of column 'TS_COL' (230 unused)
Run Code Online (Sandbox Code Playgroud)

这些警告是由data.table代码创建的,我认为非常好.

因此,如果您要继续使用ts()该类作为data.table列,那么您需要将矩阵强制为24列(24个向量,所有10个长)而不是24列的矩阵(内部一个向量240)长).

但在这一点上,似乎ts()班级不适合这项工作.你真的需要做什么?最好备份并描述更大的图景.