Las librerías a usar.
library(jsonlite)
library(plyr)
library(dplyr)
library(ggplot2)
library(wesanderson)
library(viridisLite)
library(rgdal)
library(ggplot2)
library(rgeos)
library(reshape2)
library(arules)
library(tm)
library(wordcloud)
library(RColorBrewer)
library(arulesViz)
library(DT)
library(htmlwidgets)
library(DataExplorer)
#limpio la memoria
#rm(list=ls())
#gc()
# Importamos los datos de las mediciones y de los barrios
mediciones = read.csv("./Datasets adicionales/mediciones.csv")
sucursales = read.csv("./Datasets adicionales/sucursales_barrios.csv")
productos = read.csv("./Datasets adicionales/productos_categoria.csv")
inflacion = read.csv("./Datasets adicionales/inflacion.csv")
precio_metros2 = read.csv("./barrios/precio_metro.csv")
head(productos)
glimpse(productos)
Observations: 1,016
Variables: 6
$ X_id..oid [3m[38;5;246m<fct>[39m[23m 5cbc69be7af152186c0cd784, 5cbc69be7af1...
$ nombre [3m[38;5;246m<fct>[39m[23m Aceite de Girasol Can?uelas 1.5 Lt, Ac...
$ Categoria [3m[38;5;246m<fct>[39m[23m Aceite, Aceite, Aceite, Aceite, Aceite...
$ marca [3m[38;5;246m<fct>[39m[23m CAÑUELAS, CAÑUELAS, COCINERO, COCINERO...
$ presentacion [3m[38;5;246m<fct>[39m[23m 1.5 lt, 900.0 cc, 1.5 lt, 900.0 ml, 1....
$ id [3m[38;5;246m<fct>[39m[23m 7792180001665, 7792180001641, 77900600...
head(precios)
glimpse(precios)
Observations: 1,584,661
Variables: 6
$ `_id` [3m[38;5;246m<df[,1]>[39m[23m <data.frame[21 x 1]>
$ producto [3m[38;5;246m<chr>[39m[23m "7790762052364", "12-1-2800000937881", "77...
$ sucursal [3m[38;5;246m<chr>[39m[23m "12-1-44", "12-1-44", "12-1-44", "12-1-44"...
$ precio [3m[38;5;246m<dbl>[39m[23m 56.20, 76.99, 215.00, 92.87, 81.99, 70.25,...
$ fecha [3m[38;5;246m<dttm>[39m[23m 2019-01-15 04:51:28, 2019-01-15 04:51:28,...
$ medicion [3m[38;5;246m<int>[39m[23m 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ...
Agregamos la info de los productos al df “precios”. Utilizamos inner join que matchea la columna producto del data frame precios y la columna ID de la columna del data frame productos
data1 = inner_join(precios, productos, by = c("producto" = "id"))
glimpse(data1)
Observations: 1,559,443
Variables: 11
$ `_id` [3m[38;5;246m<df[,1]>[39m[23m <data.frame[21 x 1]>
$ producto [3m[38;5;246m<chr>[39m[23m "7790762052364", "12-1-2800000937881",...
$ sucursal [3m[38;5;246m<chr>[39m[23m "12-1-44", "12-1-44", "12-1-44", "12-1...
$ precio [3m[38;5;246m<dbl>[39m[23m 56.20, 76.99, 215.00, 92.87, 81.99, 70...
$ fecha [3m[38;5;246m<dttm>[39m[23m 2019-01-15 04:51:28, 2019-01-15 04:51...
$ medicion [3m[38;5;246m<int>[39m[23m 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,...
$ X_id..oid [3m[38;5;246m<fct>[39m[23m 5cbc69be7af152186c0cd67e, 5cbc69be7af1...
$ nombre [3m[38;5;246m<fct>[39m[23m Vino Rosado Seleccion Especial Santa A...
$ Categoria [3m[38;5;246m<fct>[39m[23m Bebidas con alcohol, Conservas, Bebida...
$ marca [3m[38;5;246m<fct>[39m[23m SANTA ANA, COTO, NIETO SANETINER, BODE...
$ presentacion [3m[38;5;246m<fct>[39m[23m 700.0 ml, 81.0 gr, 750.0 cc, 750.0 ml,...
glimpse(sucursales)
Observations: 837
Variables: 15
$ X_id..oid [3m[38;5;246m<fct>[39m[23m 5cbc698b7af152186c0cd13f, 5cbc6...
$ sucursalTipo [3m[38;5;246m<fct>[39m[23m Autoservicio, Autoservicio, Aut...
$ direccion [3m[38;5;246m<fct>[39m[23m Av Dr. Ricardo Balbin 4881, San...
$ provincia [3m[38;5;246m<fct>[39m[23m AR-C, AR-C, AR-C, AR-C, AR-C, A...
$ banderaId [3m[38;5;246m<int>[39m[23m 1, 1, 3, 1, 1, 3, 1, 1, 1, 3, 1...
$ localidad [3m[38;5;246m<fct>[39m[23m Capital Federal, CAPITAL FEDERA...
$ banderaDescripcion [3m[38;5;246m<fct>[39m[23m Supermercados DIA, DEHEZA S.A.I...
$ lat [3m[38;5;246m<dbl>[39m[23m -34.55212, -34.55945, -34.54004...
$ comercioRazonSocial [3m[38;5;246m<fct>[39m[23m DIA Argentina S.A, Deheza S.A.I...
$ lng [3m[38;5;246m<dbl>[39m[23m -58.49841, -58.50503, -58.47474...
$ sucursalNombre [3m[38;5;246m<fct>[39m[23m 480 - Saavedra, GRAL PAZ - NORT...
$ comercioId [3m[38;5;246m<int>[39m[23m 15, 3, 10, 3, 3, 10, 15, 15, 15...
$ sucursalId [3m[38;5;246m<int>[39m[23m 480, 1506, 675, 1507, 29, 300, ...
$ id [3m[38;5;246m<fct>[39m[23m 15-1-480, 3-1-1506, 10-3-675, 3...
$ barrio [3m[38;5;246m<fct>[39m[23m SAAVEDRA, 0, SAAVEDRA, SAAVEDRA...
Agregamos la info de sucursales a “data1”, se crea un nuevo data frame, ver que ya no es necesario data1
data2 = inner_join(data1, sucursales, by = c("sucursal" = "id"))
glimpse(data2)
Observations: 1,559,443
Variables: 25
$ `_id` [3m[38;5;246m<df[,1]>[39m[23m <data.frame[21 x 1]>
$ producto [3m[38;5;246m<chr>[39m[23m "7790762052364", "12-1-28000009...
$ sucursal [3m[38;5;246m<chr>[39m[23m "12-1-44", "12-1-44", "12-1-44"...
$ precio [3m[38;5;246m<dbl>[39m[23m 56.20, 76.99, 215.00, 92.87, 81...
$ fecha [3m[38;5;246m<dttm>[39m[23m 2019-01-15 04:51:28, 2019-01-1...
$ medicion [3m[38;5;246m<int>[39m[23m 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6...
$ X_id..oid.x [3m[38;5;246m<fct>[39m[23m 5cbc69be7af152186c0cd67e, 5cbc6...
$ nombre [3m[38;5;246m<fct>[39m[23m Vino Rosado Seleccion Especial ...
$ Categoria [3m[38;5;246m<fct>[39m[23m Bebidas con alcohol, Conservas,...
$ marca [3m[38;5;246m<fct>[39m[23m SANTA ANA, COTO, NIETO SANETINE...
$ presentacion [3m[38;5;246m<fct>[39m[23m 700.0 ml, 81.0 gr, 750.0 cc, 75...
$ X_id..oid.y [3m[38;5;246m<fct>[39m[23m 5cbc698b7af152186c0cd187, 5cbc6...
$ sucursalTipo [3m[38;5;246m<fct>[39m[23m Supermercado, Supermercado, Sup...
$ direccion [3m[38;5;246m<fct>[39m[23m Av. Monroe 3284, Av. Monroe 328...
$ provincia [3m[38;5;246m<fct>[39m[23m AR-C, AR-C, AR-C, AR-C, AR-C, A...
$ banderaId [3m[38;5;246m<int>[39m[23m 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
$ localidad [3m[38;5;246m<fct>[39m[23m Belgrano, Belgrano, Belgrano, B...
$ banderaDescripcion [3m[38;5;246m<fct>[39m[23m COTO CICSA, COTO CICSA, COTO CI...
$ lat [3m[38;5;246m<dbl>[39m[23m -34.56358, -34.56358, -34.56358...
$ comercioRazonSocial [3m[38;5;246m<fct>[39m[23m Coto Centro Integral de Comerci...
$ lng [3m[38;5;246m<dbl>[39m[23m -58.46841, -58.46841, -58.46841...
$ sucursalNombre [3m[38;5;246m<fct>[39m[23m MONROE , MONROE , MONROE , MONR...
$ comercioId [3m[38;5;246m<int>[39m[23m 12, 12, 12, 12, 12, 12, 12, 12,...
$ sucursalId [3m[38;5;246m<int>[39m[23m 44, 44, 44, 44, 44, 44, 44, 44,...
$ barrio [3m[38;5;246m<fct>[39m[23m COGHLAN, COGHLAN, COGHLAN, COGH...
Borramos data1, nos quedamos con data2
rm(data1)
colnames(data2)
[1] "_id" "producto"
[3] "sucursal" "precio"
[5] "fecha" "medicion"
[7] "X_id..oid.x" "nombre"
[9] "Categoria" "marca"
[11] "presentacion" "X_id..oid.y"
[13] "sucursalTipo" "direccion"
[15] "provincia" "banderaId"
[17] "localidad" "banderaDescripcion"
[19] "lat" "comercioRazonSocial"
[21] "lng" "sucursalNombre"
[23] "comercioId" "sucursalId"
[25] "barrio"
data2[7]
#Solo me interesa el id de precio
Realizo con la función selectm la columnas dentro de mi data2 que serviran para conformar mi dataset llamado precios claros. Cada consulta estará determinada por el ID del df Precios.
preciosclaros = select(data2, `_id`, "producto", "nombre", "Categoria", "marca", "presentacion", "precio", "medicion", "sucursal", "sucursalTipo", "banderaDescripcion", "comercioRazonSocial", "direccion", "barrio")
#Para liberar espacio puedo quedarme solo con este dataset PRECIOSCLAROS
rm(precios)
rm(data2)
glimpse(preciosclaros)
Observations: 1,559,443
Variables: 14
$ `_id` [3m[38;5;246m<df[,1]>[39m[23m <data.frame[21 x 1]>
$ producto [3m[38;5;246m<chr>[39m[23m "7790762052364", "12-1-28000009...
$ nombre [3m[38;5;246m<fct>[39m[23m Vino Rosado Seleccion Especial ...
$ Categoria [3m[38;5;246m<fct>[39m[23m Bebidas con alcohol, Conservas,...
$ marca [3m[38;5;246m<fct>[39m[23m SANTA ANA, COTO, NIETO SANETINE...
$ presentacion [3m[38;5;246m<fct>[39m[23m 700.0 ml, 81.0 gr, 750.0 cc, 75...
$ precio [3m[38;5;246m<dbl>[39m[23m 56.20, 76.99, 215.00, 92.87, 81...
$ medicion [3m[38;5;246m<int>[39m[23m 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6...
$ sucursal [3m[38;5;246m<chr>[39m[23m "12-1-44", "12-1-44", "12-1-44"...
$ sucursalTipo [3m[38;5;246m<fct>[39m[23m Supermercado, Supermercado, Sup...
$ banderaDescripcion [3m[38;5;246m<fct>[39m[23m COTO CICSA, COTO CICSA, COTO CI...
$ comercioRazonSocial [3m[38;5;246m<fct>[39m[23m Coto Centro Integral de Comerci...
$ direccion [3m[38;5;246m<fct>[39m[23m Av. Monroe 3284, Av. Monroe 328...
$ barrio [3m[38;5;246m<fct>[39m[23m COGHLAN, COGHLAN, COGHLAN, COGH...
#Auto explorer Precios claros
#introduce(preciosclaros)
#create_report(preciosclaros)
# Tratamiento de precios
Necesito pasar los precios de productos por sucursal a formato columnar. Cada fila representará un producto de una sucursal con diez columnas asociadas a los precios en cada medición.
Cabe que esta forma es la que tenemos más asociada al ahora de trabajar la data, sin embargo distintos algoritmos de predicción puedan requerir otra manera de organizar la data. Por ejemplo: Historia clinica a lo largo de la vida.
Reshape significa cambiar la forma de nuestro dataset, esto es determinar las filas y las columnas, que variables están en función de cual otra. Claramente esto debe tener sentido. Nos interesa en este momento ver los precios en funcion de cada medición. Es decir, nos interesa agrupar cada producto por sucursal, por presentacion, por barrio, según la medición en que fue tomado el dato.
La función dcast es un melt en donde que toma la forma LHS ~ RHS, ex: var1 + var2 ~ var3. El orden de las variables es esencial. Los valores LHS (antes del newflow ~ representan las filas y luego representan las columnas.
preciosclarosdcast = dcast(preciosclaros, producto + nombre + Categoria + marca + presentacion + sucursal + sucursalTipo + banderaDescripcion + comercioRazonSocial + direccion + barrio ~ medicion, fun.aggregate=NULL, value.var="precio")
head(preciosclarosdcast)
#is.na(preciosclarosdcast) # indica cuáles de los elementos son NA (TRUE)
# Para saber la cantidad exacta de NAs que están presentes en los datos
sum(is.na(preciosclarosdcast))
[1] 0
#complete.cases(preciosclarosdcast) # Me devuelve los índices de los registros que NO tienen NAs
length(which(!complete.cases(preciosclarosdcast))) # Me permite saber cuántos registros tengo, sin hacer la cuenta
[1] 53170
# Tengo 53170 registros que tienen al menos 1 NA
colnames(preciosclarosdcast)[colSums(is.na(preciosclarosdcast)) > 0] # Obtengo las columnas que tienen un al menos NA. Mediciones sin datos.
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"
funModeling::status(preciosclarosdcast)
#Hago una copia del dataset para trabajar
df = preciosclarosdcast
#La medicion faltante en el barrio de Coghlan
df[2:2,]
NA
#selecciono aquel que tiene tipos de datos numericos. Para eso hago una funcion llamada numerico que me devolvera true por cada indice que sea numero, luego se la aplico al df. Observo que solo hay faltantes en mis mediciones
numerico<- sapply(df, is.numeric)
df2 = df[numerico]
head(df2)
for(i in 1:ncol(df2)) {
df2[ , i][is.na(df2[ , i])] <- mean(df2[ , i], na.rm = TRUE)
}
head(df2) # Check first 6 rows after substitution by mean
NA
df[numerico] = df2
df[2:2,]
NA
dfmanera2 = preciosclarosdcast
# Solo necesito las columnas numericas
library(zoo)
numerico<- sapply(dfmanera2 , is.numeric)
dfmanera2 [numerico] <- lapply(dfmanera2 [numerico], na.aggregate)
dfmanera2 [2:2,]
NA
dfomit = preciosclarosdcast
# Eliminamos toda la fila por contener un faltante
dfomit = na.omit(dfomit)
dfomit [2:2,]
nrow(dfomit)
[1] 111422
nrow(preciosclarosdcast)
[1] 164592
¿El periodo de la medicion 1 a la 10 pueden haber sido varios meses, no sería correcta reemplazarla por el promedio de las dos siguientes?
Medicion 1-2-3 son de Noviembre 2018 Medicion 4-5 son de Diciembre 2018 Medicion 6-7 son de Enero 2019 Medicion 8-9-10 son de Febrero
¿Que pasa si hago un promedio mensual? No va a haber más faltantes?
# Promedios por periodo y total
preciosclarosdcast =
(
preciosclarosdcast %>%
mutate(periodo1 = rowMeans(select(., "1","2","3")), periodo2 = rowMeans(select(., "4","5")), periodo3 = rowMeans(select(., "6","7")), periodo4 = rowMeans(select(., "8","9","10")), promedio = rowMeans(select(., "1","2","3","4","5","6","7","8","9","10")))
)
Podria imputar las mediciones sigueintes a las que tengo NA, es decir, si en la medicion 1 tengo un NA, porque no imputar directamente el valor siguiente dado que la diferencia intra mensual es menor.
# Reemplaza los NA en la medición 1 por el valor de la medición 2
i = which(is.na(preciosclarosdcast$`1`)) # Devuelve número de filas con NA
preciosclarosdcast[i,12] = preciosclarosdcast[i,13] # reemplaza los nulos en la primer medición por el valor en la segunda
En el caso de los valores siguientes que tienen un adyacente, podría promediar el valor anterior (j-1) y el valor siguiente (j+1), es decir, mi precio de la medicion con NA 5, seria un promedio entre la 4 y la 6.
# Reemplaza NA entre la columna 13 y la 20 (valores d las mediciones 2 a 9) por el promedio de sus adyacentes
for (j in 0:7) {
ii = which(is.na(preciosclarosdcast[,13+j]))
preciosclarosdcast[ii,13+j] = (preciosclarosdcast[ii,13+j-1]+preciosclarosdcast[ii,13+j+1])/2
}
# Reemplazo los NA de la medición 10 por el valor de la medición 9
iii = which(is.na(preciosclarosdcast$`10`))
preciosclarosdcast[iii,21] = preciosclarosdcast[iii,20]
sum(is.na(preciosclarosdcast))
[1] 156041
Por ultimo si me quedo algun faltante que no reemplace de esta manera, podría eliminarlo
# Eliminamos toda la fila por contener un faltante
preciosclarosdcast = na.omit(preciosclarosdcast)
nrow(preciosclarosdcast)
[1] 111422
nrow(dfomit)
[1] 111422
# Renombro las columnas de las mediciones
preciosclarosdcast =
(
preciosclarosdcast %>% rename(
"m1" = "1",
"m2" = "2",
"m3" = "3",
"m4" = "4",
"m5" = "5",
"m6" = "6",
"m7" = "7",
"m8" = "8",
"m9" = "9",
"m10" = "10"
)
)
# Variaciones intra periodo y total
preciosclarosdcast = (
preciosclarosdcast %>%
dplyr::mutate(variacion1 = (m3-m1)/m1, variacion2 = (m5-m4)/m4, variacion3 = (m7-m6)/m6, variacion4 = (m10-m8)/m8, variacionT = (m10-m1)/m1)
)