在包含多个时间系列的数据框中添加缺失的行

时间:2014-06-12 22:14:54

标签: r time-series

我有一个包含2012年前六个月销售数据的数据集(以下是样本)

   month=c('2012-M01','2012-M02','2012-M04','2012-M05','2012-M06',
   '2012-M01','2012-M02','2012-M03','2012-M04','2012-M05','2012-M06',
   '2012-M02','2012-M03','2012-M05','2012-M06')
   product=c('A','A','A','A','A','B','B','B','B','B','B','C','C','C','C')
   sales=c(10,5,10,5,10,10,20,30,40,50,60,20,10,5,5)
   df = data.frame(month, product, sales)

我想做以下事情: 1)对于每个产品,用0销售填补缺失的月份。也就是说,要生成具有以下内容的数据框:

  month=c('2012-M01','2012-M02',**'2012-M03'**,'2012-M04','2012-M05','2012-M06',
    '2012-M01','2012-M02','2012-M03','2012-M04','2012-M05','2012-M06',
    '2012-M02','2012-M03',**'2012-M04'**,'2012-M05','2012-M06')
  product=c('A','A','**A**','A','A','A',B','B','B','B','B','B','C','C',**'C'**,'C','C')
  sales=c(10,5,**0**,10,5,10,10,20,30,40,50,60,20,10,**0**,5,5)
  df = data.frame(month, product, sales)

请注意,对于产品A,添加了包含2012-M03销售0的行;对于产品C,添加了包含2012-M04销售额0的行。对于产品B,不添加任何行。另请注意,对于产品C,我不想添加一行说M01的销售额为0;这是因为我们只开始在M02中销售产品C.

2)将每个产品的销售额转换为时间序列(即总共三个时间序列),但仍然在一个数据框中包含所有信息。

请让我知道如何实现上述1)和2)。提前致谢!

1 个答案:

答案 0 :(得分:0)

您可以使用reshape2包轻松完成此操作!

 #if you don't have it yet
 install.packages("reshape2")

 library("reshape2")

 #your setup 
 month=c('2012-M01','2012-M02','2012-M04','2012-M05','2012-M06',
'2012-M01','2012-M02','2012-M03','2012-M04','2012-M05','2012-M06',
'2012-M02','2012-M03','2012-M05','2012-M06')

product=c('A','A','A','A','A','B','B','B','B','B','B','C','C','C','C')

sales=c(10,5,10,5,10,10,20,30,40,50,60,20,10,5,5)

df = data.frame(month, product, sales)

# my stuff
df.melted = melt(df, id = c("month", "product"))

df.new = dcast(df.melted, month ~ product)

noleadingNAs = apply(df.new, 2, function(x) {
      y = x[match(TRUE,!is.na(x)):length(x)]
     }
   )


noNAs= lapply(noleadingNAs, function(x) {
    x[is.na(x)] = 0
    return(x)
   }
 )

totlen = max(sapply(noNAs, length))

balanced.df = as.data.frame(lapply(noNAs, function(x){
if(length(x) < totlen){
   x=c(rep(NA,totlen - length(x)),x)
 }
 else{x}
 }
 ), stringsAsFactors=FALSE
 )

data.m.wna = melt(balanced.df, id = "month")

data.final = data.m.wna[!is.na(data.m.wna$value),]

希望有所帮助。

编辑:我不能说它很漂亮,但我已经编辑了我的答案以放弃领先的NA。可能有更好的方法,但这将有效。