【发布时间】: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 指产品标识符,week1 到week52 是一年中的每周销售额,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_i 和 year,released 是产品是否在任何时间点发布的虚拟变量。
我的问题是:考虑到多年来我在数据中拥有数万种产品,我该如何以计算效率高的方式做到这一点?不必担心实际日历年超过 52 周,只需考虑将一年中的最后一周加长以吸收剩余的日子。
我可以在左侧创建一个新的面板数据框,其中包含产品 ID 和所需的时间序列,然后编写一个三级循环,依次遍历所有产品、所有年份和所有星期。例如,这是获取sales的最内层循环的想法,数据帧olddata和newdata,假设两个外层循环当前指向产品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)
【问题讨论】:
-
由于您不只是在
release或date上干净利落地旋转,我建议您需要放置一些更大量的示例数据,并请使用dput(head(x,n=20))之类的东西使其易于复制.确保样本数据显示出足够的可变性;可能不需要太多,但只有你会知道。 -
我已经编辑了 OP,添加了代码来生成一些数据。
标签: r time-series