
library(data.table)
library(dplyr)

train <- fread('../input/train.csv', 
               select = c('Cliente_ID', 'Canal_ID', 'Producto_ID', 'Agencia_ID', 'Ruta_SAK', 'Demanda_uni_equil'))
test <- fread('../input/test.csv', 
              select = c('id', 'Cliente_ID','Canal_ID', 'Producto_ID', 'Agencia_ID', 'Ruta_SAK'))

#transform target variable to log(1 + demand) - this makes sense since we're 
#trying to minimize rmsle and the mean minimizes rmse:
train$log_demand = log(train$Demanda_uni_equil + 1.1) 

#set a table key to enable fast aggregations
setkey(train, Producto_ID, Canal_ID, Ruta_SAK)
setkey(test,  Producto_ID, Canal_ID, Ruta_SAK)

print("Computing means")
mean_total <- median(train$log_demand) #overall mean
print("Computing means1")
mean_Canal <-                  train[, .(mean_canal = median(log_demand)),           by = .(Canal_ID)]
print("Computing means2")
mean_Canal_Ruta <-             train[, .(mean_canal_ruta = median(log_demand)),      by = .(Canal_ID, Ruta_SAK)]
print("Computing means3")
mean_Canal_Ruta_Prod <-        train[, .(mean_canal_ruta_prod = median(log_demand)), by = .(Producto_ID, Canal_ID, Ruta_SAK)] 
print("Computing means4")
mean_Canal_Ruta_Client <- train[, .(mean_canal_ruta_client = median(log_demand)), by = .(Canal_ID, Ruta_SAK, Cliente_ID)] 
print("Computing mean5")
mean_Canal_Ruta_Agenc <- train[, .(mean_canal_ruta_agenc = median(log_demand)),by = .(Agencia_ID, Ruta_SAK, Canal_ID)]                   

print("Merging means with test set")
submit <- merge(test,   mean_Canal_Ruta_Agenc, all.x = TRUE, by = c("Canal_ID", "Ruta_SAK", "Agencia_ID"))
submit <- merge(submit, mean_Canal_Ruta_Client, all.x = TRUE, by = c("Cliente_ID", "Canal_ID", "Ruta_SAK"))
submit <- merge(submit, mean_Canal_Ruta_Prod, all.x = TRUE,        by = c("Producto_ID", "Canal_ID", "Ruta_SAK"))
submit <- merge(submit, mean_Canal_Ruta, all.x = TRUE,             by = c("Canal_ID", "Ruta_SAK"))
submit <- merge(submit, mean_Canal, all.x = TRUE,                  by = "Canal_ID")


print("pridiction")
preds = submit$mean_canal_ruta_prod
preds[is.na(preds)] = submit$mean_canal_ruta_client[is.na(preds)]
preds[is.na(preds)] = submit$mean_canal_ruta_agenc[is.na(preds)]
preds[is.na(preds)] = submit$mean_canal_ruta[is.na(preds)]
preds[is.na(preds)] = submit$mean_canal[is.na(preds)]
preds[is.na(preds)] = mean_total

#transform the preds back - scaling the preds worked better in some scripts 
#so it made me curious altought it doesn't make too much sense mathematically.
preds = expm1(preds)*0.91

submission = data.frame(id = submit$id, Demanda_uni_equil = preds)
write.csv(submission, "submission.csv", row.names = FALSE)