
#Notes 
# Implements the kernel https://www.kaggle.com/paulorzp/log-ma-and-days-of-week-means-lb-0-529
# Exactly porting the code into R
# Gives a Public LB Score of 0.532 (The same kernel gives 0.529 when executed in python. Don't know why :| )
# Why should python have all the fun ;)

#Libraries
library(forecast)
library(reshape2)
library(data.table)
library(lubridate)

#Using only 2017 data for forecasting
train <- fread("../input/train.csv")
train <- train[date>"2016-08-01",,]
train[,store_item:=paste0(store_nbr,"_",item_nbr),]
train[,store_nbr:=NULL,]
train[,item_nbr:=NULL,]
train <- train[,c("date","store_item","unit_sales"),with=FALSE]

#Making all the negative unit sales to zero
train[unit_sales<0,unit_sales:=0,]

#Imputing the NAs
trainMainwide <- dcast(train, store_item ~ date, value.var = "unit_sales", fill = 0)
train <- melt(trainMainwide, id = 'store_item', 
                     variable.name = "Date", 
                     value.name = 'unit_sales')
train <- data.table(train)
train[,Date:=ymd(Date),]

#Applying log(1+x) transformation
train[,unit_sales:=log1p(unit_sales),]

#Creating the day of the week column
train[,dow:=weekdays(Date),]

#Getting averages at store_item X dow level and week level
AvgsStrItemDow <- train[,list(ma_stritemdow=mean(unit_sales)),by=list(store_item,dow)]
AvgsStrItemWk <- AvgsStrItemDow[,list(ma_stritemwk=mean(ma_stritemdow)),by=list(store_item)]

#Getting averages at store_item level
AvgsStrItem <- train[,list(ma_stritem=mean(unit_sales)),by=list(store_item)]

#The actual receipe is here
mas <- c(1,3,7,14,28,56,112)
masdates <- max(train$Date)-mas
counts <- 1

for(dts in masdates){
  print(dts)
  temp <- train[Date>dts,list(ma_stritem =mean(unit_sales)),by=list(store_item)]
  colnames(temp)[2] <- paste0("ma_stritem_",mas[counts])
  counts <- counts +1
  AvgsStrItem <- merge(AvgsStrItem,temp, by=c("store_item"), all.x = T)
}

#Get the median sales from all moving average sales
macols <- colnames(AvgsStrItem)[2:9]
AvgsStrItem[,ma_median:=apply(AvgsStrItem[,macols,with=FALSE],1,median),]


#Processing the test dataset
test <- fread("../input/test.csv")
test[,date:=ymd(date),]
test[,dow:=weekdays(date),]
test[,store_item:=paste0(store_nbr,"_",item_nbr),]
test[,c("store_nbr","item_nbr"):=NULL,]

#Merging the previous files
test <- merge(test,AvgsStrItem, by=c("store_item"), all.x = T)
test <- merge(test,AvgsStrItemWk, by=c("store_item"), all.x = T)
test <- merge(test,AvgsStrItemDow, by=c("store_item","dow"), all.x = T)


#Forecasting begins here
test[,unit_sales:=ma_median,]
test[!is.na(ma_stritemwk),unit_sales:=((ma_median*ma_stritemdow)/ma_stritemwk),]#Adjusting the sales
test[is.na(unit_sales),unit_sales:=0,]#Making the unscored sales zero
test[,unit_sales:=expm1(unit_sales),]#Undoing the transformation

#Gives 1.5X weights for sales with Promotion
test[onpromotion == TRUE,unit_sales:=1.5*(unit_sales),]
Finalsubmission <- test[,c("id","unit_sales"),with=FALSE]
write.csv(Finalsubmission,"LogMA_2016.csv", row.names = F)




