Profesor del programa de Ingeniería Industrial, Universidad Sergio Arboleda. Candidato a doctor en Ingeniería de la Universidad de los Andes.

Marketing Analytics

El departamento de finanzas quizás se asocie más a menudo con mediciones y análisis con los que toda la organización está familiarizada: ingresos, ganancias, retorno de la inversión (ROI), retorno del capital (ROE) y muchos otros. La fabricación rastrea métricas como la producción y los defectos. Los recursos humanos medirán la retención y el desempeño de los empleados. Cada departamento o división de una empresa utiliza análisis para asegurarse de que haya una alineación y un progreso hacia los objetivos. El valor atípico a menudo ha sido el marketing. Incluso hoy, el 14 por ciento de las organizaciones de marketing no tienen un proceso de análisis, un reflejo de la renuencia histórica del marketing hacia el análisis.

El análisis de marketing (o marketing analytics) recopila datos de todos los canales de marketing y los consolida en una vista de marketing común. Desde esta visión común, puede extraer resultados analíticos que pueden proporcionar una asistencia invaluable para impulsar sus esfuerzos de marketing.Pero antes de iniciar, vamos a hablar de ciencia de los datos.

Ciencia de los datos

La ciencia de datos es un campo multidisciplinario que incluye estadística, computación, aprendizaje automático y dominios profesionales para obtener conocimiento e información de los datos. Además, permite describir un proceso semiautomático cuyo propósito principal es analizar un gran volumen de datos sobre un problema específico con el propósito de crear patrones en diferentes campos científicos. Esos patrones, encontrados en formas múltiples como asociaciones, anomalías, agrupaciones, clases, etc., constituyen estructuras o instancias, que aparecen en los datos y son estadísticamente significativas.La ciencia de datos usualmente termina desarrollando, a partir de estos patrones, un producto de datos. Un producto de datos es el cambio de los datos de una empresa/organización/ciudad en un producto para resolver un problema.

Por ejemplo, un producto de datos puede ser el sistema de recomendación de productos utilizado en Amazon y Lazada. Estas empresas tienen una gran cantidad de datos basados en las compras de los compradores. Usando estos datos, Amazon y Lazada pueden identificar los patrones de compra de los compradores y crear un sistema de recomendación o producto de datos para recomendar otros productos cada vez que un comprador compra un producto.

Marketing Analytics

A lo largo de los años, a medida que las empresas se expandieron a nuevas categorías de marketing, se adoptaron nuevas tecnologías para respaldarlas. Debido a que cada nueva tecnología se implementó normalmente de forma aislada, el resultado fue una mezcolanza de entornos de datos desconectados.

En consecuencia, los especialistas en marketing a menudo toman decisiones basadas en datos de canales individuales (marketing digital y métricas de sitios web, por ejemplo), sin tener en cuenta la imagen completa del marketing. Los datos de las redes sociales por sí solos no son suficientes. Los datos de análisis web por sí solos no son suficientes. Y las herramientas que miran solo una instantánea a tiempo para un solo canal son lamentablemente inadecuadas. La analítica de marketing, por el contrario, considera todos los esfuerzos de marketing en todos los canales durante un período de tiempo, que es esencial para una toma de decisiones sensata y una ejecución eficaz y eficiente del programa.

Pero ¿Qué es el marketing analytics? La analítica de marketing es el proceso de identificar métricas que son indicadores válidos del desempeño del marketing en la búsqueda de sus objetivos, rastrear esas métricas a lo largo del tiempo y usar los resultados para mejorar cómo funciona el marketing.

Los componentes más importantes son: Indicadores válidos Búsqueda de un objetivo Seguimientos de las métricas a lo largo del tiempo Mejora sobre cómo funciona el mercadeo

Y ¿cuál es el estado de marketing analytics en las empresas? Exploremos la figura 1 y 2, que nos muestran cómo se ayudan

Escenarios del marketing analytics Percepción de las empresas que hacen marketing analytics

Además, tendremos en cuenta los desafíos de la implementación de marketing. La figura 3 y 4 nos muestran los aspectos más importantes de este proceso.

Características de las organizaciones de marketing Desafíos del marketing analytics

Cómo pueden ver, la información y los productos de datos son resultados importantes de este proceso. A partir de esta información podemos:

  1. Comprender el desempeño del marketing: Para uso interno, las métricas que utiliza un proceso de análisis le indican al marketing cómo se está desempeñando. Para usar la metáfora del tablero, cuando los indicadores están en verde, el marketing puede continuar realizando su trabajo con confianza, incluso acelerando sus esfuerzos. Cuando los indicadores están en amarillo, es una indicación de que algo está a punto de fallar y necesita atención. Cuando los indicadores están en rojo, el marketing sabe con certeza que algo está roto, y el proceso roto requiere una revisión o un abandono en favor de algo mejor.

  2. Informar el desempeño del marketing: Para uso externo, el resultado del proceso de análisis, o al menos parte de él, es útil para mostrar al resto de la organización que está obteniendo un retorno de su inversión en marketing. Compartir los resultados de su trabajo crea confianza en toda la organización sobre lo que hace el marketing, lo que ayuda al CMO a mantener el lugar del marketing en la mesa de grandes decisiones.

Uso de los datos de marketing analytics Credibilidad de marketing analytics

Finalmente, ¿cuál es el proceso para lograr esto?

Proceso de marketing analytics

A lo largo de esta semana vamos a empezar a crear nuestros primeros productos de datos: tablas, gráficos y regresiones lineales. Sin embargo, hay que seguir un proceso para que los datos nos dé todo el potencial que tienen. Así pues, primero hay que “limpiar” nuestros datos y luego preguntarnos ¿qué queremos saber de nuestros datos?. Sabiendo esto, vamos a empezar.

Cargue de datos

Como vimos la clase pasada, algunos de los comandos que podemos utilizar para cargar datos son read.table()y read.csv(). Estas funciones están cargadas en R y RStudio. Sin embargo, también hay paquetes que nos ayudan a cargar los datos que recibimos. La base de datos que trabajaremos hoy se llama “Clase 2.csv”. Recuerden revisar su Working Directory y poner los datos ahí.

El día de hoy vamos a trabajar con el paquete readr para hacer el cargue de los datos. Readrnos permite no solamente leer archivos en .csv sino, por ejemplo, logs de páginas web. Todas las funciones de empiezan por read_ más la extensión del archivo. Para cargar el paquete y los datos haremos lo siguiente:

#Llamar el paquete para que funcione
library('readr')
## Warning: package 'readr' was built under R version 3.6.3
#Leer los datos
data1 <- read_csv("Clase 2.csv")
## Warning: Missing column names filled in: 'X1' [1]
## Parsed with column specification:
## cols(
##   .default = col_double(),
##   Name = col_character(),
##   Nationality = col_character(),
##   Club = col_character(),
##   `Preferred Foot` = col_character(),
##   `Work Rate` = col_character(),
##   `Body Type` = col_character(),
##   Position = col_character(),
##   Joined = col_character(),
##   `Contract Valid Until` = col_character(),
##   Height = col_character(),
##   Weight = col_character()
## )
## See spec(...) for full column specifications.

Como podemos observar, tenemos una gran cantidad de información en esta base de datos. Hagámonos una idea del tamaño usando la función dim()

dim(data1)
## [1] 18207    49

De las 49 variables que tenemos, necesitamos saber qué información recogen. Para ello, la función str() que vimos la clase pasada seguirá aplicando. Miremos los datos que acabamos de cargar:

str(data1)
## tibble [18,207 x 49] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ X1                      : num [1:18207] 0 1 2 3 4 5 6 7 8 9 ...
##  $ ID                      : num [1:18207] 158023 20801 190871 193080 192985 ...
##  $ Name                    : chr [1:18207] "L. Messi" "Cristiano Ronaldo" "Neymar Jr" "De Gea" ...
##  $ Age                     : num [1:18207] 31 33 26 27 27 27 32 31 32 25 ...
##  $ Nationality             : chr [1:18207] "Argentina" "Portugal" "Brazil" "Spain" ...
##  $ Overall                 : num [1:18207] 94 94 92 91 91 91 91 91 91 90 ...
##  $ Potential               : num [1:18207] 94 94 93 93 92 91 91 91 91 93 ...
##  $ Club                    : chr [1:18207] "FC Barcelona" "Juventus" "Paris Saint-Germain" "Manchester United" ...
##  $ Preferred Foot          : chr [1:18207] "Left" "Right" "Right" "Right" ...
##  $ International Reputation: num [1:18207] 5 5 5 4 4 4 4 5 4 3 ...
##  $ Weak Foot               : num [1:18207] 4 4 5 3 5 4 4 4 3 3 ...
##  $ Skill Moves             : num [1:18207] 4 5 5 1 4 4 4 3 3 1 ...
##  $ Work Rate               : chr [1:18207] "Medium/ Medium" "High/ Low" "High/ Medium" "Medium/ Medium" ...
##  $ Body Type               : chr [1:18207] "Messi" "C. Ronaldo" "Neymar" "Lean" ...
##  $ Position                : chr [1:18207] "RF" "ST" "LW" "GK" ...
##  $ Jersey Number           : num [1:18207] 10 7 10 1 7 10 10 9 15 1 ...
##  $ Joined                  : chr [1:18207] "Jul 1, 2004" "Jul 10, 2018" "Aug 3, 2017" "Jul 1, 2011" ...
##  $ Contract Valid Until    : chr [1:18207] "2021" "2022" "2022" "2020" ...
##  $ Height                  : chr [1:18207] "5'7" "6'2" "5'9" "6'4" ...
##  $ Weight                  : chr [1:18207] "159lbs" "183lbs" "150lbs" "168lbs" ...
##  $ Crossing                : num [1:18207] 84 84 79 17 93 81 86 77 66 13 ...
##  $ Finishing               : num [1:18207] 95 94 87 13 82 84 72 93 60 11 ...
##  $ HeadingAccuracy         : num [1:18207] 70 89 62 21 55 61 55 77 91 15 ...
##  $ ShortPassing            : num [1:18207] 90 81 84 50 92 89 93 82 78 29 ...
##  $ Volleys                 : num [1:18207] 86 87 84 13 82 80 76 88 66 13 ...
##  $ Dribbling               : num [1:18207] 97 88 96 18 86 95 90 87 63 12 ...
##  $ Curve                   : num [1:18207] 93 81 88 21 85 83 85 86 74 13 ...
##  $ FKAccuracy              : num [1:18207] 94 76 87 19 83 79 78 84 72 14 ...
##  $ LongPassing             : num [1:18207] 87 77 78 51 91 83 88 64 77 26 ...
##  $ BallControl             : num [1:18207] 96 94 95 42 91 94 93 90 84 16 ...
##  $ Acceleration            : num [1:18207] 91 89 94 57 78 94 80 86 76 43 ...
##  $ SprintSpeed             : num [1:18207] 86 91 90 58 76 88 72 75 75 60 ...
##  $ Agility                 : num [1:18207] 91 87 96 60 79 95 93 82 78 67 ...
##  $ Reactions               : num [1:18207] 95 96 94 90 91 90 90 92 85 86 ...
##  $ Balance                 : num [1:18207] 95 70 84 43 77 94 94 83 66 49 ...
##  $ ShotPower               : num [1:18207] 85 95 80 31 91 82 79 86 79 22 ...
##  $ Jumping                 : num [1:18207] 68 95 61 67 63 56 68 69 93 76 ...
##  $ Stamina                 : num [1:18207] 72 88 81 43 90 83 89 90 84 41 ...
##  $ Strength                : num [1:18207] 59 79 49 64 75 66 58 83 83 78 ...
##  $ LongShots               : num [1:18207] 94 93 82 12 91 80 82 85 59 12 ...
##  $ Aggression              : num [1:18207] 48 63 56 38 76 54 62 87 88 34 ...
##  $ Interceptions           : num [1:18207] 22 29 36 30 61 41 83 41 90 19 ...
##  $ Positioning             : num [1:18207] 94 95 89 12 87 87 79 92 60 11 ...
##  $ Vision                  : num [1:18207] 94 82 87 68 94 89 92 84 63 70 ...
##  $ Penalties               : num [1:18207] 75 85 81 40 79 86 82 85 75 11 ...
##  $ Composure               : num [1:18207] 96 95 94 68 88 91 84 85 82 70 ...
##  $ Marking                 : num [1:18207] 33 28 27 15 68 34 60 62 87 27 ...
##  $ StandingTackle          : num [1:18207] 28 31 24 21 58 27 76 45 92 12 ...
##  $ SlidingTackle           : num [1:18207] 26 23 33 13 51 22 73 38 91 18 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   X1 = col_double(),
##   ..   ID = col_double(),
##   ..   Name = col_character(),
##   ..   Age = col_double(),
##   ..   Nationality = col_character(),
##   ..   Overall = col_double(),
##   ..   Potential = col_double(),
##   ..   Club = col_character(),
##   ..   `Preferred Foot` = col_character(),
##   ..   `International Reputation` = col_double(),
##   ..   `Weak Foot` = col_double(),
##   ..   `Skill Moves` = col_double(),
##   ..   `Work Rate` = col_character(),
##   ..   `Body Type` = col_character(),
##   ..   Position = col_character(),
##   ..   `Jersey Number` = col_double(),
##   ..   Joined = col_character(),
##   ..   `Contract Valid Until` = col_character(),
##   ..   Height = col_character(),
##   ..   Weight = col_character(),
##   ..   Crossing = col_double(),
##   ..   Finishing = col_double(),
##   ..   HeadingAccuracy = col_double(),
##   ..   ShortPassing = col_double(),
##   ..   Volleys = col_double(),
##   ..   Dribbling = col_double(),
##   ..   Curve = col_double(),
##   ..   FKAccuracy = col_double(),
##   ..   LongPassing = col_double(),
##   ..   BallControl = col_double(),
##   ..   Acceleration = col_double(),
##   ..   SprintSpeed = col_double(),
##   ..   Agility = col_double(),
##   ..   Reactions = col_double(),
##   ..   Balance = col_double(),
##   ..   ShotPower = col_double(),
##   ..   Jumping = col_double(),
##   ..   Stamina = col_double(),
##   ..   Strength = col_double(),
##   ..   LongShots = col_double(),
##   ..   Aggression = col_double(),
##   ..   Interceptions = col_double(),
##   ..   Positioning = col_double(),
##   ..   Vision = col_double(),
##   ..   Penalties = col_double(),
##   ..   Composure = col_double(),
##   ..   Marking = col_double(),
##   ..   StandingTackle = col_double(),
##   ..   SlidingTackle = col_double()
##   .. )

¿Notaron algo en los datos que acabamos de cargar? Si miran detenidamente las columnas, tenemos problemas con la altura, el peso y el año en que se termina su contrato. Además, el nombre de la primera variable parece no existir. Para eso, iremos al segundo paso que todo científico de datos debe tener en cuenta, el preprocesamiento de los datos.

Preprocesamiento de datos.

Lo primero que hemos de detectar es qué información está incluida en las columnas que parece haber problemas. Para eso utilizaremos una función que vimos la clase pasada, unique(). Miremos cómo nos va:

# Los datos en Weight
unique(data1$Weight)
#Los datos en Height
unique(data1$Height)
#Los datos en Contract Valid Until
unique(data1$`Contract Valid Until`)

Dado que hemos visto que, por lo menos, en estas tres variables tenemos datos que son NA, lo primero que debemos hacer es eliminar estos datos. Para eso usaremos la función na.omit(). Esta función eliminará todos los registros que sean NA de cualquiera de las variables.

data2 <- na.omit(data1)

Ya nos aseguramos de que al menos no hay valores vacíos. Lo siguiente es arreglar el peso. Para eso debemos extraer el valor de la columna usando la función parse.number(). Esta función nos permitirá eliminar las letras antes y después del primer número disponible. La aplicaremos a la variable peso para que la podamos usar.

data2$Weight <- parse_number(data2$Weight)

Lo siguiente es eliminar los datos que no nos sirven de Contract valid until. Para esto, usaremos solamente las que nos interesan y las seleccionaremos usando expresiones lógicas. Miremos cómo funciona:

data3 <- data2[data2$`Contract Valid Until` <= 2021 & data2$`Contract Valid Until`>= 2018,]

Si revisamos, estos datos todavía aparecen como caracteres. ¿Qué hacer ahí? Vamos a convertir la variable en numérica usando la función as.numeric(). Miremos cómo lo hacemos:

data3$`Contract Valid Until` <- as.numeric(data3$`Contract Valid Until`)

Para la altura, debemos entender cuál es el problema que tenemos. ¿Qué es lo que pasa con esta variable? Al estar en una medida inglesa no podemos hacer operaciones con estas variables. Por tanto, lo que tendremos que hacer es usar la función substr(). Una vez separados los datos, haremos las operaciones respectivas para convertirlos en datos útiles.

#Extraemos los dos valores
pies <- substr(data3$Height, start = 1, stop = 1)
pulgadas <- substr(data3$Height, start = 3, stop = 3)
#Convertimos las columnas en números
pies <- as.numeric(pies)
pulgadas <- as.numeric(pulgadas)
#Asignamos la conversión a la variable
data3$Height <- pies * 0.3 + pulgadas * 0.03

Finalmente, nuestra primera variable nos dice que su nombre está mal ¿cómo lo cambiamos? Fácil, usaremos el comando colnames()

colnames(data3)[1] <- "Indicador"

Aunque esta revisión de datos no fue exhaustiva, hay otra forma de mirar toda la información que tenemos. Para eso vamos a utilizar la función summary().

summary(data3)

¿Y qué podemos hacer ya cuándo los datos están limpios? Fácil, nos empezaremos a hacer las preguntas importantes sobre nuestros datos.

Formular preguntas de nuestros datos

Formular una pregunta puede ser una forma útil de guiar el proceso de análisis de datos exploratorios y limitar el número exponencial de rutas que se pueden tomar con cualquier conjunto de datos de tamaño considerable. En particular, una pregunta aguda o hipótesis puede servir como una herramienta de reducción de dimensión que puede eliminar variables que no son inmediatamente relevantes para la pregunta.

Por ejemplo, en este capítulo veremos un conjunto de datos de los jugadores que están en este momento inscritos en la FIFA para el año 2019. Una pregunta general podría ser:

*¿Los niveles de desempeño de un jugador son más altos si son más ágiles?

Pero una pregunta más específica podría ser

*¿Los niveles de desempeño potencial de un jugador son más altos para los jugadores esbeltos que para los jugadores normales?

Tenga en cuenta que ambas preguntas pueden ser de interés y que ninguna es correcta o incorrecta. Pero la primera pregunta requiere analizar todos los tipos de desempeño en todas las variables, mientras que la segunda pregunta solo requiere observar un solo tipo de desempeño en dos tipos de cuerpos.

Por lo general, es una buena idea dedicar unos minutos a averiguar cuál es la pregunta que realmente le interesa y reducirla para que sea lo más específica posible (sin dejar de ser interesante).

Para este capítulo, no nos centraremos en una pregunta específica, ya que veremos a lo largo del tiempo iremos cambiando la pregunta.

Como nota al margen, una de las preguntas más importantes que puede responder con un análisis exploratorio de datos es “¿Tengo los datos correctos para responder a esta pregunta?” A menudo, esta pregunta es difícil de responder al principio, pero puede ser más clara a medida que ordenamos y miramos los datos.

Para eso, empezaremos con las medidas de tendencia central.

Medidas de tendencia central y dispersión

Las medidas de posición (o medidas de tendencia central) describen brevemente la ubicación de los datos en la recta numérica real. Especifican un punto central alrededor del cual los datos tienen la tendencia a reunirse. Las medidas de posición más importantes son la moda, la media y la mediana.

La primera de la medida que expondremos es la moda. Dado que no existe una función específica en R (sin usar un paquete). Para hacerlo, usaremos la tabla de frecuencias y calcularemos el valor máximo. Nota: usaremos una variable que nos interese conocer

table(data3$Age)

La siguiente medida que nos interesa es la media. Esta es la medida más popular, y se calcula con la función mean():

mean(data3$Age)

Por último, nos interesa conocer la mediana. La mediana es el valor de la observación mediana, cuando las observaciones se ordenan en orden ascendente o descendente. Si el número de observaciones (n) es un número impar, entonces la observación mediana es el (n + 1) / 2, mientras que si el número de observaciones es un número par, tenemos dos observaciones de la mediana en las posiciones n / 2 yn / 2 +1, entonces la mediana es el valor medio de estos dos valores. Para calcularla, usaremos la función median():

median(data3$Age)

Ahora trataremos las medidas de dispersión. Estas medidas describen brevemente la variabilidad de los datos en la recta numérica real. En otras palabras, revelan la variabilidad de las observaciones. La variabilidad no siempre es clara a partir de las medidas de posición, como por ejemplo la media. Si los datos se recopilan alrededor de la media, por ejemplo, si la varianza es baja, la media puede representar datos de manera bastante efectiva. Sin embargo, en el escenario opuesto, las medidas de posición no proporcionan una manera efectiva de describir los datos. Para esto, las medidas de dispersión más importantes, que se describen más adelante, son el rango, la varianza, la desviación estándar, el coeficiente de variación y los valores percentiles.

Para calcular el rango tenemos dos opciones. Primero, usando los valores mínimos y máximos de la función y la segunda usando la función range():

#Versión 1: valores mínimos y máximos
minimo <- min(data3$Age)
maximo <- max(data3$Age)
maximo - minimo
## [1] 29
#Versión 2: función range

range(data3$Age)
## [1] 16 45
range(data3$Age)[2] - range(data3$Age)[1]
## [1] 29

El valor del percentil p de una muestra con n observaciones, se define como la observación para la cual el p% de las observaciones son más pequeñas que él y el (1-p)% de las observaciones son mayores que este. Para calcular estos cuantiles usaremos la función quantile():

quantile(data3$Age, 0.75, type=7)
## 75% 
##  29

La varianza es el promedio de las diferencias al cuadrado de la media, y se usa para medir la extensión de los datos. Para calcular este valor, se usa la función var()

var(data3$Age)
## [1] 23.36141

Sin embargo, hay que hacer una aclaración. Esta es la varianza de la muestra, no de la población. Para ajustar este valor, deberá multiplicar por el tamaño de la muestra menos 1 y dividir por el tamaño de la muestra.

La desviación estándar es la raíz cuadrada de una varianza y mide la dispersión de los datos. Las variaciones se incrementan cuando hay más variaciones y se reducen cuando hay variaciones menores, porque la variación es un resultado cuadrado. Con la desviación estándar, la varianza es la raíz cuadrada, por lo que es más fácil de visualizar y aplicar. Para calcular la desviación estándar usaremos la función sd()

sd(data3$Age)
## [1] 4.833364

Ahora, ¿con estos datos puedo construir intervalos de confianza? Claro que si, ya tenemos suficiente información para lograr este resultado.

Visualización de datos

Datos cualitativos

En este capítulo presentaremos las formas que podemos utilizar para visualizar nuestras observaciones. La visualización puede realizarse con vectores y tablas, pero también mediante diagramas como histogramas, gráficos de barras, gráficos circulares, etc. En cada caso, es muy importante distinguir nuestras observaciones en datos cuantitativos o cualitativos. Comenzamos con datos cualitativos, que generalmente se representan con tablas, gráficos de barras y gráficos circulares.

Lo primero que haremos será crear tablas de frecuencia. Para esto usaremos el comando table():

table(data3$`Body Type`)
## 
## Akinfenwa      Lean     Messi    Normal    Stocky 
##         1      4917         1      8302       871

Si lo que deseamos no son la frecuencias absolutas sino las frecuencias relativas usaremos la función prop.table() sobre la función table:

prop.table(table(data3$`Body Type`))*100
## 
##    Akinfenwa         Lean        Messi       Normal       Stocky 
##  0.007096225 34.892137383  0.007096225 58.912858359  6.180811808

También podemos crear matrices de contingencia. Una matriz de contingencia tiene que ver con dos variables categóricas y muestra su distribución de frecuencia. Estas las creamos igual que las tablas de frecuencia:

table(data3$`Body Type`, data3$`Preferred Foot`)
##            
##             Left Right
##   Akinfenwa    0     1
##   Lean      1205  3712
##   Messi        1     0
##   Normal    1815  6487
##   Stocky     186   685
prop.table(table(data3$`Body Type`, data3$`Preferred Foot`))*100
##            
##                     Left        Right
##   Akinfenwa  0.000000000  0.007096225
##   Lean       8.550950894 26.341186489
##   Messi      0.007096225  0.000000000
##   Normal    12.879648027 46.033210332
##   Stocky     1.319897814  4.860913994

Ahora, trataremos de visualizar los datos a través de gráficas de barras. Para eso utilizaremos dos versiones, los gráficos de R y el paquete ggplot2. ggplot2 es un paquete que ofrece un poderoso lenguaje que permite crear gráficos que representan datos univariados, multivariados y categóricos de manera directa. La funcionalidad incorporada de R ofrece el trazado de gráficos, pero ggplot nos permite trazar gráficos más avanzados utilizando la gramática de gráficos. Sin embargo, dado que el curso es muy corto, les dejaré explorar las funcionalidades de ggplot2 en este link: https://cran.r-project.org/web/packages/ggplot2/ggplot2.pdf

Primero crearemos la gráfica con barplot() sobre la tabla de frecuencias relativas:

barplot(table(data3$`Body Type`))

Ahora haremos la versión de ggplot. Para esto, usaremos la función ggplot()y le añadiremos una capa con la función geom_bar():

#Primero cargamos el paquete
library("ggplot2")
## Warning: package 'ggplot2' was built under R version 3.6.3
#Usamos ggplot2 para crear los gráficos
ggplot(data3) + geom_bar(aes(x=data3$`Body Type`, fill="red"))
## Warning: Use of `data3$`Body Type`` is discouraged. Use `Body Type` instead.

Finalmente, si queremos un gráfico de pie o circular, con R podemos usar el comando pie:

pie(table(data3$`Body Type`))

O si lo queremos hacer con ggplot2, lo que debemos hacer es añadir otra capa al gráfico que indique que las coordenadas son polares

ggplot(data3) + geom_bar(aes(x=data3$`Body Type`), fill="red") + coord_polar()
## Warning: Use of `data3$`Body Type`` is discouraged. Use `Body Type` instead.

Datos cuantitativos

La primera tabla que veremos será la misma que en el caso anterior, la tabla de frecuencia. No lo explicaremos de nuevo, pero es una opción. Acá nos centraremos en tres tipos de gráficas, los histogramas, los gráficos de dispersión y los diagramas de caja.

un histograma es una representación gráfica de una variable en forma de barras, donde la superficie de cada barra es proporcional a la frecuencia de los valores representados. Sirven para obtener una “primera vista” general, o panorama, de la distribución de la población, o de la muestra, respecto a una característica, cuantitativa y continua (como la longitud o el peso).

Para representar un histograma con R, la función que utilizaremos será hist() y para personalizar la clases usaremos nclass:

hist(data3$Potential, nclass = 50)

Para crear un histograma con ggplot2, usaremos la capa geom_histogram() y las clases se personalizan con binds o binwidth:

ggplot(data3, aes(x=data3$Potential)) + geom_histogram(binwidth = 1)
## Warning: Use of `data3$Potential` is discouraged. Use `Potential` instead.

El diagrama de caja es una forma adecuada de mostrar las características más importantes de la distribución de observación de las muestras. El diagrama de caja es un rectángulo basado en los valores del primer, segundo (mediana) y tercer cuartil, mientras que los bigotes varían desde el valor más pequeño hasta el más alto de las observaciones.

Para crear estos gráficos en R usaremos la función boxplot():

boxplot(data3$Potential)

boxplot(data3$Potential, data3$Overall)

Para hacer un boxplot en ggplot2 usaremos la capa geom_boxplot. Pero antes usaremos el preferred foot como un factor para hacer la comparación:

data3$`Preferred Foot`<- as.factor(data3$`Preferred Foot`)
ggplot(data3, aes(x=data3$`Preferred Foot`, y=data3$Potential)) + geom_boxplot(fill="grey") + labs(title="boxplot")
## Warning: Use of `data3$`Preferred Foot`` is discouraged. Use `Preferred Foot`
## instead.
## Warning: Use of `data3$Potential` is discouraged. Use `Potential` instead.

Finalmente, haremos un gráfico de dispersión para mirar la relación entre dos variables. Para esto, usaremos el graficador por excelencia de R, plot():

plot(data3$Potential ~ data3$Crossing)

Para hacer estos gráficos en ggplot2, la capa que agregaremos será geom_point():

ggplot(data3) + geom_point(aes(color="red", x=Potential, y=Crossing))

Ok, hemos finalizado el análisis exploratorio de datos. ¿Eso quiere decir que ya acabé? No, eso quiere decir que ahora va a empezar lo más interesante. Vamos a terminar la clase hablando de uno de los modelos por excelencia para la toma de decisiones basada en datos, la regresión lineal. Pero…y la relación de las variables. Tranquilos, empezaremos por hablar de correlaciones.

Para calcular la relación entre las variables tengo dos opciones, la correlación bivariada o la correlación parcial. Si deseo calcular la correlación bivariada podemos usar la función cor() o cor.test():

cor(data3$Height,data3$Potential)
## [1] -0.002380412
cor.test(data3$Height,data3$Potential)
## 
##  Pearson's product-moment correlation
## 
## data:  data3$Height and data3$Potential
## t = -0.28256, df = 14090, p-value = 0.7775
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.01889049  0.01413096
## sample estimates:
##          cor 
## -0.002380412

Regresiones lineales

El análisis de regresión implica identificar relaciones entre variables. Dado un conjunto de variables independientes o predictoras, nuestro objetivo es predecir una variable dependiente o objetivo. En el análisis de regresión, la variable objetivo es numérica y las variables predictoras pueden ser numéricas, categóricas u ordinales.

Empezaremos con el modelo de regresión más sencillo, la regresión lineal simple. La regresión lineal simple es un caso especial de regresión lineal con una sola variable predictiva x y una variable objetivo y. Para realizar una regresión usaremos el comando lm():

reg1 <- lm(data3$Acceleration ~ data3$Weight)
reg1
## 
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight)
## 
## Coefficients:
##  (Intercept)  data3$Weight  
##     141.4277       -0.4673
summary(reg1)
## 
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -62.747  -7.130   1.599   8.870  37.355 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  141.427706   1.196572   118.2   <2e-16 ***
## data3$Weight  -0.467279   0.007178   -65.1   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 13.28 on 14090 degrees of freedom
## Multiple R-squared:  0.2312, Adjusted R-squared:  0.2312 
## F-statistic:  4238 on 1 and 14090 DF,  p-value: < 2.2e-16

Si queremos ver que tan bien nos fue con los datos, usando un gráfico de dispersión de nuestras variables podemos añadir nuestra línea de regresión con la función abline().

plot(data3$Acceleration ~ data3$Weight)
abline(reg1)

Si queremos una regresión que pase por el origen (sin intercepto) deberemos usar la siguiente expresión:

reg2 <- lm(data3$Acceleration ~ data3$Weight - 1)
summary(reg2)
## 
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight - 1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -69.067  -9.404   4.729  14.483  45.692 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## data3$Weight 0.3774029  0.0009466   398.7   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.73 on 14091 degrees of freedom
## Multiple R-squared:  0.9186, Adjusted R-squared:  0.9186 
## F-statistic: 1.589e+05 on 1 and 14091 DF,  p-value: < 2.2e-16
plot(data3$Acceleration ~ data3$Weight)
abline(reg2)

Para la regresión lineal múltiple, a las variables predictoras las agregaremos con el comando +:

reg3 <- lm(data3$Acceleration ~ data3$Weight + data3$`Preferred Foot`+ data3$Height)
summary(reg3)
## 
## Call:
## lm(formula = data3$Acceleration ~ data3$Weight + data3$`Preferred Foot` + 
##     data3$Height)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -58.245  -6.985   1.284   8.583  38.292 
## 
## Coefficients:
##                              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                 168.49638    1.52321  110.62   <2e-16 ***
## data3$Weight                 -0.37007    0.00781  -47.38   <2e-16 ***
## data3$`Preferred Foot`Right  -2.96994    0.25989  -11.43   <2e-16 ***
## data3$Height                -23.55001    0.89578  -26.29   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 12.9 on 14088 degrees of freedom
## Multiple R-squared:  0.274,  Adjusted R-squared:  0.2738 
## F-statistic:  1772 on 3 and 14088 DF,  p-value: < 2.2e-16

Sin embargo, hay una trinidad que debemos revisar para asegurar que se cumplan tres condiciones: multicolinealidad, heterocedasticidad y independencia de los residuos.

Para determinar si los residuos son independientes, usaremos un gráfico QQ. Usaremos las funciones qqnorm() y qqline():

plot(reg3$residuals)

qqnorm(reg3$residuals)
qqline(reg3$residuals)

Además, podemos usar el test de Durbin Watson para saber si se comportan normalmente. La función que nos permite hacer eso es durbinWatsonTest() de la librería car.

library(car)
## Warning: package 'car' was built under R version 3.6.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 3.6.3
durbinWatsonTest(reg3)
##  lag Autocorrelation D-W Statistic p-value
##    1      0.09085532      1.818067       0
##  Alternative hypothesis: rho != 0

¿Cómo podríamos hacer las otras pruebas? Esa será su tarea, construyan su código para resolver estos problemas.

Taller

Ahora que ya hemos visto las formas de entender los datos, ustedes deberán hacer su propia investigación con la base de datos que tienen. Háganse al menos 5 preguntas sobre sus datos y traten de resolverlas usando lo que aprendimos el día de hoy.