** Objetivo ****

Entender aspectos concretos de los fundamentos para resumir un conjunto o una variable.

Las observaciones pueden incluir datos discretos que ocurren en niveles específicos (variables discretas) o datos continuos con muchos valores posibles (variables continuas).


** Variables discretas ****

Una manera basica de describir las variables discretas es a traves del conteo de frecuencia. La funcion table() nos permite hacerlo. Esta funcion contará la prevalencia observada de cada valor que ocurre en una variable.

En este caso contaremos las veces que el producto 1 estaba a la venta en cada precio de venta.

library(tidyverse)
table(store.df$p1price)
## 
## 2.19 2.29 2.49 2.79 2.99 
##  395  444  423  443  375

Si avanzamos y visualizamos de manera basica la informacion podemos observar que el producto estaba a la venta a cada precio de venta casi el mismo numero de veces.

p1.table <- table(store.df$p1price)
plot(p1.table)

Con la funcion table() tambien somos capaces de juntar varias variables que nos puedan interesar cruzar. Por ejemplo, en este caso queremos saber el numero de veces que se ha promocionado el producto a cada rango de precio.

Ademas si queremos podemos sacar el dato exacto de veces que ha estado en promocion.

p1.table2 <- table(store.df$p1price, store.df$p1prom)

p1.table2[,2] / (p1.table2[,1] + p1.table2[,2])
##       2.19       2.29       2.49       2.79       2.99 
## 0.10379747 0.10360360 0.09929078 0.10609481 0.08533333

** Variables continuas ****

En el caso de las variables continuas es mas util resumir la informacion en base a su distribucion.

knitr::include_graphics("Funciones de distribucion.jpg")
A caption

A caption

min(store.df$p1sales)
## [1] 66
max(store.df$p2sales)
## [1] 248
mean(store.df$p1prom)
## [1] 0.1
median(store.df$p2sales)
## [1] 121
var(store.df$p1sales)
## [1] 720.2054
sd(store.df$p1sales)
## [1] 26.83664
IQR(store.df$p1sales)
## [1] 36
mad(store.df$p1sales)
## [1] 25.2042
quantile(store.df$p1sales, probs = c(0.25, 0.5, 0.75))
## 25% 50% 75% 
## 105 121 141

En el caso de Quantile (), hemos solicitado los percentiles 25, 50 y 75.Usando el argumento probs = c (0.25, 0.5, 0.75), que también se conoce como la mediana (percentil 50, igual que la función mediana () y los bordes de la rango intercuartil, los percentiles 25 y 75.

Para distribuciones asimetricas que son comunes en marketing, como las unidades vendidas. La media aritmetica mean() y la desviacion estandar, sd() pueden ser engañosas. En estos casos, la mediana, median() y el rango intercuartil IQR() son son mas utiles para resumir la distrubicion.

Si quisieramos cambiando el argumento probs =, podemos tener mas variabilidad que nos puede ser interesante de explorar.

quantile(store.df$p1sales, probs = c(0.05, 0.95))
##  5% 95% 
##  87 173
quantile(store.df$p1sales, probs = 0:10/10)
##   0%  10%  20%  30%  40%  50%  60%  70%  80%  90% 100% 
##   66   93  102  109  115  121  128  136  147  161  248

Por ejemplo, podríamos hacer un resumen de las ventas del producto 1 y producto 2 en base a su mediana y rango intercuartil.

mysummary.df <- data.frame(matrix(NA, nrow = 2, ncol = 2))
names(mysummary.df) <- c("Median Sales", "IQR")
rownames(mysummary.df) <- c("Product1", "Product2")
mysummary.df["Product1", "Median Sales"] <- median(store.df$p1sales)
mysummary.df["Product2", "Median Sales"] <- median(store.df$p2sales)
mysummary.df["Product1", "IQR"] <- IQR(store.df$p1sales)
mysummary.df["Product2", "IQR"] <- IQR(store.df$p2sales)

mysummary.df
##          Median Sales IQR
## Product1          121  36
## Product2          121  36

** Resumiendo data frames ****

R nos provee de una variedad de maneras de resumir data frames si escribir mucho codigo. Podemos distingirlos en 3 funciones:

Summary() es un abuena manera de hacer una inspección preliminar de un data frame o un objeto.si queremos cambiar la precision de los datos podemos utilizar el argumento digits.

Con summary podemos hacer un check de los minimos y maximos en busca de outliers, o si la media y mediana son similares la una a la otra.

summary(store.df)
##     storeNum          Year          Week          p1sales   
##  Min.   :101.0   Min.   :1.0   Min.   : 1.00   Min.   : 66  
##  1st Qu.:105.8   1st Qu.:1.0   1st Qu.:13.75   1st Qu.:105  
##  Median :110.5   Median :1.5   Median :26.50   Median :121  
##  Mean   :110.5   Mean   :1.5   Mean   :26.50   Mean   :125  
##  3rd Qu.:115.2   3rd Qu.:2.0   3rd Qu.:39.25   3rd Qu.:141  
##  Max.   :120.0   Max.   :2.0   Max.   :52.00   Max.   :248  
##     p2sales         p1price         p2price          p1prom   
##  Min.   : 66.0   Min.   :2.190   Min.   :2.190   Min.   :0.0  
##  1st Qu.:105.0   1st Qu.:2.290   1st Qu.:2.290   1st Qu.:0.0  
##  Median :121.0   Median :2.490   Median :2.490   Median :0.0  
##  Mean   :124.6   Mean   :2.544   Mean   :2.542   Mean   :0.1  
##  3rd Qu.:141.0   3rd Qu.:2.790   3rd Qu.:2.790   3rd Qu.:0.0  
##  Max.   :248.0   Max.   :2.990   Max.   :2.990   Max.   :1.0  
##      p2prom          country         
##  Min.   :0.00000   Length:2080       
##  1st Qu.:0.00000   Class :character  
##  Median :0.00000   Mode  :character  
##  Mean   :0.09135                     
##  3rd Qu.:0.00000                     
##  Max.   :1.00000
summary(store.df$Year)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     1.0     1.0     1.5     1.5     2.0     2.0
summary(store.df, digits = 2)
##     storeNum        Year          Week       p1sales       p2sales   
##  Min.   :101   Min.   :1.0   Min.   : 1   Min.   : 66   Min.   : 66  
##  1st Qu.:106   1st Qu.:1.0   1st Qu.:14   1st Qu.:105   1st Qu.:105  
##  Median :110   Median :1.5   Median :26   Median :121   Median :121  
##  Mean   :110   Mean   :1.5   Mean   :26   Mean   :125   Mean   :125  
##  3rd Qu.:115   3rd Qu.:2.0   3rd Qu.:39   3rd Qu.:141   3rd Qu.:141  
##  Max.   :120   Max.   :2.0   Max.   :52   Max.   :248   Max.   :248  
##     p1price       p2price        p1prom        p2prom     
##  Min.   :2.2   Min.   :2.2   Min.   :0.0   Min.   :0.000  
##  1st Qu.:2.3   1st Qu.:2.3   1st Qu.:0.0   1st Qu.:0.000  
##  Median :2.5   Median :2.5   Median :0.0   Median :0.000  
##  Mean   :2.5   Mean   :2.5   Mean   :0.1   Mean   :0.091  
##  3rd Qu.:2.8   3rd Qu.:2.8   3rd Qu.:0.0   3rd Qu.:0.000  
##  Max.   :3.0   Max.   :3.0   Max.   :1.0   Max.   :1.000  
##    country         
##  Length:2080       
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

En cuanto a describe() reporta una variedad de aspectos estadisticos para cada variable en el dataset, incluyendo n (el recuento de observaciones), trimmed mean o media recortada (la media despues de dejar de lado una pequeña proporcion de valores extremos) y otros aspectos como skew(sesgo) y kurtosis, que son utiles a la hora de interpretar informacion en relacion a distribuciones normales.

Si comparamos la media recortada con la media general, podemos descubrir cuando los outliers estan sesgando la media con valores extremos.

En el caso de factores, describe() los analiza como si fueran integers. Describe() seria verdaderamente util con los factores si estos siguieran un orden significativo.

Por otro lado, otra de las herramientas mas interesantes de R es apply(), que sigue este comando apply(x=DATA, MARGIN=MARGIN, FUN=FUNCTION).

apply() tiene como objetivo ejecuta cualquier función que especifique en cada una de las filas y / o columnas de un objeto.

En R, el argumento margin es una metáfora bidimensional que denota qué “dirección” quieres hacer algo: a lo largo de las filas (MARGEN = 1) o columnas (MARGEN = 2), o ambos simultáneamente (MARGEN = c (1, 2)).

apply(store.df[,2:9], MARGIN = 2, FUN = mean)
##         Year         Week      p1sales      p2sales      p1price 
##   1.50000000  26.50000000 124.99663462 124.62355769   2.54437500 
##      p2price       p1prom       p2prom 
##   2.54197115   0.10000000   0.09134615

De igual manera, podemos calcular aspectos como sum() o sd().

apply(store.df[,2:9], MARGIN = 2, FUN = sum)
##     Year     Week  p1sales  p2sales  p1price  p2price   p1prom   p2prom 
##   3120.0  55120.0 259993.0 259217.0   5292.3   5287.3    208.0    190.0
apply(store.df[,2:9], MARGIN = 2, FUN = sd)
##       Year       Week    p1sales    p2sales    p1price    p2price 
##  0.5001202 15.0119401 26.8366424 26.3237351  0.2948819  0.2985712 
##     p1prom     p2prom 
##  0.3000721  0.2881700

Incluso, podemos calcular aspectos mas complejos como la diferencia entre la media y mediana de cada variable.

apply(store.df[,2:9], 2, function (x) { mean(x) - median(x)})
##       Year       Week    p1sales    p2sales    p1price    p2price 
## 0.00000000 0.00000000 3.99663462 3.62355769 0.05437500 0.05197115 
##     p1prom     p2prom 
## 0.10000000 0.09134615

El resultado nos indica que la media del producto 1 y 2 son mayores que la mediana por 4 ventas por semana, lo que indica que hay una rigth hand tail en la distribuicon. Es decirm semanas con grandes ventas que aumentan la media.

Con apply() personalizamos todo el proceso.

mysummary2.df <- data.frame(matrix(NA, nrow = 2, ncol = 2))
names(mysummary2.df) <- c("Median Sales", "IQR")
rownames(mysummary2.df) <- c("Product1", "Product2")
mysummary2.df[, "Median Sales"] <- apply(store.df[,4:5], 2, median)
mysummary2.df[, "IQR"] <- apply(store.df[,4:5], 2, IQR)

mysummary.df
##          Median Sales IQR
## Product1          121  36
## Product2          121  36