为 hts 字符参数 R 创建正确的输入名称

Create proper input names for the hts character argument R

这个问题与 hts 包没有必要相关,但它的动机是由于需要在 hts 包的列名中指定层次结构(函数 hts 参数 "characters")

原始数据:

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

原创

              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”

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

字符参数要求:

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.

所以我需要将"Original"格式转换成"required"格式,所以我可以进一步将它输入到一个hts对象中,注意到我已经添加了"l" (可以是任何字符)以便为所有子子级别创建相同的长度:

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

需要

              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 的以下代码可以工作,因为每个 "names" 将被分成 4 个长度级别:3,5,4,4(包括下划线):

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 个级别的最大值(对于 "names" 的所有值),然后 运行 遍历所有 "names" 并拆分循环中的每个级别,如果它的级别比它的级别短,则粘贴必要的 ll's,这样它将与等效级别中的所有其他 TS 具有相同的名称长度。

尝试使用 stringi

来解决这个问题
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"

这里的想法是:按 _ 拆分 > 找到每列的最大长度 > 将 ls 填充到较短的值 > 将所有内容与 _ 分隔符组合起来。