通过串联重塑以使 R 中的每个变量具有单个时间序列

Reshape with concatenation to have a single time series for each variable in R

想用下面的结构重塑数据集,以帮助我创建用于时间序列分析的数据集

下面的数据集是一个示例,我有多个变量作为列,多个品牌作为行以及它们各自的时间段

Brand Period V1 V2 V3 A Week1 1 2 3 A Week2 1 2 3 A Week3 1 2 3 B Week1 1 2 3 B Week2 1 2 3 B Week3 1 2 3 C Week1 1 2 3 C Week2 1 2 3 C Week3 1 2 3

数据集如下所示:

期间A_V1A_V2A_V3B_V1B_V2B_V3C_V1C_V2C_V3 第 1 周<br> 第 2 周<br> 第三周

想知道重塑包或我可以使用的任何其他包中是否有某些功能

如果您习惯了 tidyverse,您可以使用 tidyr 中的 gatherspread 的组合(类似于 this 回答):

Brand <- c(rep("A", 3), rep("B", 3), rep("C", 3))
Period <- c(rep(c("Week1", "Week2", "Week3"), 3))
V1 <- c(rep(1, 9))
V2 <- c(rep(2, 9))
V3 <- c(rep(3, 9))
df <- data.frame(cbind(Brand, Period, V1, V2, V3))

df %>% 
  gather(vars, value, -Brand, -Period) %>% 
  mutate(observation = paste(Brand, vars, sep="_")) %>% 
  select(-Brand, -vars) %>% 
  spread(observation, value)

结果:

  Period A_V1 A_V2 A_V3 B_V1 B_V2 B_V3 C_V1 C_V2 C_V3
1 Week1     1    2    3    1    2    3    1    2    3
2 Week2     1    2    3    1    2    3    1    2    3
3 Week3     1    2    3    1    2    3    1    2    3

基本操作可以在一个 read.zoo 调用中完成,它将:

  • 读取 brands.dat 文件(在末尾的注释中可重复定义)——如果你有一个数据框作为输入,那么使用下面注释掉的行而不是未注释的行,
  • 按品牌拆分数据。

结果是动物园系列 z。该系列可以直接以该形式进行操作,也可以使用 fortify.zoo(z) 或通过将索引收敛为数字(如后所示)然后使用 as.ts(z).[= 将其转换为数据框或 ts 系列21=]

library(zoo)

# z <- read.zoo(brands, index = 2, split = 1, FUN = as.character, header = TRUE)
z <- read.zoo("brands.dat", index = 2, split = 1, FUN = as.character, header = TRUE)

给予:

      V1.A V2.A V3.A V1.B V2.B V3.B V1.C V2.C V3.C
Week1    1    2    3    1    2    3    1    2    3
Week2    1    2    3    1    2    3    1    2    3
Week3    1    2    3    1    2    3    1    2    3

如果您更喜欢问题中所示形式的列名,请添加:

colnames(z) <- sub("(\w+)[.](\w+)", "\2_\1", colnames(z))

如果您更喜欢数字时间索引或想将其转换为 ts 系列(这需要这样),请添加:

time(z) <- 1:nrow(z)

或者这个:

time(z) <- as.numeric(gsub("\D", "", time(z))

注意: 这将生成输入文件:

Lines <- "
Brand   Period  V1  V2  V3
A      Week1    1   2   3
A      Week2    1   2   3
A      Week3    1   2   3
B      Week1    1   2   3
B      Week2    1   2   3
B      Week3    1   2   3
C      Week1    1   2   3
C      Week2    1   2   3
C      Week3    1   2   3"
cat(Lines, file = "brands.dat")

或者如果您的起点是数据框,则:

brands <- read.table(text = Lines, header = TRUE)

我们可以使用 data.table 中的 dcast,它需要多个 value.var

library(data.table)
dcast(setDT(df1), Period ~ Brand, value.var =names(df1)[3:5])
#   Period V1_A V1_B V1_C V2_A V2_B V2_C V3_A V3_B V3_C
#1:  Week1    1    1    1    2    2    2    3    3    3
#2:  Week2    1    1    1    2    2    2    3    3    3
#3:  Week3    1    1    1    2    2    2    3    3    3