关于时间序列:为hts字符参数R创建正确的输入名称

Create proper input names for the hts character argument R

这个问题与hts包不是必需的,但是其动机来自于需要在hts包中的列名称中指定层次结构(函数hts参数"字符")

原始数据:

1
2
3
4
5
library(data.table)
Original<-data.table(column_names=c("12_2985_40_4025","12_2986_26_4027",
         "12_3385_17_4863","48_2570_433_3376"))
Original[,nchar:=nchar(column_names)]
Original

原版的

1
2
3
4
5
              names nchar
1:  12_2985_40_4025    15
2:  12_2986_26_4027    15
3:  12_3385_17_4863    15
4: 48_2570_433_3376    16

请注意,每行由一个按层次结构构建的单个时间序列的4个粘贴标签组成,例如Original$names[1]:"12_2985_40_4025,是类型为" 12",子类型为" 2985",子子类型为" 40"且唯一的时间序列标识符" 4025"

原始数据层次结构的图示:

enter image description here
character参数要求:

Integers indicate the segments in which the bottom level names can be
read in order to construct the corresponding node structure and its
labels. For instance, suppose one of the bottom series is named
"VICMelb" referring to the city of Melbourne within the state of
Victoria. Then characters would be specified as c(3, 4) referring to
states of 3 characters (e.g.,"VIC") and cities of 4 characters (e.g.,
"Melb") All the bottom names must be of the same length, with number
of characters for each segment the same for all series.

因此,我需要将"原始"格式转换为"必需"格式,因此我可以将其进一步输入到hts对象中,注意我添加了" l"(可以是任何字符)以创建相同的长度到所有子子级别:

1
2
3
4
required<-data.table(names=c("12_2985_40l_4025","12_2986_26l_4027",
                            "12_3385_17l_4863","48_2570_433_3376"))
required[,nchar:=nchar(names)]
required

需要

1
2
3
4
5
              names nchar
1: 12_2985_40l_4025    16
2: 12_2986_26l_4027    16
3: 12_3385_17l_4863    16
4: 48_2570_433_3376    16

因此,现在hts中的以下代码将起作用,因为每个"名称"将被分成4个级别的长度:3,5,4,4(包括下划线):

1
2
3
4
5
6
library(hts)
abc <- ts(5 + matrix(sort(rnorm(1000)), ncol = 4, nrow = 100))
colnames(abc) <- required$names
y <- hts(abc, characters=c(3,5,4,4)) #this would work after properly fixing
Alert_forecast <- forecast(y, h=10, method="comb")
plot(Alert_forecast, include=10)

我虽然的一般解决方案:
(尽管我真的没有设法将其正确地表达为代码,但绝对不是一个优雅的方法)
为了将其转换为正确的格式,我想到了先查找所有4个级别中的最大值(针对"名称"的所有值),然后对所有"名称"运行一个循环并将每个级别拆分为一个循环,如果它的级别短于其级别粘贴必要的ll的长度,因此它将具有与其等效级别中的所有其他TS相同的名称长度。


这是尝试使用stringi包解决此问题的尝试

1
2
3
4
5
6
7
library(data.table) #V 1.9.6+
library(stringi)
Original[, tstrsplit(column_names,"_", fixed = TRUE)
         ][, lapply(.SD, function(x) stri_pad_right(x, max(nchar(x)),"l"))
           ][, do.call(paste, c(sep ="_", .SD))]

## [1]"12_2985_40l_4025""12_2986_26l_4027""12_3385_17l_4863""48_2570_433_3376"

这里的想法是:用_拆分>找到每列的最大长度>将l s填充为较短的值>用_分隔符将所有内容组合回去。