【问题标题】:Consolidating variables into unified time series将变量合并为统一的时间序列
【发布时间】:2018-08-27 11:44:57
【问题描述】:

我的数据按以下方式组织:

product  week1  ...   week52   year    release
A        NA     ...   100      2008    2008-06-06
B        200    ...   200      2008    2008-01-01 
...      ...    ...   ...      ...     ...
A        60     ...   50       2009    2008-06-06

其中product 指产品标识符,week1week52 是一年中的每周销售额,year 是当年,release 是产品的发布日期。

我想结合并“透视”年和周来创建一个像这样的新数据集:

product  date        released  sales
A        2008-01-07  0         NA       
...      ...         ...       ...
A        2008-12-31  1         100
A        2009-01-07  1         60
...      ...         ...       ...
A        2009-12-31  1         50
B        2008-01-07  1         200
...      ...         ...       ...
B        2008-12-31  1         200

现在,我们为每个产品使用一个时间序列变量,而不是 week_iyearreleased 是产品是否在任何时间点发布的虚拟变量。

我的问题是:考虑到多年来我在数据中拥有数万种产品,我该如何以计算效率高的方式做到这一点?不必担心实际日历年超过 52 周,只需考虑将一年中的最后一周加长以吸收剩余的日子。

我可以在左侧创建一个新的面板数据框,其中包含产品 ID 和所需的时间序列,然后编写一个三级循环,依次遍历所有产品、所有年份和所有星期。例如,这是获取sales的最内层循环的想法,数据帧olddatanewdata,假设两个外层循环当前指向产品P和年份Y

temp=newdata[which(newdata$product==P & year(newdata$date)==Y),]
for (i in (1:52)) {
 temp[i,4]=olddata[which(olddata$product==P & olddata$year==Y),1+i]
}

lubridate 提供年份提取。

但是,这对于计算波谷可能非常低效。 你有更直接的建议吗?

提前致谢!

编辑:这里有一些代码可以生成一个示例,就像我无法共享的数据一样:

mydata=matrix(0,4,55)
colnames(mydata)=c("product",paste0(rep("week",52),seq(from=1,to=52)),"year","release")
mydata[1,1]="A"
mydata[2,1]="B"
mydata[3,1]="A"
mydata[4,1]="B"
mydata[1,54]=2008
mydata[2,54]=2008
mydata[3,54]=2009
mydata[4,54]=2009
library(lubridate)
mydata[1,55]=ymd("2008-06-06")
mydata[2,55]=ymd("2008-01-01")
mydata[3,55]=ymd("2008-06-06")
mydata[4,55]=ymd("2008-01-01")
mydata[1,2:23]=rep(NA,22)
mydata[1,24:53]=seq(from=71,by=1,length.out = 30)
mydata[2,2:53]=rep(200,52)
mydata[3,2:53]=seq(from=60,to=50,length.out = 52)
mydata[4,2:53]=rnorm(52,200,20)
mydata=as.data.frame(mydata)

【问题讨论】:

  • 由于您不只是在releasedate 上干净利落地旋转,我建议您需要放置一些更大量的示例数据,并请使用dput(head(x,n=20)) 之类的东西使其易于复制.确保样本数据显示出足够的可变性;可能不需要太多,但只有你会知道。
  • 我已经编辑了 OP,添加了代码来生成一些数据。

标签: r time-series


【解决方案1】:

好的,这是我发现的最简单的方法。不过,它仍然需要一个循环;打字慢但不太麻烦。

首先按产品id对数据进行排序:

mydata=mydata[order(mydata$product, mydata$year),]

product  week1  ...   week52   year    release
A        NA     ...   100      2008    2008-06-06
A        60     ...   50       2009    2008-06-06
B        200    ...   200      2008    2008-01-01 

然后请注意,通过转置您获得的每周销售数据矩阵(显示产品 A 的观察结果):

t(mydata[which(mydata$product=="A"),2:53])

week1  NA   60
...    ...  ...
week52 100  50

第一列对应 2008 年,第二列对应 2009 年。 因此,通过对该矩阵进行向量化,您可以获得一列每周数据:

c(t(mydata[which(mydata$product=="A"),2:53]))

week1   NA
...     ... 
week52  100
week1   60
...     ...
week52  50

这是我们希望为每个产品获得的。生成的循环是,表示newdata“堆叠”数据框:

# List all unique products
products=unique(mydata$product)
N=length(products)
for (i in (1:N)) {
 # Replace values in the vector of "stacked up" sales:
 newdata$sales[which(newdata$product==products[i])]=c(t(mydata[which(mydata$product==products[i]),2:53]))
}

这个循环需要一段时间才能运行,但不需要太多的用户算术增量,因此人为错误的风险并不高。

【讨论】:

    猜你喜欢
    • 2015-02-03
    • 2022-06-27
    • 1970-01-01
    • 2021-10-20
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    相关资源
    最近更新 更多