【问题标题】:Reshape with concatenation to have a single time series for each variable in R [duplicate]通过连接重塑形状,为 R 中的每个变量提供一个时间序列 [重复]
【发布时间】:2017-11-22 09:42:58
【问题描述】:

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

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

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

数据集如下所示:

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

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

【问题讨论】:

  • data.tabledcast,即dcast(setDT(df1), Period ~Brand, value.var = c("V1", "V2", "V3"))
  • 嘿,看看我不需要为每种情况输入变量名的解决方案,例如“V1”、“V2”等
  • 您可以使用names(df1)[3:5] 代替它
  • @akrun 这很好用!

标签: r reshape reshape2 melt


【解决方案1】:

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

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

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

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)

【讨论】:

  • 这也有效,但我发现@akrun 解决方案,目前更可行。顺便说一句,如果您不介意,您能解释一下这行代码吗? colnames(z)
  • 匹配一个或多个单词字符,后跟一个点,然后是一个或多个单词字符。括号定义捕获组。然后替换字符串指定与第二个捕获组的匹配、一个下划线和与第一个捕获组的匹配。
【解决方案2】:

我们可以使用来自data.tabledcast,它需要多个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

【讨论】:

    【解决方案3】:

    如果您习惯使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      相关资源
      最近更新 更多