diff --git a/01-exploratorio.md b/01-exploratorio.md index bb3d997..dd50215 100644 --- a/01-exploratorio.md +++ b/01-exploratorio.md @@ -67,23 +67,23 @@ slice_sample(propinas, n = 10) |> gt() ``` ```{=html} -
- @@ -528,62 +528,62 @@ slice_sample(propinas, n = 10) |> gt() - 15.36 -1.64 + 28.15 +3.00 Si Sab Cena -2 - 35.26 -5.00 +5 + 12.54 +2.50 No Dom Cena -4 - 18.15 -3.50 +2 + 10.63 +2.00 +Si +Sab +Cena +2 + 20.29 +3.21 Si +Sab +Cena +2 + 9.94 +1.56 +No Dom Cena -3 - 41.19 -5.00 +2 + 12.43 +1.80 No Jue Comida -5 - 9.68 -1.32 -No -Dom -Cena 2 - 16.21 -2.00 + 15.98 +2.03 No -Dom -Cena -3 - 20.76 -2.24 +Jue +Comida +2 + 19.49 +3.51 No Dom Cena 2 - 22.67 -2.00 -Si -Sab -Cena -2 - 7.74 -1.44 -Si + 18.35 +2.50 +No Sab Cena -2 - 44.30 -2.50 +4 + 26.59 +3.41 Si Sab Cena @@ -636,23 +636,23 @@ bind_rows(head(cuenta), tail(cuenta)) |> ``` ```{=html} -
- @@ -1212,7 +1212,7 @@ cada $x_{(i)}$ definimos\ $$f_i = i / N$$ entonces definimos el cuantil $q(f_i)=x_{(i)}$. Para cualquier $f$ entre 0 y 1, podemos definir $q(f)$ como sigue: si $f$ está entre $f_i$ y $f_{i+1}$ interpolamos linealmente los valores -correspondientes $x_{(i)}$ y $x_{(i-1)}$. +correspondientes $x_{(i)}$ y $x_{(i+1)}$. En la práctica, es más conveniente usar $f_i= \frac{i - 0.5}{N}$. La gráfica de cuantiles no cambia mucho comparado con la difinición @@ -1485,6 +1485,7 @@ varía la mediana entre zonas: casas |> group_by(nombre_zona) |> summarise(mediana_zona = median(precio_m2), .groups = "drop") |> + arrange(mediana_zona) |> pull(mediana_zona) |> quantile() |> round() @@ -1524,6 +1525,7 @@ Podemos resumir este primer análisis con un par de gráficas de cuantiles ``` r mediana <- median(casas$precio_m2) resumen <- casas |> + select(nombre_zona, precio_m2) |> group_by(nombre_zona) |> mutate(mediana_zona = median(precio_m2)) |> mutate(residual = precio_m2 - mediana_zona) |> diff --git "a/an\303\241lisis-exploratorio.html" "b/an\303\241lisis-exploratorio.html" index 9f7d84f..5459c73 100644 --- "a/an\303\241lisis-exploratorio.html" +++ "b/an\303\241lisis-exploratorio.html" @@ -287,23 +287,23 @@

Algunos conceptos básicospropinas <- read_csv("./data/propinas.csv")

Y vemos una muestra

slice_sample(propinas, n = 10) |> gt()
-
- @@ -748,62 +748,62 @@

Algunos conceptos básicos - 15.36 -1.64 + 28.15 +3.00 Si Sab Cena -2 - 35.26 -5.00 +5 + 12.54 +2.50 No Dom Cena -4 - 18.15 -3.50 +2 + 10.63 +2.00 +Si +Sab +Cena +2 + 20.29 +3.21 Si +Sab +Cena +2 + 9.94 +1.56 +No Dom Cena -3 - 41.19 -5.00 +2 + 12.43 +1.80 No Jue Comida -5 - 9.68 -1.32 -No -Dom -Cena 2 - 16.21 -2.00 + 15.98 +2.03 No -Dom -Cena -3 - 20.76 -2.24 +Jue +Comida +2 + 19.49 +3.51 No Dom Cena 2 - 22.67 -2.00 -Si -Sab -Cena -2 - 7.74 -1.44 -Si + 18.35 +2.50 +No Sab Cena -2 - 44.30 -2.50 +4 + 26.59 +3.41 Si Sab Cena @@ -846,23 +846,23 @@

Algunos conceptos básicos arrange(f) bind_rows(head(cuenta), tail(cuenta)) |> gt() |> fmt_number(columns = f, decimals = 3)

-
- @@ -1419,7 +1419,7 @@

Algunos conceptos básicos\[f_i = i / N\] entonces definimos el cuantil \(q(f_i)=x_{(i)}\). Para cualquier \(f\) entre 0 y 1, podemos definir \(q(f)\) como sigue: si \(f\) está entre \(f_i\) y \(f_{i+1}\) interpolamos linealmente los valores -correspondientes \(x_{(i)}\) y \(x_{(i-1)}\).

+correspondientes \(x_{(i)}\) y \(x_{(i+1)}\).

En la práctica, es más conveniente usar \(f_i= \frac{i - 0.5}{N}\). La gráfica de cuantiles no cambia mucho comparado con la difinición anterior, y esto nos permitirá comparar de mejor manera con @@ -1625,9 +1625,10 @@

Precios de casas
casas |>
   group_by(nombre_zona) |>
   summarise(mediana_zona = median(precio_m2), .groups = "drop") |>
-  pull(mediana_zona) |>
-  quantile() |>
-  round()

+ arrange(mediana_zona) |> + pull(mediana_zona) |> + quantile() |> + round()
##   0%  25%  50%  75% 100% 
 ##  963 1219 1298 1420 1725

Por otro lado, las variaciones con respecto a las medianas dentro de @@ -1647,19 +1648,20 @@

Precios de casasWilliam S. Cleveland (1993)):

mediana <- median(casas$precio_m2)
 resumen <- casas |>
-  group_by(nombre_zona) |>
-  mutate(mediana_zona = median(precio_m2)) |>
-  mutate(residual = precio_m2 - mediana_zona) |>
-  ungroup() |>
-  mutate(mediana_zona = mediana_zona - mediana) |>
-  select(nombre_zona, mediana_zona, residual) |>
-  pivot_longer(mediana_zona:residual, names_to = "tipo", values_to = "valor")
-ggplot(resumen, aes(sample = valor)) +
-  geom_qq(distribution = stats::qunif) +
-  facet_wrap(~ tipo) +
-  ylab("Precio por m2") + xlab("f") +
-  labs(subtitle = "Precio por m2 por zona",
-       caption = paste0("Mediana total de ", round(mediana)))
+ select(nombre_zona, precio_m2) |> + group_by(nombre_zona) |> + mutate(mediana_zona = median(precio_m2)) |> + mutate(residual = precio_m2 - mediana_zona) |> + ungroup() |> + mutate(mediana_zona = mediana_zona - mediana) |> + select(nombre_zona, mediana_zona, residual) |> + pivot_longer(mediana_zona:residual, names_to = "tipo", values_to = "valor") +ggplot(resumen, aes(sample = valor)) + + geom_qq(distribution = stats::qunif) + + facet_wrap(~ tipo) + + ylab("Precio por m2") + xlab("f") + + labs(subtitle = "Precio por m2 por zona", + caption = paste0("Mediana total de ", round(mediana)))

Vemos que la mayor parte de la variación del precio por metro cuadrado ocurre dentro de cada zona, una vez que controlamos por el tamaño de las diff --git a/index.html b/index.html index b4e57c7..e89e0ce 100644 --- a/index.html +++ b/index.html @@ -258,7 +258,7 @@

Ligashttps://itam.zoom.us/j/92745909276
-
  • Zoom sesiones de dudas (viernes 3:00-3:45 pm): https://itam.zoom.us/j/92518922348
    +
  • Zoom sesiones de dudas (lunes y viernes de 5:00-6:00 pm): https://itam.zoom.us/j/92518922348
  • Canvas: https://itam.instructure.com/courses/13328
  • diff --git a/index.md b/index.md index 16d82e6..ed83c69 100644 --- a/index.md +++ b/index.md @@ -24,7 +24,7 @@ Notas del curso *Fundamentos de Estadística con Remuestreo*, este curso busca e - Repositorio con material: \ - Correo: [teresa.ortiz.mancera\@gmail.com](mailto:teresa.ortiz.mancera@gmail.com)\ - Zoom clase (miércoles 4:00-7:00 pm): \ -- Zoom sesiones de dudas (viernes 3:00-3:45 pm): \ +- Zoom sesiones de dudas (lunes y viernes de 5:00-6:00 pm): \ - Canvas: \
    diff --git a/search_index.json b/search_index.json index 9754303..89b1236 100644 --- a/search_index.json +++ b/search_index.json @@ -1 +1 @@ -[["index.html", "Fundamentos de Estadística con Remuestreo Información del curso", " Fundamentos de Estadística con Remuestreo Teresa Ortiz, Felipe González, Alfredo Garbuno Información del curso Notas del curso Fundamentos de Estadística con Remuestreo, este curso busca explicar los principios básicos de la estadística y su papel en el análisis de datos. Nuestro punto de vista es uno de fundamentos, con menos énfasis en recetas o técnicas particulares. Ligas Notas: https://tereom.github.io/fundamentos-2024/ Repositorio con material: https://github.com/tereom/fundamentos-2024 Correo: teresa.ortiz.mancera@gmail.com Zoom clase (miércoles 4:00-7:00 pm): https://itam.zoom.us/j/92745909276 Zoom sesiones de dudas (viernes 3:00-3:45 pm): https://itam.zoom.us/j/92518922348 Canvas: https://itam.instructure.com/courses/13328 Este trabajo está bajo una Licencia Creative Commons Atribución 4.0 Internacional. "],["temario.html", "Temario Plan semanal Evaluación", " Temario Plan semanal Datos y análisis exploratorio Referencias: (W. S. Cleveland 1994), (Chihara and Hesterberg 2018) Visualización1 Análisis exploratorio Tipos de datos o estudios Muestras diseñadas y muestras naturales Experimentos y datos observacionales Introducción a Pruebas de Hipótesis Referencias: (Chihara and Hesterberg 2018) Introducción a pruebas de hipótesis. Pruebas de permutaciones Muestras pareadas y otros ejemplos Estimación y distribución de muestreo Referencias: (Chihara and Hesterberg 2018), (Hesterberg 2015) Estimadores y su distribución de muestreo Repaso de probabilidad y Teorema del límite central Introducción a estimación por intervalos Referencias: (Chihara and Hesterberg 2018), (Efron and Tibshirani 1993), (Hesterberg 2015) El método plugin y el boostrap Bootstrap e Intervalos de confianza. Ejemplos. Estimación Referencias: (Chihara and Hesterberg 2018), (Wasserman 2013) Estimación por máxima verosimilitud Ejemplos de estimación por máxima verosimilitud y Bootstrap paramétrico Propiedades de estimadores de máxima verosimilitud Más de pruebas de hipótesis Referencias: (Chihara and Hesterberg 2018), (Wasserman 2013) Pruebas de hipótesis para medias y proporciones: una y dos poblaciones. Introducción a inferencia bayesiana Referencias: (Kruschke 2015) Introducción a inferencia bayesiana Ejemplos de distribuciones conjugadas Introducción a métodos computacionales básicos: Muestreadores Metrópolis y Gibbs Ejemplos de inferencia bayesiana en Stan Evaluación Se evaluará mediante tareas semanales y dos exámenes: Tareas semanales (20%) Examen parcial en clase y a casa (40%) Examen final a casa (40%) Referencias "],["análisis-exploratorio.html", "Sección 1 Análisis exploratorio El papel de la exploración en el análisis de datos Preguntas y datos Algunos conceptos básicos Ejemplos Suavizamiento loess Caso de estudio: nacimientos en México", " Sección 1 Análisis exploratorio “Exploratory data analysis can never be the whole story, but nothing else can serve as the foundation stone –as the first step.” — John Tukey El papel de la exploración en el análisis de datos El estándar científico para contestar preguntas o tomar decisiones es uno que se basa en el análisis de datos. Es decir, en primer lugar se deben reunir todos los datos que puedan contener o sugerir alguna guía para entender mejor la pregunta o la decisión a la que nos enfrentamos. Esta recopilación de datos —que pueden ser cualitativos, cuantitativos, o una mezcla de los dos— debe entonces ser analizada para extraer información relevante para nuestro problema. En análisis de datos existen dos distintos tipos de trabajo: El trabajo exploratorio o de detective: ¿cuáles son los aspectos importantes de estos datos? ¿qué indicaciones generales muestran los datos? ¿qué tareas de análisis debemos empezar haciendo? ¿cuáles son los caminos generales para formular con precisión y contestar algunas preguntas que nos interesen? El trabajo inferencial, confirmatorio, o de juez: ¿cómo evaluar el peso de la evidencia de los descubrimientos del paso anterior? ¿qué tan bien soportadas están las respuestas y conclusiones por nuestro conjunto de datos? Preguntas y datos Cuando observamos un conjunto de datos, independientemente de su tamaño, el paso inicial más importante es entender bajo qué proceso se generan los datos. A grandes rasgos, cuanto más sepamos de este proceso, mejor podemos contestar preguntas de interés. En muchos casos, tendremos que hacer algunos supuestos de cómo se generan estos datos para dar respuestas (condicionales a esos supuestos). Algunos conceptos básicos Empezamos explicando algunas ideas que no serán útiles más adelante. El primer concepto se refiere a entender cómo se distribuyen los datos a los largo de su escala de medición. Comenzamos con un ejemplo: los siguientes datos fueron registrados en un restaurante durante cuatro días consecutivos. library(tidyverse) library(patchwork) # organizar gráficas library(gt) # formatear tablas source("R/funciones_auxiliares.R") # usamos los datos tips del paquete reshape2 propinas <- read_csv("./data/propinas.csv") Y vemos una muestra slice_sample(propinas, n = 10) |> gt() #uflqawelmg table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #uflqawelmg thead, #uflqawelmg tbody, #uflqawelmg tfoot, #uflqawelmg tr, #uflqawelmg td, #uflqawelmg th { border-style: none; } #uflqawelmg p { margin: 0; padding: 0; } #uflqawelmg .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #uflqawelmg .gt_caption { padding-top: 4px; padding-bottom: 4px; } #uflqawelmg .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #uflqawelmg .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #uflqawelmg .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #uflqawelmg .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #uflqawelmg .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #uflqawelmg .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #uflqawelmg .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #uflqawelmg .gt_column_spanner_outer:first-child { padding-left: 0; } #uflqawelmg .gt_column_spanner_outer:last-child { padding-right: 0; } #uflqawelmg .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #uflqawelmg .gt_spanner_row { border-bottom-style: hidden; } #uflqawelmg .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #uflqawelmg .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #uflqawelmg .gt_from_md > :first-child { margin-top: 0; } #uflqawelmg .gt_from_md > :last-child { margin-bottom: 0; } #uflqawelmg .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #uflqawelmg .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #uflqawelmg .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #uflqawelmg .gt_row_group_first td { border-top-width: 2px; } #uflqawelmg .gt_row_group_first th { border-top-width: 2px; } #uflqawelmg .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #uflqawelmg .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #uflqawelmg .gt_first_summary_row.thick { border-top-width: 2px; } #uflqawelmg .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #uflqawelmg .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #uflqawelmg .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #uflqawelmg .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #uflqawelmg .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #uflqawelmg .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #uflqawelmg .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #uflqawelmg .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #uflqawelmg .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #uflqawelmg .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #uflqawelmg .gt_left { text-align: left; } #uflqawelmg .gt_center { text-align: center; } #uflqawelmg .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #uflqawelmg .gt_font_normal { font-weight: normal; } #uflqawelmg .gt_font_bold { font-weight: bold; } #uflqawelmg .gt_font_italic { font-style: italic; } #uflqawelmg .gt_super { font-size: 65%; } #uflqawelmg .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #uflqawelmg .gt_asterisk { font-size: 100%; vertical-align: 0; } #uflqawelmg .gt_indent_1 { text-indent: 5px; } #uflqawelmg .gt_indent_2 { text-indent: 10px; } #uflqawelmg .gt_indent_3 { text-indent: 15px; } #uflqawelmg .gt_indent_4 { text-indent: 20px; } #uflqawelmg .gt_indent_5 { text-indent: 25px; } #uflqawelmg .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #uflqawelmg div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } cuenta_total propina fumador dia momento num_personas 15.36 1.64 Si Sab Cena 2 35.26 5.00 No Dom Cena 4 18.15 3.50 Si Dom Cena 3 41.19 5.00 No Jue Comida 5 9.68 1.32 No Dom Cena 2 16.21 2.00 No Dom Cena 3 20.76 2.24 No Dom Cena 2 22.67 2.00 Si Sab Cena 2 7.74 1.44 Si Sab Cena 2 44.30 2.50 Si Sab Cena 3 Aquí la unidad de observación es una cuenta particular. Tenemos tres mediciones numéricas de cada cuenta: cúanto fue la cuenta total, la propina, y el número de personas asociadas a la cuenta. Los datos están separados según se fumó o no en la mesa, y temporalmente en dos partes: el día (Jueves, Viernes, Sábado o Domingo), cada uno separado por Cena y Comida. Denotamos por \\(x\\) el valor de medición de una unidad de observación. Usualmente utilizamos sub-índices para identificar entre diferentes puntos de datos (observaciones), por ejemplo, \\(x_n\\) para la \\(n-\\)ésima observación. De tal forma que una colección de \\(N\\) observaciones la escribimos como \\[\\begin{align} \\{x_1, \\ldots, x_N\\}. \\end{align}\\] El primer tipo de comparaciones que nos interesa hacer es para una medición: ¿Varían mucho o poco los datos de un tipo de medición? ¿Cuáles son valores típicos o centrales? ¿Existen valores atípicos? Supongamos entonces que consideramos simplemente la variable de cuenta_total. Podemos comenzar por ordenar los datos, y ver cuáles datos están en los extremos y cuáles están en los lugares centrales: propinas <- propinas |> mutate(orden_cuenta = rank(cuenta_total, ties.method = "first"), f = (orden_cuenta - 0.5) / n()) cuenta <- propinas |> select(orden_cuenta, f, cuenta_total) |> arrange(f) bind_rows(head(cuenta), tail(cuenta)) |> gt() |> fmt_number(columns = f, decimals = 3) #pwsenweudp table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #pwsenweudp thead, #pwsenweudp tbody, #pwsenweudp tfoot, #pwsenweudp tr, #pwsenweudp td, #pwsenweudp th { border-style: none; } #pwsenweudp p { margin: 0; padding: 0; } #pwsenweudp .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #pwsenweudp .gt_caption { padding-top: 4px; padding-bottom: 4px; } #pwsenweudp .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #pwsenweudp .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #pwsenweudp .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #pwsenweudp .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #pwsenweudp .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #pwsenweudp .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #pwsenweudp .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #pwsenweudp .gt_column_spanner_outer:first-child { padding-left: 0; } #pwsenweudp .gt_column_spanner_outer:last-child { padding-right: 0; } #pwsenweudp .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #pwsenweudp .gt_spanner_row { border-bottom-style: hidden; } #pwsenweudp .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #pwsenweudp .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #pwsenweudp .gt_from_md > :first-child { margin-top: 0; } #pwsenweudp .gt_from_md > :last-child { margin-bottom: 0; } #pwsenweudp .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #pwsenweudp .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #pwsenweudp .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #pwsenweudp .gt_row_group_first td { border-top-width: 2px; } #pwsenweudp .gt_row_group_first th { border-top-width: 2px; } #pwsenweudp .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #pwsenweudp .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #pwsenweudp .gt_first_summary_row.thick { border-top-width: 2px; } #pwsenweudp .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #pwsenweudp .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #pwsenweudp .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #pwsenweudp .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #pwsenweudp .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #pwsenweudp .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #pwsenweudp .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #pwsenweudp .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #pwsenweudp .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #pwsenweudp .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #pwsenweudp .gt_left { text-align: left; } #pwsenweudp .gt_center { text-align: center; } #pwsenweudp .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #pwsenweudp .gt_font_normal { font-weight: normal; } #pwsenweudp .gt_font_bold { font-weight: bold; } #pwsenweudp .gt_font_italic { font-style: italic; } #pwsenweudp .gt_super { font-size: 65%; } #pwsenweudp .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #pwsenweudp .gt_asterisk { font-size: 100%; vertical-align: 0; } #pwsenweudp .gt_indent_1 { text-indent: 5px; } #pwsenweudp .gt_indent_2 { text-indent: 10px; } #pwsenweudp .gt_indent_3 { text-indent: 15px; } #pwsenweudp .gt_indent_4 { text-indent: 20px; } #pwsenweudp .gt_indent_5 { text-indent: 25px; } #pwsenweudp .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #pwsenweudp div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } orden_cuenta f cuenta_total 1 0.002 3.07 2 0.006 5.75 3 0.010 7.25 4 0.014 7.25 5 0.018 7.51 6 0.023 7.56 239 0.977 44.30 240 0.982 45.35 241 0.986 48.17 242 0.990 48.27 243 0.994 48.33 244 0.998 50.81 También podemos graficar los datos en orden, interpolando valores consecutivos. A esta función le llamamos la función de cuantiles para la variable cuenta_total. Nos sirve para comparar directamente los distintos valores que observamos los datos según el orden que ocupan. En particular, podemos estudiar la dispersión y valores centrales de los datos observados: El rango de datos va de unos 3 dólares hasta 50 dólares Los valores centrales, por ejemplo el 50% de los valores más centrales, están entre unos 13 y 25 dólares. El valor que divide en dos mitades iguales a los datos es de alrededor de 18 dólares. El cuantil \\(f\\), que denotamos por \\(q(f)\\) es valor a lo largo de la escala de medición de los datos tal que aproximadamente una fracción \\(f\\) de los datos son menores o iguales a \\(q(f)\\). Al cuantil \\(f=0.5\\) le llamamos la mediana. A los cuantiles \\(f=0.25\\) y \\(f=0.75\\) les llamamos cuartiles inferior y superior. En nuestro ejemplo: Los valores centrales —del cuantil 0.25 al 0.75, por decir un ejemplo— están entre unos 13 y 25 dólares. Estos dos cuantiles se llaman cuartil inferior y cuartil superior respectivamente El cuantil 0.5 (o también conocido como mediana) está alrededor de 18 dólares. Éste último puede ser utilizado para dar un valor central de la distribución de valores para cuenta_total. Asimismo podemos dar resúmenes más refinados si es necesario. Por ejemplo, podemos reportar que: El cuantil 0.95 es de unos 35 dólares — sólo 5% de las cuentas son de más de 35 dólares El cuantil 0.05 es de unos 8 dólares — sólo 5% de las cuentas son de 8 dólares o menos. Finalmente, la forma de la gráfica se interpreta usando su pendiente (tasa de cambio) haciendo comparaciones en diferentes partes de la gráfica: La distribución de valores tiene asimetría: el 10% de las cuentas más altas tiene considerablemente más dispersión que el 10% de las cuentas más bajas. Entre los cuantiles 0.2 y 0.7 es donde existe mayor densidad de datos: la pendiente (tasa de cambio) es baja, lo que significa que al avanzar en los valores observados, los cuantiles (el porcentaje de casos) aumenta rápidamente. Cuando la pendiente alta, quiere decir que los datos tienen más dispersión local o están más separados. Observación: Hay varias maneras de definir los cuantiles (ver (William S. Cleveland 1993)): Supongamos que queremos definir \\(q(f)\\), y denotamos los datos ordenados como \\(x_{(1)}, x_{(2)}, \\ldots, x_{(N)}\\), de forma que \\(x_{(1)}\\) es el dato más chico y \\(x_{(N)}\\) es el dato más grande. Para cada \\(x_{(i)}\\) definimos \\[f_i = i / N\\] entonces definimos el cuantil \\(q(f_i)=x_{(i)}\\). Para cualquier \\(f\\) entre 0 y 1, podemos definir \\(q(f)\\) como sigue: si \\(f\\) está entre \\(f_i\\) y \\(f_{i+1}\\) interpolamos linealmente los valores correspondientes \\(x_{(i)}\\) y \\(x_{(i-1)}\\). En la práctica, es más conveniente usar \\(f_i= \\frac{i - 0.5}{N}\\). La gráfica de cuantiles no cambia mucho comparado con la difinición anterior, y esto nos permitirá comparar de mejor manera con distribuciones teóricas que no tienen definido su cuantil 0 y el 1, pues tienen soporte en los números reales (como la distribución normal, por ejemplo). Asociada a la función de cuantiles \\(q\\) tenemos la distribución acumulada empírica de los datos, que es aproximadamente inversa de la función de cuantiles, y se define como: \\[\\hat{F}(x) = i/N\\] si \\(x_{(i)} \\leq x < x_{(i+1)}\\). Nótese que \\(\\hat{F}(q(f_i)) = i/N = f_i\\) (demuéstralo). acum_cuenta <- ecdf(cuenta$cuenta_total) cuenta <- cuenta |> mutate(dea_cuenta_total = acum_cuenta(cuenta_total)) g_acum <- ggplot(cuenta, aes(x = cuenta_total, y = dea_cuenta_total)) + geom_point() + labs(subtitle = "Distribución acum empírica de cuenta total", x = "") g_cuantiles + g_acum La función de distribución acumulada empírica es otra forma de graficar la dispersión de los datos. En su gráfica vemos que proporción de los datos que son iguales o están por debajo de cada valor en el eje horizontal. Nota: En análisis de datos, es más frecuente utilizar la función de cuantiles pues existen versiones más generales que son útiles, por ejemplo, para evaluar ajuste de modelos probabilísticos En la teoría, generalmente es más común utilizar la fda empírica, que tiene una única definición que veremos coincide con definiciones teóricas. Histogramas En algunos casos, es más natural hacer un histograma, donde dividimos el rango de la variable en cubetas o intervalos (en este caso de igual longitud), y graficamos por medio de barras cuántos datos caen en cada cubeta: Es una gráfica más popular, pero perdemos cierto nivel de detalle, y distintas particiones resaltan distintos aspectos de los datos. ¿Cómo se ve la gráfica de cuantiles de las propinas? ¿Cómo crees que esta gráfica se compara con distintos histogramas? g_1 <- ggplot(propinas, aes(sample = propina)) + geom_qq(distribution = stats::qunif) + labs(x = "f", y = "propina") g_1 Finalmente, una gráfica más compacta que resume la gráfica de cuantiles o el histograma es el diagrama de caja y brazos. Mostramos dos versiones, la clásica de Tukey (T) y otra versión menos común de Spear/Tufte (ST): library(ggthemes) cuartiles <- quantile(cuenta$cuenta_total) cuartiles |> round(2) ## 0% 25% 50% 75% 100% ## 3.07 13.35 17.80 24.13 50.81 g_1 <- ggplot(cuenta, aes(x = f, y = cuenta_total)) + labs(subtitle = "Gráfica de cuantiles: Cuenta total") + geom_hline(yintercept = cuartiles[2:4], colour = "gray") + geom_point(alpha = 0.5) + geom_line() g_2 <- ggplot(cuenta, aes(x = factor("ST", levels = "ST"), y = cuenta_total)) + geom_tufteboxplot() + labs(subtitle = "", x = "", y = "") g_3 <- ggplot(cuenta, aes(x = factor("T"), y = cuenta_total)) + geom_boxplot() + labs(subtitle = "", x = "", y = "") g_4 <- ggplot(cuenta, aes(x = factor("P"), y = cuenta_total)) + geom_jitter(height = 0, width =0.2, alpha = 0.5) + labs(subtitle = "", x = "", y = "") g_5 <- ggplot(cuenta, aes(x = factor("V"), y = cuenta_total)) + geom_violin() + labs(subtitle = "", x = "", y = "") g_1 + g_2 + g_3 + g_4 + plot_layout(widths = c(8, 2, 2, 2)) El diagrama de abajo explica los elementos de la versión típica del diagrama de caja y brazos (boxplot). RIC se refiere al Rango Intercuantílico, definido por la diferencia entre los cuantiles 25% y 75%. Figura: Jumanbar / CC BY-SA Ventajas en el análisis inicial En un principio del análisis, estos resúmenes (cuantiles) pueden ser más útiles que utilizar medias y varianzas, por ejemplo. La razón es que los cuantiles: Son cantidades más fácilmente interpretables Los cuantiles centrales son más resistentes a valores atípicos que medias o varianzas Permiten identificar valores extremos Es fácil comparar cuantiles de distintos bonches de datos en la misma escala Nota: Existen diferentes definiciones para calcular cuantiles de una muestra de datos, puedes leer más en este artículo. Media y desviación estándar Las medidas más comunes de localización y dispersión para un conjunto de datos son la media muestral y la desviación estándar muestral. En general, no son muy apropiadas para iniciar el análisis exploratorio, pues: Son medidas más difíciles de interpretar y explicar que los cuantiles. En este sentido, son medidas especializadas. Por ejemplo, compara una explicación intuitiva de la mediana contra una explicación intuitiva de la media. No son resistentes a valores atípicos. Su falta de resistencia los vuelve poco útiles en las primeras etapas de limpieza y descripción y en resúmenes deficientes para distribuciones irregulares (con colas largas por ejemplo). La media, o promedio, se denota por \\(\\bar x\\) y se define como \\[\\begin{align} \\bar x = \\frac1N \\sum_{n = 1}^N x_n. \\end{align}\\] La desviación estándar muestral se define como \\[\\begin{align} \\text{std}(x) = \\sqrt{\\frac1{N-1} \\sum_{n = 1}^N (x_n - \\bar x)^2}. \\end{align}\\] Observación: Si \\(N\\) no es muy chica, no importa mucho si dividimos por \\(N\\) o por \\(N-1\\) en la fórmula de la desviación estándar. La razón de que típicamente se usa \\(N-1\\) la veremos más adelante, en la parte de estimación. Por otro lado, ventajas de estas medidas de centralidad y dispersión son: La media y desviación estándar son computacionalmente convenientes. Por lo tanto regresaremos a estas medidas una vez que estudiemos modelos de probabilidad básicos. En muchas ocasiones conviene usar estas medidas pues permite hacer comparaciones históricas o tradicionales —pues análisis anteriores pudieran estar basados en éstas. Considera el caso de tener \\(N\\) observaciones y asume que ya tienes calculado el promedio para dichas observaciones. Este promedio lo denotaremos por \\(\\bar x_N\\). Ahora, considera que has obtenido \\(M\\) observaciones más. Escribe una fórmula recursiva para la media del conjunto total de datos \\(\\bar x_{N+M}\\) en función de lo que ya tenías precalculado \\(\\bar x_N.\\) ¿En qué situaciones esta propiedad puede ser conveniente? Ejemplos Precios de casas En este ejemplo consideremos los datos de precios de ventas de la ciudad de Ames, Iowa. En particular nos interesa entender la variación del precio de las casas. Por este motivo calculamos los cuantiles que corresponden al 25%, 50% y 75% (cuartiles), así como el mínimo y máximo de los precios de las casas: quantile(casas |> pull(precio_miles)) ## 0% 25% 50% 75% 100% ## 37.9 132.0 165.0 215.0 755.0 Comprueba que el mínimo y máximo están asociados a los cuantiles 0% y 100%, respectivamente. Una posible comparación es considerar los precios y sus variación en función de zona de la ciudad en que se encuentra una vivienda. Podemos usar diagramas de caja y brazos para hacer una comparación burda de los precios en distintas zonas de la ciudad: ggplot(casas, aes(x = nombre_zona, y = precio_miles)) + geom_boxplot() + coord_flip() La primera pregunta que nos hacemos es cómo pueden variar las características de las casas dentro de cada zona. Para esto, podemos considerar el área de las casas. En lugar de graficar el precio, graficamos el precio por metro cuadrado, por ejemplo: ggplot(casas, aes(x = nombre_zona, y = precio_m2)) + geom_boxplot() + coord_flip() Podemos cuantificar la variación que observamos de zona a zona y la variación que hay dentro de cada una de las zonas. Una primera aproximación es observar las variación del precio al calcular la mediana dentro de cada zona, y después cuantificar por medio de cuantiles cómo varía la mediana entre zonas: casas |> group_by(nombre_zona) |> summarise(mediana_zona = median(precio_m2), .groups = "drop") |> pull(mediana_zona) |> quantile() |> round() ## 0% 25% 50% 75% 100% ## 963 1219 1298 1420 1725 Por otro lado, las variaciones con respecto a las medianas dentro de cada zona, por grupo, se resume como: quantile(casas |> group_by(nombre_zona) |> mutate(residual = precio_m2 - median(precio_m2)) |> pull(residual)) |> round() ## 0% 25% 50% 75% 100% ## -765 -166 0 172 1314 Nótese que este último paso tiene sentido pues la variación dentro de las zonas, en términos de precio por metro cuadrado, es similar. Esto no lo podríamos haber hecho de manera efectiva si se hubiera utilizado el precio de las casas sin ajustar por su tamaño. Podemos resumir este primer análisis con un par de gráficas de cuantiles (William S. Cleveland (1993)): mediana <- median(casas$precio_m2) resumen <- casas |> group_by(nombre_zona) |> mutate(mediana_zona = median(precio_m2)) |> mutate(residual = precio_m2 - mediana_zona) |> ungroup() |> mutate(mediana_zona = mediana_zona - mediana) |> select(nombre_zona, mediana_zona, residual) |> pivot_longer(mediana_zona:residual, names_to = "tipo", values_to = "valor") ggplot(resumen, aes(sample = valor)) + geom_qq(distribution = stats::qunif) + facet_wrap(~ tipo) + ylab("Precio por m2") + xlab("f") + labs(subtitle = "Precio por m2 por zona", caption = paste0("Mediana total de ", round(mediana))) Vemos que la mayor parte de la variación del precio por metro cuadrado ocurre dentro de cada zona, una vez que controlamos por el tamaño de las casas. La variación dentro de cada zona es aproximadamente simétrica, aunque la cola derecha es ligeramente más larga con algunos valores extremos. Podemos seguir con otro indicador importante: la calificación de calidad de los terminados de las casas. Como primer intento podríamos hacer: Lo que indica que las calificaciones de calidad están distribuidas de manera muy distinta a lo largo de las zonas, y que probablemente no va ser simple desentrañar qué variación del precio se debe a la zona y cuál se debe a la calidad. Prueba Enlace Consideremos la prueba Enlace (2011) de matemáticas para primarias. Una primera pregunta que alguien podría hacerse es: ¿cuáles escuelas son mejores en este rubro, las privadas o las públicas? enlace_tbl <- enlace |> group_by(tipo) |> summarise(n_escuelas = n(), cuantiles = list(cuantil(mate_6, c(0.05, 0.25, 0.5, 0.75, 0.95)))) |> unnest(cols = cuantiles) |> mutate(valor = round(valor)) enlace_tbl |> spread(cuantil, valor) |> gt() #sykxxonvyi table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #sykxxonvyi thead, #sykxxonvyi tbody, #sykxxonvyi tfoot, #sykxxonvyi tr, #sykxxonvyi td, #sykxxonvyi th { border-style: none; } #sykxxonvyi p { margin: 0; padding: 0; } #sykxxonvyi .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #sykxxonvyi .gt_caption { padding-top: 4px; padding-bottom: 4px; } #sykxxonvyi .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #sykxxonvyi .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #sykxxonvyi .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #sykxxonvyi .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #sykxxonvyi .gt_column_spanner_outer:first-child { padding-left: 0; } #sykxxonvyi .gt_column_spanner_outer:last-child { padding-right: 0; } #sykxxonvyi .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #sykxxonvyi .gt_spanner_row { border-bottom-style: hidden; } #sykxxonvyi .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #sykxxonvyi .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #sykxxonvyi .gt_from_md > :first-child { margin-top: 0; } #sykxxonvyi .gt_from_md > :last-child { margin-bottom: 0; } #sykxxonvyi .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #sykxxonvyi .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #sykxxonvyi .gt_row_group_first td { border-top-width: 2px; } #sykxxonvyi .gt_row_group_first th { border-top-width: 2px; } #sykxxonvyi .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #sykxxonvyi .gt_first_summary_row.thick { border-top-width: 2px; } #sykxxonvyi .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #sykxxonvyi .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #sykxxonvyi .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_left { text-align: left; } #sykxxonvyi .gt_center { text-align: center; } #sykxxonvyi .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #sykxxonvyi .gt_font_normal { font-weight: normal; } #sykxxonvyi .gt_font_bold { font-weight: bold; } #sykxxonvyi .gt_font_italic { font-style: italic; } #sykxxonvyi .gt_super { font-size: 65%; } #sykxxonvyi .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #sykxxonvyi .gt_asterisk { font-size: 100%; vertical-align: 0; } #sykxxonvyi .gt_indent_1 { text-indent: 5px; } #sykxxonvyi .gt_indent_2 { text-indent: 10px; } #sykxxonvyi .gt_indent_3 { text-indent: 15px; } #sykxxonvyi .gt_indent_4 { text-indent: 20px; } #sykxxonvyi .gt_indent_5 { text-indent: 25px; } #sykxxonvyi .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #sykxxonvyi div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } tipo n_escuelas 0.05 0.25 0.5 0.75 0.95 Indígena/Conafe 13599 304 358 412 478 588 General 60166 380 454 502 548 631 Particular 6816 479 551 593 634 703 Para un análisis exploratorio podemos utilizar distintas gráficas. Por ejemplo, podemos utilizar nuevamente las gráficas de caja y brazos, así como graficar los percentiles. Nótese que en la gráfica 1 se utilizan los cuantiles 0.05, 0.25, 0.5, 0.75 y 0.95: ## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0. ## ℹ Please use `linewidth` instead. ## This warning is displayed once every 8 hours. ## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was ## generated. Se puede discutir qué tan apropiada es cada gráfica con el objetivo de realizar comparaciones. Sin duda, graficar más cuantiles es más útil para hacer comparaciones. Por ejemplo, en la Gráfica 1 podemos ver que la mediana de las escuelas generales está cercana al cuantil 5% de las escuelas particulares. Por otro lado, el diagrama de caja y brazos muestra también valores “atípicos”. Antes de contestar prematuramente la pregunta: ¿cuáles son las mejores escuelas? busquemos mejorar la interpretabilidad de nuestras comparaciones. Podemos comenzar por agregar, por ejemplo, el nivel del marginación del municipio donde se encuentra la escuela. Para este objetivo, podemos usar páneles (pequeños múltiplos útiles para hacer comparaciones) y graficar: Esta gráfica pone en contexto la pregunta inicial, y permite evidenciar la dificultad de contestarla. En particular: Señala que la pregunta no sólo debe concentarse en el tipo de “sistema”: pública, privada, etc. Por ejemplo, las escuelas públicas en zonas de marginación baja no tienen una distribución de calificaciones muy distinta a las privadas en zonas de marginación alta. El contexto de la escuela es importante. Debemos de pensar qué factores –por ejemplo, el entorno familiar de los estudiantes– puede resultar en comparaciones que favorecen a las escuelas privadas. Un ejemplo de esto es considerar si los estudiantes tienen que trabajar o no. A su vez, esto puede o no ser reflejo de la calidad del sistema educativo. Si esto es cierto, entonces la pregunta inicial es demasiado vaga y mal planteada. Quizá deberíamos intentar entender cuánto “aporta” cada escuela a cada estudiante, como medida de qué tan buena es cada escuela. Estados y calificaciones en SAT ¿Cómo se relaciona el gasto por alumno, a nivel estatal, con sus resultados académicos? Hay trabajo considerable en definir estos términos, pero supongamos que tenemos el siguiente conjunto de datos (Guber 1999), que son datos oficiales agregados por estado de Estados Unidos. Consideremos el subconjunto de variables sat, que es la calificación promedio de los alumnos en cada estado (para 1997) y expend, que es el gasto en miles de dólares por estudiante en (1994-1995). sat <- read_csv("data/sat.csv") sat_tbl <- sat |> select(state, expend, sat) |> gather(variable, valor, expend:sat) |> group_by(variable) |> summarise(cuantiles = list(cuantil(valor))) |> unnest(cols = c(cuantiles)) |> mutate(valor = round(valor, 1)) |> spread(cuantil, valor) sat_tbl |> gt() #sykxxonvyi table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #sykxxonvyi thead, #sykxxonvyi tbody, #sykxxonvyi tfoot, #sykxxonvyi tr, #sykxxonvyi td, #sykxxonvyi th { border-style: none; } #sykxxonvyi p { margin: 0; padding: 0; } #sykxxonvyi .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #sykxxonvyi .gt_caption { padding-top: 4px; padding-bottom: 4px; } #sykxxonvyi .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #sykxxonvyi .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #sykxxonvyi .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #sykxxonvyi .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #sykxxonvyi .gt_column_spanner_outer:first-child { padding-left: 0; } #sykxxonvyi .gt_column_spanner_outer:last-child { padding-right: 0; } #sykxxonvyi .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #sykxxonvyi .gt_spanner_row { border-bottom-style: hidden; } #sykxxonvyi .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #sykxxonvyi .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #sykxxonvyi .gt_from_md > :first-child { margin-top: 0; } #sykxxonvyi .gt_from_md > :last-child { margin-bottom: 0; } #sykxxonvyi .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #sykxxonvyi .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #sykxxonvyi .gt_row_group_first td { border-top-width: 2px; } #sykxxonvyi .gt_row_group_first th { border-top-width: 2px; } #sykxxonvyi .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #sykxxonvyi .gt_first_summary_row.thick { border-top-width: 2px; } #sykxxonvyi .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #sykxxonvyi .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #sykxxonvyi .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_left { text-align: left; } #sykxxonvyi .gt_center { text-align: center; } #sykxxonvyi .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #sykxxonvyi .gt_font_normal { font-weight: normal; } #sykxxonvyi .gt_font_bold { font-weight: bold; } #sykxxonvyi .gt_font_italic { font-style: italic; } #sykxxonvyi .gt_super { font-size: 65%; } #sykxxonvyi .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #sykxxonvyi .gt_asterisk { font-size: 100%; vertical-align: 0; } #sykxxonvyi .gt_indent_1 { text-indent: 5px; } #sykxxonvyi .gt_indent_2 { text-indent: 10px; } #sykxxonvyi .gt_indent_3 { text-indent: 15px; } #sykxxonvyi .gt_indent_4 { text-indent: 20px; } #sykxxonvyi .gt_indent_5 { text-indent: 25px; } #sykxxonvyi .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #sykxxonvyi div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } variable 0 0.25 0.5 0.75 1 expend 3.7 4.9 5.8 6.4 9.8 sat 844.0 897.2 945.5 1032.0 1107.0 Esta variación es considerable para promedios del SAT: el percentil 75 es alrededor de 1050 puntos, mientras que el percentil 25 corresponde a alrededor de 800. Igualmente, hay diferencias considerables de gasto por alumno (miles de dólares) a lo largo de los estados. Ahora hacemos nuestro primer ejercico de comparación: ¿Cómo se ven las calificaciones para estados en distintos niveles de gasto? Podemos usar una gráfica de dispersión: library(ggrepel) ggplot(sat, aes(x = expend, y = sat, label = state)) + geom_point(colour = "red", size = 2) + geom_text_repel(colour = "gray50") + xlab("Gasto por alumno (miles de dólares)") + ylab("Calificación promedio en SAT") Estas comparaciones no son de alta calidad, solo estamos usando 2 variables —que son muy pocas— y no hay mucho que podamos decir en cuanto explicación. Sin duda nos hace falta una imagen más completa. Necesitaríamos entender la correlación que existe entre las demás características de nuestras unidades de estudio. Las unidades que estamos comparando pueden diferir fuertemente en otras propiedades importantes (o dimensiones), lo cual no permite interpretar la gráfica de manera sencilla. Una variable que tenemos es el porcentaje de alumnos de cada estado que toma el SAT. Podemos agregar como sigue: ggplot(sat, aes(x = expend, y = math, label=state, colour = frac)) + geom_point() + geom_text_repel() + xlab("Gasto por alumno (miles de dólares)") + ylab("Calificación en matemáticas") Esto nos permite entender por qué nuestra comparación inicial es relativamente pobre. Los estados con mejores resultados promedio en el SAT son aquellos donde una fracción relativamente baja de los estudiantes toma el examen. La diferencia es considerable. En este punto podemos hacer varias cosas. Una primera idea es intentar comparar estados más similares en cuanto a la población de alumnos que asiste. Podríamos hacer grupos como sigue: set.seed(991) k_medias_sat <- kmeans(sat |> select(frac), centers = 4, nstart = 100, iter.max = 100) sat$clase <- k_medias_sat$cluster sat <- sat |> group_by(clase) |> mutate(clase_media = round(mean(frac))) |> ungroup() |> mutate(clase_media = factor(clase_media)) sat <- sat |> mutate(rank_p = rank(frac, ties= "first") / length(frac)) ggplot(sat, aes(x = rank_p, y = frac, label = state, colour = clase_media)) + geom_point(size = 2) Estos resultados indican que es más probable que buenos alumnos decidan hacer el SAT. Lo interesante es que esto ocurre de manera diferente en cada estado. Por ejemplo, en algunos estados era más común otro examen: el ACT. Si hacemos clusters de estados según el % de alumnos, empezamos a ver otra historia. Para esto, ajustemos rectas de mínimos cuadrados como referencia: Esto da una imagen muy diferente a la que originalmente planteamos. Nota que dependiendo de cómo categorizamos, esta gráfica puede variar (puedes intentar con más o menos grupos, por ejemplo). Tablas de conteos Consideremos los siguientes datos de tomadores de té (del paquete FactoMineR (Lê et al. 2008)): tea <- read_csv("data/tea.csv") # nombres y códigos te <- tea |> select(how, price, sugar) |> rename(presentacion = how, precio = price, azucar = sugar) |> mutate( presentacion = fct_recode(presentacion, suelto = "unpackaged", bolsas = "tea bag", mixto = "tea bag+unpackaged"), precio = fct_recode(precio, marca = "p_branded", variable = "p_variable", barato = "p_cheap", marca_propia = "p_private label", desconocido = "p_unknown", fino = "p_upscale"), azucar = fct_recode(azucar, sin_azúcar = "No.sugar", con_azúcar = "sugar")) sample_n(te, 10) ## # A tibble: 10 × 3 ## presentacion precio azucar ## <fct> <fct> <fct> ## 1 bolsas marca sin_azúcar ## 2 bolsas variable sin_azúcar ## 3 bolsas marca con_azúcar ## 4 bolsas fino con_azúcar ## 5 mixto variable con_azúcar ## 6 mixto fino con_azúcar ## 7 bolsas marca sin_azúcar ## 8 bolsas fino sin_azúcar ## 9 mixto variable con_azúcar ## 10 mixto variable sin_azúcar Nos interesa ver qué personas compran té suelto, y de qué tipo. Empezamos por ver las proporciones que compran té según su empaque (en bolsita o suelto): precio <- te |> count(precio) |> mutate(prop = round(100 * n / sum(n))) |> select(-n) tipo <- te |> count(presentacion) |> mutate(pct = round(100 * n / sum(n))) tipo |> gt() #wiljiluquk table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #wiljiluquk thead, #wiljiluquk tbody, #wiljiluquk tfoot, #wiljiluquk tr, #wiljiluquk td, #wiljiluquk th { border-style: none; } #wiljiluquk p { margin: 0; padding: 0; } #wiljiluquk .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #wiljiluquk .gt_caption { padding-top: 4px; padding-bottom: 4px; } #wiljiluquk .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #wiljiluquk .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #wiljiluquk .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #wiljiluquk .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #wiljiluquk .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #wiljiluquk .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #wiljiluquk .gt_column_spanner_outer:first-child { padding-left: 0; } #wiljiluquk .gt_column_spanner_outer:last-child { padding-right: 0; } #wiljiluquk .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #wiljiluquk .gt_spanner_row { border-bottom-style: hidden; } #wiljiluquk .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #wiljiluquk .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #wiljiluquk .gt_from_md > :first-child { margin-top: 0; } #wiljiluquk .gt_from_md > :last-child { margin-bottom: 0; } #wiljiluquk .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #wiljiluquk .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #wiljiluquk .gt_row_group_first td { border-top-width: 2px; } #wiljiluquk .gt_row_group_first th { border-top-width: 2px; } #wiljiluquk .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #wiljiluquk .gt_first_summary_row.thick { border-top-width: 2px; } #wiljiluquk .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #wiljiluquk .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #wiljiluquk .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #wiljiluquk .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #wiljiluquk .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_left { text-align: left; } #wiljiluquk .gt_center { text-align: center; } #wiljiluquk .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #wiljiluquk .gt_font_normal { font-weight: normal; } #wiljiluquk .gt_font_bold { font-weight: bold; } #wiljiluquk .gt_font_italic { font-style: italic; } #wiljiluquk .gt_super { font-size: 65%; } #wiljiluquk .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #wiljiluquk .gt_asterisk { font-size: 100%; vertical-align: 0; } #wiljiluquk .gt_indent_1 { text-indent: 5px; } #wiljiluquk .gt_indent_2 { text-indent: 10px; } #wiljiluquk .gt_indent_3 { text-indent: 15px; } #wiljiluquk .gt_indent_4 { text-indent: 20px; } #wiljiluquk .gt_indent_5 { text-indent: 25px; } #wiljiluquk .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #wiljiluquk div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } presentacion n pct bolsas 170 57 mixto 94 31 suelto 36 12 La mayor parte de las personas toma té en bolsas. Sin embargo, el tipo de té (en términos de precio o marca) que compran es muy distinto dependiendo de la presentación: tipo <- tipo |> select(presentacion, prop_presentacion = pct) tabla_cruzada <- te |> count(presentacion, precio) |> # porcentajes por presentación group_by(presentacion) |> mutate(prop = round(100 * n / sum(n))) |> select(-n) tabla_cruzada |> pivot_wider(names_from = presentacion, values_from = prop, values_fill = list(prop = 0)) |> gt() #sxkvcchtyg table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #sxkvcchtyg thead, #sxkvcchtyg tbody, #sxkvcchtyg tfoot, #sxkvcchtyg tr, #sxkvcchtyg td, #sxkvcchtyg th { border-style: none; } #sxkvcchtyg p { margin: 0; padding: 0; } #sxkvcchtyg .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #sxkvcchtyg .gt_caption { padding-top: 4px; padding-bottom: 4px; } #sxkvcchtyg .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #sxkvcchtyg .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #sxkvcchtyg .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #sxkvcchtyg .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #sxkvcchtyg .gt_column_spanner_outer:first-child { padding-left: 0; } #sxkvcchtyg .gt_column_spanner_outer:last-child { padding-right: 0; } #sxkvcchtyg .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #sxkvcchtyg .gt_spanner_row { border-bottom-style: hidden; } #sxkvcchtyg .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #sxkvcchtyg .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #sxkvcchtyg .gt_from_md > :first-child { margin-top: 0; } #sxkvcchtyg .gt_from_md > :last-child { margin-bottom: 0; } #sxkvcchtyg .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #sxkvcchtyg .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #sxkvcchtyg .gt_row_group_first td { border-top-width: 2px; } #sxkvcchtyg .gt_row_group_first th { border-top-width: 2px; } #sxkvcchtyg .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #sxkvcchtyg .gt_first_summary_row.thick { border-top-width: 2px; } #sxkvcchtyg .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #sxkvcchtyg .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #sxkvcchtyg .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_left { text-align: left; } #sxkvcchtyg .gt_center { text-align: center; } #sxkvcchtyg .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #sxkvcchtyg .gt_font_normal { font-weight: normal; } #sxkvcchtyg .gt_font_bold { font-weight: bold; } #sxkvcchtyg .gt_font_italic { font-style: italic; } #sxkvcchtyg .gt_super { font-size: 65%; } #sxkvcchtyg .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #sxkvcchtyg .gt_asterisk { font-size: 100%; vertical-align: 0; } #sxkvcchtyg .gt_indent_1 { text-indent: 5px; } #sxkvcchtyg .gt_indent_2 { text-indent: 10px; } #sxkvcchtyg .gt_indent_3 { text-indent: 15px; } #sxkvcchtyg .gt_indent_4 { text-indent: 20px; } #sxkvcchtyg .gt_indent_5 { text-indent: 25px; } #sxkvcchtyg .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #sxkvcchtyg div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } precio bolsas mixto suelto marca 41 21 14 barato 3 1 3 marca_propia 9 4 3 desconocido 6 1 0 fino 8 20 56 variable 32 52 25 Estos datos podemos examinarlos un rato y llegar a conclusiones, pero esta tabla no necesariamente es la mejor manera de mostrar patrones en los datos. Tampoco son muy útiles gráficas como la siguiente: ggplot(tabla_cruzada |> ungroup() |> mutate(price = fct_reorder(precio, prop)), aes(x = precio, y = prop, group = presentacion, colour = presentacion)) + geom_point() + coord_flip() + geom_line() En lugar de eso, calcularemos perfiles columna. Esto es, comparamos cada una de las columnas con la columna marginal (en la tabla de tipo de estilo de té): num_grupos <- n_distinct(te |> select(presentacion)) tabla <- te |> count(presentacion, precio) |> group_by(presentacion) |> mutate(prop_precio = (100 * n / sum(n))) |> group_by(precio) |> mutate(prom_prop = sum(prop_precio)/num_grupos) |> mutate(perfil = 100 * (prop_precio / prom_prop - 1)) tabla ## # A tibble: 17 × 6 ## # Groups: precio [6] ## presentacion precio n prop_precio prom_prop perfil ## <fct> <fct> <int> <dbl> <dbl> <dbl> ## 1 bolsas marca 70 41.2 25.4 61.8 ## 2 bolsas barato 5 2.94 2.26 30.1 ## 3 bolsas marca_propia 16 9.41 5.48 71.7 ## 4 bolsas desconocido 11 6.47 2.51 158. ## 5 bolsas fino 14 8.24 28.0 -70.6 ## 6 bolsas variable 54 31.8 36.3 -12.5 ## 7 mixto marca 20 21.3 25.4 -16.4 ## 8 mixto barato 1 1.06 2.26 -52.9 ## 9 mixto marca_propia 4 4.26 5.48 -22.4 ## 10 mixto desconocido 1 1.06 2.51 -57.6 ## 11 mixto fino 19 20.2 28.0 -27.8 ## 12 mixto variable 49 52.1 36.3 43.6 ## 13 suelto marca 5 13.9 25.4 -45.4 ## 14 suelto barato 1 2.78 2.26 22.9 ## 15 suelto marca_propia 1 2.78 5.48 -49.3 ## 16 suelto fino 20 55.6 28.0 98.4 ## 17 suelto variable 9 25 36.3 -31.1 tabla_perfil <- tabla |> select(presentacion, precio, perfil, pct = prom_prop) |> pivot_wider(names_from = presentacion, values_from = perfil, values_fill = list(perfil = -100.0)) if_profile <- function(x){ any(x < 0) & any(x > 0) } marcar <- marcar_tabla_fun(25, "red", "black") tab_out <- tabla_perfil |> arrange(desc(bolsas)) |> select(-pct, everything()) |> mutate(across(where(is.numeric), \\(x) round(x, 0))) |> mutate(across(where(if_profile), \\(x) marcar(x))) |> knitr::kable(format_table_salida(), escape = FALSE, digits = 0, booktabs = T) |> kableExtra::kable_styling(latex_options = c("striped", "scale_down"), bootstrap_options = c( "hover", "condensed"), full_width = FALSE) tab_out precio bolsas mixto suelto pct desconocido 158 -58 -100 3 marca_propia 72 -22 -49 5 marca 62 -16 -45 25 barato 30 -53 23 2 variable -12 44 -31 36 fino -71 -28 98 28 Leemos esta tabla como sigue: por ejemplo, los compradores de té suelto compran té fino a una tasa casi el doble (98%) que el promedio. También podemos graficar como: tabla_graf <- tabla_perfil |> ungroup() |> mutate(precio = fct_reorder(precio, bolsas)) |> select(-pct) |> pivot_longer(cols = -precio, names_to = "presentacion", values_to = "perfil") g_perfil <- ggplot(tabla_graf, aes(x = precio, xend = precio, y = perfil, yend = 0, group = presentacion)) + geom_point() + geom_segment() + facet_wrap(~presentacion) + geom_hline(yintercept = 0 , colour = "gray")+ coord_flip() g_perfil Observación: hay dos maneras de construir la columna promedio: tomando los porcentajes sobre todos los datos, o promediando los porcentajes de las columnas. Si los grupos de las columnas están desbalanceados, estos promedios son diferentes. Cuando usamos porcentajes sobre la población, perfiles columna y renglón dan el mismo resultado Sin embargo, cuando hay un grupo considerablemente más grande que otros, las comparaciones se vuelven vs este grupo particular. No siempre queremos hacer esto. Interpretación En el último ejemplo de tomadores de té utilizamos una muestra de personas, no toda la población de tomadores de té. Eso quiere decir que tenemos cierta incertidumbre de cómo se generalizan o no los resultados que obtuvimos en nuestro análisis a la población general. Nuestra respuesta depende de cómo se extrajo la muestra que estamos considerando. Si el mecanismo de extracción incluye algún proceso probabilístico, entonces es posible en principio entender qué tan bien generalizan los resultados de nuestro análisis a la población general, y entender esto depende de entender qué tanta variación hay de muestra a muestra, de todas las posibles muestras que pudimos haber extraido. En las siguiente secciones discutiremos estos aspectos, en los cuales pasamos del trabajo de “detective” al trabajo de “juez” en nuestro trabajo analítico. Suavizamiento loess Las gráficas de dispersión son la herramienta básica para describir la relación entre dos variables cuantitativas, y como vimos en ejemplo anteriores, muchas veces podemos apreciar mejor la relación entre ellas si agregamos una curva loess que suavice. Los siguientes datos muestran los premios ofrecidos y las ventas totales de una lotería a lo largo de 53 sorteos (las unidades son cantidades de dinero indexadas). Graficamos en escalas logarítmicas y agregamos una curva loess. # cargamos los datos load(here::here("data", "ventas_sorteo.Rdata")) ggplot(ventas.sorteo, aes(x = premio, y = ventas.tot.1)) + geom_point() + geom_smooth(method = "loess", alpha = 0.5, degree = 1, se = FALSE) + scale_x_log10(breaks = c(20000, 40000, 80000)) + scale_y_log10(breaks = c(10000, 15000, 22000, 33000)) El patrón no era difícil de ver en los datos originales, sin embargo, la curva lo hace más claro, el logaritmo de las ventas tiene una relación no lineal con el logaritmo del premio: para premios no muy grandes no parece haber gran diferencia, pero cuando los premios empiezan a crecer por encima de 20,000, las ventas crecen más rápidamente que para premios menores. Este efecto se conoce como bola de nieve, y es frecuente en este tipo de loterías. Antes de adentrarnos a los modelos loess comenzamos explicando cómo se ajustan familias paramétricas de curvas a conjuntos de datos dados. El modelo de regresion lineal ajusta una recta a un conjunto de datos. Por ejemplo, consideremos la familia \\[f_{a,b}(x) = a x + b,\\] para un conjunto de datos bivariados \\(\\{ (x_1, y_1), \\ldots, (x_N, y_N)\\}\\). Buscamos encontrar \\(a\\) y \\(b\\) tales que \\(f_{a,b}\\) de un ajuste óptimo a los datos. Para esto, se minimiza la suma de errores cuadráticos \\[\\frac1N \\sum_{n = 1}^N ( y_n - a x_n - b)^2.\\] En este caso, las constantes \\(a\\) y \\(b\\) se pueden encontrar diferenciando la función de mínimos cuadrados. Nótese que podemos repetir el argumento con otras familias de funciones (por ejemplo cuadráticas). ggplot(ventas.sorteo, aes(x = premio, y = ventas.tot.1)) + geom_point() + geom_smooth(method = "lm", alpha = 0.5, se = FALSE) + scale_x_log10(breaks = c(20000, 40000, 80000)) + scale_y_log10(breaks = c(10000, 15000, 22000, 33000)) Si observamos la gráfica notamos que este modelo lineal (en los logaritmos) no resumen adecuadamente estos datos. Podríamos experimentar con otras familias (por ejemplo, una cuadrática o cúbica, potencias, exponenciales, etc.); sin embargo, en la etapa exploratoria es mejor tomar una ruta de ajuste más flexible y robusta. Regresión local nos provee de un método con estas características: Curvas loess (regresión local): Una manera de mejorar la flexibilidad de los modelos lineales es considerar rectas de manera local. Es decir, en cada \\(x\\) posible consideramos cuál es la recta que mejor ajusta a los datos, considerando solamente valores de \\(x_n\\) que están cercanos a \\(x\\). La siguiente gráfica muestra qué recta se ajusta alrededor de cada punto, y cómo queda el suavizador completo, con distintos valores de suavizamiento. El tono de los puntos indican en cada paso que ventana de datos es considerada: Escogiendo de los parámetros. El parámetro de suavizamiento se encuentra por ensayo y error. La idea general es que debemos encontrar una curva que explique patrones importantes en los datos (que ajuste los datos) pero que no muestre variaciones a escalas más chicas difíciles de explicar (que pueden ser el resultado de influencias de otras variables, variación muestral, ruido o errores de redondeo, por ejemplo). En el proceso de prueba y error iteramos el ajuste y en cada paso hacemos análisis de residuales, con el fin de seleccionar un suavizamiento adecuado. En lugar de usar ajustes locales lineales, podemos usar ajustes locales cuadráticos que nos permiten capturar formas locales cuadráticas sin tener que suavizar demasiado poco: Opcional: cálculo del suavizador La idea es producir ajustes locales de rectas o funciones lineales o cuadráticas. Consideremos especificar dos parámetros: Parámetro de suavizamiento \\(\\alpha\\): cuando \\(\\alpha\\) es más grande, la curva ajustada es más suave. Grado de los polinomios locales que ajustamos \\(\\lambda\\): generalmente se toma \\(\\lambda=1,2\\). Entonces, supongamos que los datos están dados por \\((x_1,y_1), \\ldots, (x_N, y_N)\\), y sean \\(\\alpha\\) un parámetro de suavizamiento fijo, y \\(\\lambda=1\\). Denotamos como \\(\\hat{g}(x)\\) la curva loess ajustada, y como \\(w_n(x)\\) a una función de peso (que depende de x) para la observación \\((x_n, y_n)\\). Para poder calcular \\(w_n(x)\\) debemos comenzar calculando \\(q=\\lfloor{N\\alpha}\\rfloor\\) que suponemos mayor que uno, esta \\(q\\) es el número de puntos que se utilizan en cada ajuste local. Ahora definimos la función tricubo: \\[\\begin{align} T(u)=\\begin{cases} (1-|u|^3)^3, & \\text{para $|u| < 1$}.\\\\ 0, & \\text{en otro caso}. \\end{cases} \\end{align}\\] entonces, para el punto \\(x\\) definimos el peso correspondiente al dato \\((x_n,y_n)\\), denotado por \\(w_n(x)\\) como: \\[w_n(x)=T\\bigg(\\frac{|x-x_n|}{d_q(x)}\\bigg)\\] donde \\(d_q(x)\\) es el valor de la \\(q\\)-ésima distancia más chica (la más grande entre las \\(q\\) más chicas) entre los valores \\(|x-x_j|\\), \\(j=1,\\ldots,N\\). De esta forma, las observaciones \\(x_n\\) reciben más peso cuanto más cerca estén de \\(x\\). En palabras, de \\(x_1,...,x_N\\) tomamos los \\(q\\) datos más cercanos a \\(x\\), que denotamos \\(x_{i_1}(x) \\leq x_{i_2}(x) \\leq \\cdots \\leq x_{i_q}(x)\\). Los re-escalamos a \\([0,1]\\) haciendo corresponder \\(x\\) a \\(0\\) y el punto más alejado de \\(x\\) (que es \\(x_{i_q}\\)) a 1. Aplicamos el tricubo (gráfica de abajo), para encontrar los pesos de cada punto. Los puntos que están a una distancia mayor a \\(d_q(x)\\) reciben un peso de cero, y los más cercanos un peso que depende de que tan cercanos están a \\(x\\). Nótese que \\(x\\) es el punto ancla en dónde estamos ajustando la regresión local. tricubo <- function(x) { ifelse(abs(x) < 1, (1 - abs(x) ^ 3) ^ 3, 0) } curve(tricubo, from = -1.5, to = 1.5) Finalmente, para cada valor de \\(x_k\\) que está en el conjunto de datos \\(\\{x_1,...,x_n\\}\\), ajustamos una recta de mínimos cuadrados ponderados por los pesos \\(w_n(x)\\), es decir, minimizamos (en el caso lineal): \\[\\sum_{i=1}^nw_n(x_k)(y_i-ax_n-b)^2.\\] Observaciones: Cualquier función (continua y quizás diferenciable) con la forma de flan del tricubo que se desvanece fuera de \\((-1,1),\\) es creciente en \\((-1,0)\\) y decreciente en \\((0, 1)\\) es un buen candidato para usarse en lugar del tricubo. La razón por la que escogemos precisamente esta forma algebráica no tiene que ver con el análisis exploratorio, sino con las ventajas teóricas adicionales que tiene en la inferencia. El caso \\(\\lambda=2\\) es similar. La única diferencia es en el paso de ajuste, donde usamos funciones cuadráticas, y obtendríamos entonces tres familias de parámetros \\(a(x_k), b_1(x_k), b_2(x_k),\\) para cada \\(k \\in \\{1, \\ldots, N\\}\\). Caso de estudio: nacimientos en México Podemos usar el suavizamiento loess para entender y describir el comportamiento de series de tiempo, en las cuáles intentamos entender la dependencia de una serie de mediciones indexadas por el tiempo. Típicamente es necesario utilizar distintas componentes para describir exitosamente una serie de tiempo, y para esto usamos distintos tipos de suavizamientos. Veremos que distintas componentes varían en distintas escalas de tiempo (unas muy lentas, como la tendencia, otras más rapidamente, como variación quincenal, etc.). Este caso de estudio esta basado en un análisis propuesto por A. Vehtari y A. Gelman, junto con un análisis de serie de tiempo de William S. Cleveland (1993). En nuestro caso, usaremos los datos de nacimientos registrados por día en México desde 1999. Los usaremos para contestar las preguntas: ¿cuáles son los cumpleaños más frecuentes? y ¿en qué mes del año hay más nacimientos? Podríamos utilizar una gráfica popular (ver por ejemplo esta visualización) como: Sin embargo, ¿cómo criticarías este análisis desde el punto de vista de los tres primeros principios del diseño analítico? ¿Las comparaciones son útiles? ¿Hay aspectos multivariados? ¿Qué tan bien explica o sugiere estructura, mecanismos o causalidad? Datos de natalidad para México library(lubridate) library(ggthemes) theme_set(theme_minimal(base_size = 14)) natalidad <- read_rds("./data/nacimientos/natalidad.rds") |> mutate(dia_semana = weekdays(fecha)) |> mutate(dia_año = yday(fecha)) |> mutate(año = year(fecha)) |> mutate(mes = month(fecha)) |> ungroup() |> mutate(dia_semana = recode(dia_semana, Monday = "Lunes", Tuesday = "Martes", Wednesday = "Miércoles", Thursday = "Jueves", Friday = "Viernes", Saturday = "Sábado", Sunday = "Domingo")) |> #necesario pues el LOCALE puede cambiar mutate(dia_semana = recode(dia_semana, lunes = "Lunes", martes = "Martes", miércoles = "Miércoles", jueves = "Jueves", viernes = "Viernes", sábado = "Sábado", domingo = "Domingo")) |> mutate(dia_semana = fct_relevel(dia_semana, c("Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"))) Consideremos los datos agregados del número de nacimientos (registrados) por día desde 1999 hasta 2016. Un primer intento podría ser hacer una gráfica de la serie de tiempo. Sin embargo, vemos que no es muy útil: Hay varias características que notamos. Primero, parece haber una tendencia ligeramente decreciente del número de nacimientos a lo largo de los años. Segundo, la gráfica sugiere un patrón anual. Y por último, encontramos que hay dispersión producida por los días de la semana. Sólo estas características hacen que la comparación entre días sea difícil de realizar. Supongamos que comparamos el número de nacimientos de dos miércoles dados. Esa comparación será diferente dependiendo: del año donde ocurrieron, el mes donde ocurrieron, si semana santa ocurrió en algunos de los miércoles, y así sucesivamente. Como en nuestros ejemplos anteriores, la idea del siguiente análisis es aislar las componentes que observamos en la serie de tiempo: extraemos componentes ajustadas, y luego examinamos los residuales. En este caso particular, asumiremos una descomposición aditiva de la serie de tiempo (William S. Cleveland 1993). En el estudio de series de tiempo una estructura común es considerar el efecto de diversos factores como tendencia, estacionalidad, ciclicidad e irregularidades de manera aditiva. Esto es, consideramos la descomposición \\[\\begin{align} y(t) = f_{t}(t) + f_{e}(t) + f_{c}(t) + \\varepsilon. \\end{align}\\] Una estrategia de ajuste, como veremos más adelante, es proceder de manera modular. Es decir, se ajustan los componentes de manera secuencial considerando los residuales de los anteriores. Tendencia Comenzamos por extraer la tendencia, haciendo promedios loess (William S. Cleveland 1979) con vecindades relativamente grandes. Quizá preferiríamos suavizar menos para capturar más variación lenta, pero si hacemos esto en este punto empezamos a absorber parte de la componente anual: mod_1 <- loess(n ~ as.numeric(fecha), data = natalidad, span = 0.2, degree = 1) datos_dia <- natalidad |> mutate(ajuste_1 = fitted(mod_1)) |> mutate(res_1 = n - ajuste_1) Notemos que a principios de 2000 el suavizador está en niveles de alrededor de 7000 nacimientos diarios, hacia 2015 ese número es más cercano a unos 6000. Componente anual Al obtener la tendencia podemos aislar el efecto a largo plazo y proceder a realizar mejores comparaciones (por ejemplo, comparar un día de 2000 y de 2015 tendria más sentido). Ahora, ajustamos los residuales del suavizado anterior, pero con menos suavizamiento. Así evitamos capturar tendencia: mod_anual <- loess(res_1 ~ as.numeric(fecha), data = datos_dia, degree = 2, span = 0.005) datos_dia <- datos_dia |> mutate(ajuste_2 = fitted(mod_anual)) |> mutate(res_2 = res_1 - ajuste_2) Día de la semana Hasta ahora, hemos aislado los efectos por plazos largos de tiempo (tendencia) y hemos incorporado las variaciones estacionales (componente anual) de nuestra serie de tiempo. Ahora, veremos cómo capturar el efecto por día de la semana. En este caso, podemos hacer suavizamiento loess para cada serie de manera independiente datos_dia <- datos_dia |> group_by(dia_semana) |> nest() |> mutate(ajuste_mod = map(data, ~ loess(res_2 ~ as.numeric(fecha), data = .x, span = 0.1, degree = 1))) |> mutate(ajuste_3 = map(ajuste_mod, fitted)) |> select(-ajuste_mod) |> unnest(cols = c(data, ajuste_3)) |> mutate(res_3 = res_2 - ajuste_3) |> ungroup() Residuales Por último, examinamos los residuales finales quitando los efectos ajustados: ## `geom_smooth()` using formula = 'y ~ x' Observación: nótese que la distribución de estos residuales presenta irregularidades interesantes. La distribución es de colas largas, y no se debe a unos cuantos datos atípicos. Esto generalmente es indicación que hay factores importantes que hay que examinar mas a detalle en los residuales: Reestimación Cuando hacemos este proceso secuencial de llevar el ajuste a los residual, a veces conviene iterarlo. La razón es que en una segunda o tercera pasada podemos hacer mejores estimaciones de cada componente, y es posible suavizar menos sin capturar componentes de más alta frecuencia. Así que podemos regresar a la serie original para hacer mejores estimaciones, más suavizadas: # Quitamos componente anual y efecto de día de la semana datos_dia <- datos_dia |> mutate(n_1 = n - ajuste_2 - ajuste_3) # Reajustamos mod_1 <- loess(n_1 ~ as.numeric(fecha), data = datos_dia, span = 0.02, degree = 2, family = "symmetric") Y ahora repetimos con la componente de día de la semana: Análisis de componentes Ahora comparamos las componentes estimadas y los residuales en una misma gráfica. Por definición, la suma de todas estas componentes da los datos originales. Este último paso nos permite diversas comparaciones que explican la variación que vimos en los datos. Una gran parte de los residuales está entre \\(\\pm 250\\) nacimientos por día. Sin embargo, vemos que las colas tienen una dispersión mucho mayor: quantile(datos_dia$res_6, c(00, .01,0.05, 0.10, 0.90, 0.95, 0.99, 1)) |> round() ## 0% 1% 5% 10% 90% 95% 99% 100% ## -2238 -1134 -315 -202 188 268 516 2521 ¿A qué se deben estas colas tan largas? Viernes 13? Podemos empezar con una curosidad. Los días Viernes o Martes 13, ¿nacen menos niños? Nótese que fue útil agregar el indicador de Semana santa por el Viernes 13 de Semana Santa que se ve como un atípico en el panel de los viernes 13. Residuales: antes y después de 2006 Veamos primero una agregación sobre los años de los residuales. Lo primero es observar un cambio que sucedió repentinamente en 2006: La razón es un cambio en la ley acerca de cuándo pueden entrar los niños a la primaria. Antes era por edad y había poco margen. Ese exceso de nacimientos son reportes falsos para que los niños no tuvieran que esperar un año completo por haber nacido unos cuantos días después de la fecha límite. Otras características que debemos investigar: Efectos de Año Nuevo, Navidad, Septiembre 16 y otros días feriados como Febrero 14. Semana santa: como la fecha cambia, vemos que los residuales negativos tienden a ocurrir dispersos alrededor del día 100 del año. Otros días especiales: más de residuales Ahora promediamos residuales (es posible agregar barras para indicar dispersión a lo largo de los años) para cada día del año. Podemos identificar ahora los residuales más grandes: se deben, por ejemplo, a días feriados, con consecuencias adicionales que tienen en días ajuntos (excesos de nacimientos): Semana santa Para Semana Santa tenemos que hacer unos cálculos. Si alineamos los datos por días antes de Domingo de Pascua, obtenemos un patrón de caída fuerte de nacimientos el Viernes de Semana Santa, y la característica forma de “valle con hombros” en días anteriores y posteriores estos Viernes. ¿Por qué ocurre este patrón? Nótese un defecto de nuestro modelo: el patrón de “hombros” alrededor del Viernes Santo no es suficientemente fuerte para equilibrar los nacimientos faltantes. ¿Cómo podríamos mejorar nuestra descomposición? Referencias "],["apéndice-principios-de-visualizacion.html", "Apéndice: Principios de visualizacion Introducción Visualización popular de datos Teoría de visualización de datos Ejemplo: gráfica de Minard", " Apéndice: Principios de visualizacion “The simple graph has brought more information to the data analyst’s mind than any other device.” — John Tukey El cuarteto de Anscombe En 1971 un estadístico llamado Frank Anscombe (fundador del departamento de Estadística de la Universidad de Yale) publicó cuatro conjuntos de dato. Cada uno consiste de 11 observaciones. La peculariedad de estos conjuntos es que tienen las mismas propiedades estadísticas. Sin embargo, cuando analizamos los datos de manera gráfica en un histograma encontramos rápidamente que los conjuntos de datos son muy distintos. Media de \\(x\\): 9 Varianza muestral de \\(x\\): 11 Media de \\(y\\): 7.50 Varianza muestral de \\(y\\): 4.12 Correlación entre \\(x\\) y \\(y\\): 0.816 Línea de regresión lineal: \\(y = 3.00 + 0.500x\\) En la gráfica del primer conjunto de datos, se ve clara una relación lineal simple con un modelo que cumple los supuestos de normalidad. La segunda gráfica (arriba a la derecha) muestra unos datos que tienen una asociación pero definitivamente no es lineal. En la tercera gráfica (abajo a la izquierda) están puntos alineados perfectamente en una línea recta, excepto por uno de ellos. En la última gráfica podemos ver un ejemplo en el cual basta tener una observación atípica para que se produzca un coeficiente de correlación alto aún cuando en realidad no existe una asociación lineal entre las dos variables. El cuarteto de Ascombe inspiró una técnica reciente para crear datos que comparten las mismas propiedades estadísticas al igual que en el cuarteto, pero que producen gráficas muy distintas (Matejka, Fitzmaurice). Introducción La visualización de datos no trata de hacer gráficas “bonitas” o “divertidas”, ni de simplificar lo complejo o ayudar a una persona “que no entiende mucho” a entender ideas complejas. Más bien, trata de aprovechar nuestra gran capacidad de procesamiento visual para exhibir de manera clara aspectos importantes de los datos. El siguiente ejemplo de (Tufte 2006), ilustra claramente la diferencia entre estos dos enfoques. A la izquierda están gráficas (más o menos típicas de Powerpoint) basadas en la filosofía de simplificar, de intentar no “ahogar” al lector con datos. El resultado es una colección incoherente, de bajo contenido, que no tiene mucho qué decir y que es, “indeferente al contenido y la evidencia”. A la derecha está una variación del rediseño de Tufte en forma de tabla, que en este caso particular es una manera eficiente de mostrar claramente los patrones que hay en este conjunto simple de datos. ¿Qué principios son los que soportan la efectividad de esta tabla sobre la gráfica de la derecha? Veremos que hay dos conjuntos de principios importantes: unos relacionados con el diseño y otros con la naturaleza del análisis de datos, independientemente del método de visualización. Visualización popular de datos Publicaciones populares (periódicos, revistas, sitios internet) muchas veces incluyen visualización de datos como parte de sus artículos o reportajes. En general siguen el mismo patrón que en la visión tradicionalista de la estadística: sirven más para divertir que para explicar, tienden a explicar ideas simples y conjuntos chicos de datos, y se consideran como una “ayuda” para los “lectores menos sofisticados”. Casi siempre se trata de gráficas triviales (muchas veces con errores graves) que no aportan mucho a artículos que tienen un nivel de complejidad mucho mayor (es la filosofía: lo escrito para el adulto, lo graficado para el niño). Teoría de visualización de datos Existe teoría fundamentada acerca de la visualización. Después del trabajo pionero de Tukey, los principios e indicadores de Tufte se basan en un estudio de la historia de la graficación y ejercicios de muestreo de la práctica gráfica a lo largo de varias disciplinas (¿cuáles son las mejores gráficas? ¿por qué?) El trabajo de Cleveland es orientado a la práctica del análisis de datos (¿cuáles gráficas nos han ayudado a mostrar claramente los resultados del análisis?), por una parte, y a algunos estudios de percepción visual. En resumen, hablaremos de las siguientes guías: Principios generales del diseño analítico Aplicables a una presentación o análisis completos, y como guía para construir nuevas visualizaciones (Tufte 2006). Principio 1. Muestra comparaciones, contrastes, diferencias. Principio 2. Muestra causalidad, mecanismo, explicación, estructura sistemática. Principio 3. Muestra datos multivariados, es decir, más de una o dos variables. Principio 4. Integra palabras, números, imágenes y diagramas. Principio 5. Describe la totalidad de la evidencia. Muestra fuentes usadas y problemas relevantes. Principio 6. Las presentaciones analíticas, a fin de cuentas, se sostienen o caen dependiendo de la calidad, relevancia e integridad de su contenido. Técnicas de visualización Esta categoría incluye técnicas específicas que dependen de la forma de nuestros datos y el tipo de pregunta que queremos investigar (Tukey (1977), William S. Cleveland (1993), W. S. Cleveland (1994), Tufte (2006)). Tipos de gráficas: cuantiles, histogramas, caja y brazos, gráficas de dispersión, puntos/barras/ líneas, series de tiempo. Técnicas para mejorar gráficas: Transformación de datos, transparencia, vibración, banking 45, suavizamiento y bandas de confianza. Pequeños múltiplos Indicadores de calidad gráfica Aplicables a cualquier gráfica en particular. Estas son guías concretas y relativamente objetivas para evaluar la calidad de una gráfica (Tufte 1986). Integridad Gráfica. El factor de engaño, es decir, la distorsión gráfica de las cantidades representadas, debe ser mínimo. Chartjunk. Minimizar el uso de decoración gráfica que interfiera con la interpretación de los datos: 3D, rejillas, rellenos con patrones. Tinta de datos. Maximizar la proporción de tinta de datos vs. tinta total de la gráfica. For non-data- ink, less is more. For data-ink, less is a bore. Densidad de datos. Las mejores gráficas tienen mayor densidad de datos, que es la razón entre el tamaño del conjunto de datos y el área de la gráfica. Las gráficas se pueden encoger mucho. Percepción visual. Algunas tareas son más fáciles para el ojo humano que otras (W. S. Cleveland 1994). Factor de engaño y Chartjunk El factor de engaño es el cociente entre el efecto mostrado en una gráfica y el efecto correspondiente en los datos. Idealmente, el factor de engaño debe ser 1 (ninguna distorsión). El chartjunk son aquellos elementos gráficos que no corresponden a variación de datos, o que entorpecen la interpretación de una gráfica. Estos son los indicadores de calidad más fáciles de entender y aplicar, y afortunadamente cada vez son menos comunes. Un diseño popular que califica como chartjunk y además introduce factores de engaño es el pie de 3D. En la gráfica de la derecha, podemos ver como la rebanada C se ve más grande que la rebanada A, aunque claramente ese no es el caso (factor de engaño). La razón es la variación en la perspectiva que no corresponde a variación en los datos (chartjunk). Crítica gráfica: Gráfica de pie Todavía elementos que pueden mejorar la comprensión de nuestra gráfica de pie: se trata de la decodificiación que hay que hacer categoría - color - cuantificación. Podemos agregar las etiquetas como se muestra en la serie de la derecha, pero entonces: ¿por qué no mostrar simplemente la tabla de datos? ¿qué agrega el pie a la interpretación? La deficiencias en el pie se pueden ver claramente al intentar graficar más categorías (13) . En el primer pie no podemos distinguir realmente cuáles son las categorías grandes y cuáles las chicas, y es muy difícil tener una imagen mental clara de estos datos. Agregar los porcentajes ayuda, pero entonces, otra vez, preguntamos cuál es el propósito del pie. La tabla de la izquierda hace todo el trabajo (una vez que ordenamos las categrías de la más grande a la más chica). Es posible hacer una gráfica de barras como la de abajo a la izquierda. Hay otros tipos de chartjunk comunes: uno es la textura de barras, por ejemplo. El efecto es la producción de un efecto moiré que es desagradable y quita la atención de los datos, como en la gráfica de barras de abajo. Otro común son las rejillas, como mostramos en las gráficas de la izquierda. Nótese como en estos casos hay efectos ópticos no planeados que degradan la percepción de los patrones en los datos. Pequeños múltiplos y densidad gráfica La densidad de una gráfica es el tamaño del conjunto de datos que se grafica comparado con el área total de la gráfica. En el siguiente ejemplo, graficamos en logaritmo-10 de millones de cabezas de ganado en Francia (cerdos, res, ovejas y caballos). La gráfica de la izquierda es pobre en densidad pues sólo representa 4 datos. La manera más fácil de mejorar la densidad es hacer más chica la gráfica: La razón de este encogimiento es una que tiene qué ver con las oportunidades perdidas de una gráfica grande. Si repetimos este mismo patrón (misma escala, mismos tipos de ganado) para distintos países obtenemos la siguiente gráfica: Esta es una gráfica de puntos. Es útil como sustituto de una gráfica de barras, y es superior en el sentido de que una mayor proporción de la tinta que se usa es tinta de datos. Otra vez, mayor proporción de tinta de datos representa más oportunidades que se pueden capitalizar. Más pequeños múltiplos Los pequeños múltiplos presentan oportunidades para mostrar más acerca de nuestro problema de interés. Consideramos por ejemplo la relación de radiación solar y niveles de ozono: En el ejemplo anterior incluyendo una variable adicional (velocidad del viento) podemos entender más acerca de la relación de radiación solar y niveles de ozono: Tinta de datos Maximizar la proporción de tinta de datos en nuestras gráficas tiene beneficios inmediatos. La regla es: si hay tinta que no representa variación en los datos, o la eliminación de esa tinta no representa pérdidas de significado, esa tinta debe ser eliminada. El ejemplo más claro es el de las rejillas en gráficas y tablas: ¿Por qué usar grises en lugar de negros? La respuesta tiene qué ver con el principio de tinta de datos: si marcamos las diferencias sutil pero claramente, tenemos más oportunidades abiertas para hacer énfasis en lo que nos interesa: a una gráfica o tabla saturada no se le puede hacer más - es difícil agregar elementos adicionales que ayuden a la comprensión. Si comenzamos marcando con sutileza, entonces se puede hacer más. Los mapas geográficos son un buen ejemplo de este principio. El espacio en blanco es suficientemente bueno para indicar las fronteras en una tabla, y facilita la lectura: Para un ejemplo del proceso de rediseño de una tabla, ver aquí. Finalmente, podemos ver un ejemplo que intenta incorporar los elementos del diseño analítico, incluyendo pequeños múltiplos: Decoración Percepción de escala Entre la percepción visual y la interpretación de una gráfica están implícitas tareas visuales específicas que las personas debemos realizar para ver correctamente la gráfica. En la década de los ochenta, William S. Cleveland y Robert McGill realizaron algunos experimentos identificando y clasificando estas tareas para diferentes tipos de gráficos (William S. Cleveland and McGill 1984). En estos, se le pregunta a la persona que compare dos valores dentro de una gráfica, por ejemplo, en dos barras en una gráfica de barras, o dos rebanadas de una gráfica de pie. Los resultados de Cleveland y McGill fueron replicados por Heer y Bostock en 2010 y los resultados se muestran en las gráficas de la derecha: Ejemplo: gráfica de Minard Concluimos esta sección con una gráfica que, aunque poco común, ejemplifica los principios de una buena gráfica, y es reconocida como una de las mejores visualizaciones de la historia. Una gráfica excelente, presenta datos interesantes de forma bien diseñada: es una cuestión de fondo, de diseño, y estadística… [Se] compone de ideas complejas comunicadas con claridad, precisión y eficiencia. … [Es] lo que da al espectador la mayor cantidad de ideas, en el menor tiempo, con la menor cantidad de tinta, y en el espacio más pequeño. … Es casi siempre multivariado. … Una excelente gráfica debe decir la verdad acerca de los datos. (Tufte, 1983) La famosa visualización de Charles Joseph Minard de la marcha de Napoleón sobre Moscú, ilustra los principios de una buena gráfica. Tufte señala que esta imagen “bien podría ser el mejor gráfico estadístico jamás dibujado”, y sostiene que “cuenta una historia rica y coherente con sus datos multivariados, mucho más esclarecedora que un solo número que rebota en el tiempo”. Se representan seis variables: el tamaño del ejército, su ubicación en una superficie bidimensional, la dirección del movimiento del ejército y la temperatura en varias fechas durante la retirada de Moscú”. Hoy en día Minard es reconocido como uno de los principales contribuyentes a la teoría de análisis de datos y creación de infografías con un fundamento estadístico. Se grafican 6 variables: el número de tropas de Napoleón, la distancia, la temperatura, la latitud y la longitud, la dirección en que viajaban las tropas y la localización relativa a fechas específicas. La gráfica de Minard, como la describe E.J. Marey, parece “desafiar la pluma del historiador con su brutal elocuencia”, la combinación de datos del mapa, y la serie de tiempo, dibujados en 1869, “retratan una secuencia de pérdidas devastadoras que sufrieron las tropas de Napoleón en 1812”. Comienza en la izquierda, en la frontera de Polonia y Rusia, cerca del río Niemen. La línea gruesa dorada muestra el tamaño de la Gran Armada (422,000) en el momento en que invadía Rusia en junio de 1812. El ancho de esta banda indica el tamaño de la armada en cada punto del mapa. En septiembre, la armada llegó a Moscú, que ya había sido saqueada y dejada desértica, con sólo 100,000 hombres. El camino del retiro de Napoleón desde Moscú está representado por la línea oscura (gris) que está en la parte inferior, que está relacionada a su vez con la temperatura y las fechas en el diagrama de abajo. Fue un invierno muy frío, y muchos se congelaron en su salida de Rusia. Como se muestra en el mapa, cruzar el río Berezina fue un desastre, y el ejército de Napoleón logró regresar a Polonia con tan sólo 10,000 hombres. También se muestran los movimientos de las tropas auxiliaries, que buscaban proteger por atrás y por la delantera mientras la armada avanzaba hacia Moscú. La gráfica de Minard cuenta una historia rica y cohesiva, coherente con datos multivariados y con los hechos históricos, y que puede ser más ilustrativa que tan sólo representar un número rebotando a lo largo del tiempo. Referencias "],["referencias.html", "Referencias", " Referencias "],["404.html", "Page not found", " Page not found The page you requested cannot be found (perhaps it was moved or renamed). You may want to try searching to find the page's new location, or use the table of contents to find the page you are looking for. "]] +[["index.html", "Fundamentos de Estadística con Remuestreo Información del curso", " Fundamentos de Estadística con Remuestreo Teresa Ortiz, Felipe González, Alfredo Garbuno Información del curso Notas del curso Fundamentos de Estadística con Remuestreo, este curso busca explicar los principios básicos de la estadística y su papel en el análisis de datos. Nuestro punto de vista es uno de fundamentos, con menos énfasis en recetas o técnicas particulares. Ligas Notas: https://tereom.github.io/fundamentos-2024/ Repositorio con material: https://github.com/tereom/fundamentos-2024 Correo: teresa.ortiz.mancera@gmail.com Zoom clase (miércoles 4:00-7:00 pm): https://itam.zoom.us/j/92745909276 Zoom sesiones de dudas (lunes y viernes de 5:00-6:00 pm): https://itam.zoom.us/j/92518922348 Canvas: https://itam.instructure.com/courses/13328 Este trabajo está bajo una Licencia Creative Commons Atribución 4.0 Internacional. "],["temario.html", "Temario Plan semanal Evaluación", " Temario Plan semanal Datos y análisis exploratorio Referencias: (W. S. Cleveland 1994), (Chihara and Hesterberg 2018) Visualización1 Análisis exploratorio Tipos de datos o estudios Muestras diseñadas y muestras naturales Experimentos y datos observacionales Introducción a Pruebas de Hipótesis Referencias: (Chihara and Hesterberg 2018) Introducción a pruebas de hipótesis. Pruebas de permutaciones Muestras pareadas y otros ejemplos Estimación y distribución de muestreo Referencias: (Chihara and Hesterberg 2018), (Hesterberg 2015) Estimadores y su distribución de muestreo Repaso de probabilidad y Teorema del límite central Introducción a estimación por intervalos Referencias: (Chihara and Hesterberg 2018), (Efron and Tibshirani 1993), (Hesterberg 2015) El método plugin y el boostrap Bootstrap e Intervalos de confianza. Ejemplos. Estimación Referencias: (Chihara and Hesterberg 2018), (Wasserman 2013) Estimación por máxima verosimilitud Ejemplos de estimación por máxima verosimilitud y Bootstrap paramétrico Propiedades de estimadores de máxima verosimilitud Más de pruebas de hipótesis Referencias: (Chihara and Hesterberg 2018), (Wasserman 2013) Pruebas de hipótesis para medias y proporciones: una y dos poblaciones. Introducción a inferencia bayesiana Referencias: (Kruschke 2015) Introducción a inferencia bayesiana Ejemplos de distribuciones conjugadas Introducción a métodos computacionales básicos: Muestreadores Metrópolis y Gibbs Ejemplos de inferencia bayesiana en Stan Evaluación Se evaluará mediante tareas semanales y dos exámenes: Tareas semanales (20%) Examen parcial en clase y a casa (40%) Examen final a casa (40%) Referencias "],["análisis-exploratorio.html", "Sección 1 Análisis exploratorio El papel de la exploración en el análisis de datos Preguntas y datos Algunos conceptos básicos Ejemplos Suavizamiento loess Caso de estudio: nacimientos en México", " Sección 1 Análisis exploratorio “Exploratory data analysis can never be the whole story, but nothing else can serve as the foundation stone –as the first step.” — John Tukey El papel de la exploración en el análisis de datos El estándar científico para contestar preguntas o tomar decisiones es uno que se basa en el análisis de datos. Es decir, en primer lugar se deben reunir todos los datos que puedan contener o sugerir alguna guía para entender mejor la pregunta o la decisión a la que nos enfrentamos. Esta recopilación de datos —que pueden ser cualitativos, cuantitativos, o una mezcla de los dos— debe entonces ser analizada para extraer información relevante para nuestro problema. En análisis de datos existen dos distintos tipos de trabajo: El trabajo exploratorio o de detective: ¿cuáles son los aspectos importantes de estos datos? ¿qué indicaciones generales muestran los datos? ¿qué tareas de análisis debemos empezar haciendo? ¿cuáles son los caminos generales para formular con precisión y contestar algunas preguntas que nos interesen? El trabajo inferencial, confirmatorio, o de juez: ¿cómo evaluar el peso de la evidencia de los descubrimientos del paso anterior? ¿qué tan bien soportadas están las respuestas y conclusiones por nuestro conjunto de datos? Preguntas y datos Cuando observamos un conjunto de datos, independientemente de su tamaño, el paso inicial más importante es entender bajo qué proceso se generan los datos. A grandes rasgos, cuanto más sepamos de este proceso, mejor podemos contestar preguntas de interés. En muchos casos, tendremos que hacer algunos supuestos de cómo se generan estos datos para dar respuestas (condicionales a esos supuestos). Algunos conceptos básicos Empezamos explicando algunas ideas que no serán útiles más adelante. El primer concepto se refiere a entender cómo se distribuyen los datos a los largo de su escala de medición. Comenzamos con un ejemplo: los siguientes datos fueron registrados en un restaurante durante cuatro días consecutivos. library(tidyverse) library(patchwork) # organizar gráficas library(gt) # formatear tablas source("R/funciones_auxiliares.R") # usamos los datos tips del paquete reshape2 propinas <- read_csv("./data/propinas.csv") Y vemos una muestra slice_sample(propinas, n = 10) |> gt() #blackhgvac table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #blackhgvac thead, #blackhgvac tbody, #blackhgvac tfoot, #blackhgvac tr, #blackhgvac td, #blackhgvac th { border-style: none; } #blackhgvac p { margin: 0; padding: 0; } #blackhgvac .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #blackhgvac .gt_caption { padding-top: 4px; padding-bottom: 4px; } #blackhgvac .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #blackhgvac .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #blackhgvac .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #blackhgvac .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #blackhgvac .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #blackhgvac .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #blackhgvac .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #blackhgvac .gt_column_spanner_outer:first-child { padding-left: 0; } #blackhgvac .gt_column_spanner_outer:last-child { padding-right: 0; } #blackhgvac .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #blackhgvac .gt_spanner_row { border-bottom-style: hidden; } #blackhgvac .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #blackhgvac .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #blackhgvac .gt_from_md > :first-child { margin-top: 0; } #blackhgvac .gt_from_md > :last-child { margin-bottom: 0; } #blackhgvac .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #blackhgvac .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #blackhgvac .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #blackhgvac .gt_row_group_first td { border-top-width: 2px; } #blackhgvac .gt_row_group_first th { border-top-width: 2px; } #blackhgvac .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #blackhgvac .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #blackhgvac .gt_first_summary_row.thick { border-top-width: 2px; } #blackhgvac .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #blackhgvac .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #blackhgvac .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #blackhgvac .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #blackhgvac .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #blackhgvac .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #blackhgvac .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #blackhgvac .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #blackhgvac .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #blackhgvac .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #blackhgvac .gt_left { text-align: left; } #blackhgvac .gt_center { text-align: center; } #blackhgvac .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #blackhgvac .gt_font_normal { font-weight: normal; } #blackhgvac .gt_font_bold { font-weight: bold; } #blackhgvac .gt_font_italic { font-style: italic; } #blackhgvac .gt_super { font-size: 65%; } #blackhgvac .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #blackhgvac .gt_asterisk { font-size: 100%; vertical-align: 0; } #blackhgvac .gt_indent_1 { text-indent: 5px; } #blackhgvac .gt_indent_2 { text-indent: 10px; } #blackhgvac .gt_indent_3 { text-indent: 15px; } #blackhgvac .gt_indent_4 { text-indent: 20px; } #blackhgvac .gt_indent_5 { text-indent: 25px; } #blackhgvac .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #blackhgvac div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } cuenta_total propina fumador dia momento num_personas 28.15 3.00 Si Sab Cena 5 12.54 2.50 No Dom Cena 2 10.63 2.00 Si Sab Cena 2 20.29 3.21 Si Sab Cena 2 9.94 1.56 No Dom Cena 2 12.43 1.80 No Jue Comida 2 15.98 2.03 No Jue Comida 2 19.49 3.51 No Dom Cena 2 18.35 2.50 No Sab Cena 4 26.59 3.41 Si Sab Cena 3 Aquí la unidad de observación es una cuenta particular. Tenemos tres mediciones numéricas de cada cuenta: cúanto fue la cuenta total, la propina, y el número de personas asociadas a la cuenta. Los datos están separados según se fumó o no en la mesa, y temporalmente en dos partes: el día (Jueves, Viernes, Sábado o Domingo), cada uno separado por Cena y Comida. Denotamos por \\(x\\) el valor de medición de una unidad de observación. Usualmente utilizamos sub-índices para identificar entre diferentes puntos de datos (observaciones), por ejemplo, \\(x_n\\) para la \\(n-\\)ésima observación. De tal forma que una colección de \\(N\\) observaciones la escribimos como \\[\\begin{align} \\{x_1, \\ldots, x_N\\}. \\end{align}\\] El primer tipo de comparaciones que nos interesa hacer es para una medición: ¿Varían mucho o poco los datos de un tipo de medición? ¿Cuáles son valores típicos o centrales? ¿Existen valores atípicos? Supongamos entonces que consideramos simplemente la variable de cuenta_total. Podemos comenzar por ordenar los datos, y ver cuáles datos están en los extremos y cuáles están en los lugares centrales: propinas <- propinas |> mutate(orden_cuenta = rank(cuenta_total, ties.method = "first"), f = (orden_cuenta - 0.5) / n()) cuenta <- propinas |> select(orden_cuenta, f, cuenta_total) |> arrange(f) bind_rows(head(cuenta), tail(cuenta)) |> gt() |> fmt_number(columns = f, decimals = 3) #cmkrduxrmj table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #cmkrduxrmj thead, #cmkrduxrmj tbody, #cmkrduxrmj tfoot, #cmkrduxrmj tr, #cmkrduxrmj td, #cmkrduxrmj th { border-style: none; } #cmkrduxrmj p { margin: 0; padding: 0; } #cmkrduxrmj .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #cmkrduxrmj .gt_caption { padding-top: 4px; padding-bottom: 4px; } #cmkrduxrmj .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #cmkrduxrmj .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #cmkrduxrmj .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #cmkrduxrmj .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #cmkrduxrmj .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #cmkrduxrmj .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #cmkrduxrmj .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #cmkrduxrmj .gt_column_spanner_outer:first-child { padding-left: 0; } #cmkrduxrmj .gt_column_spanner_outer:last-child { padding-right: 0; } #cmkrduxrmj .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #cmkrduxrmj .gt_spanner_row { border-bottom-style: hidden; } #cmkrduxrmj .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #cmkrduxrmj .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #cmkrduxrmj .gt_from_md > :first-child { margin-top: 0; } #cmkrduxrmj .gt_from_md > :last-child { margin-bottom: 0; } #cmkrduxrmj .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #cmkrduxrmj .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #cmkrduxrmj .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #cmkrduxrmj .gt_row_group_first td { border-top-width: 2px; } #cmkrduxrmj .gt_row_group_first th { border-top-width: 2px; } #cmkrduxrmj .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #cmkrduxrmj .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #cmkrduxrmj .gt_first_summary_row.thick { border-top-width: 2px; } #cmkrduxrmj .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #cmkrduxrmj .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #cmkrduxrmj .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #cmkrduxrmj .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #cmkrduxrmj .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #cmkrduxrmj .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #cmkrduxrmj .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #cmkrduxrmj .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #cmkrduxrmj .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #cmkrduxrmj .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #cmkrduxrmj .gt_left { text-align: left; } #cmkrduxrmj .gt_center { text-align: center; } #cmkrduxrmj .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #cmkrduxrmj .gt_font_normal { font-weight: normal; } #cmkrduxrmj .gt_font_bold { font-weight: bold; } #cmkrduxrmj .gt_font_italic { font-style: italic; } #cmkrduxrmj .gt_super { font-size: 65%; } #cmkrduxrmj .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #cmkrduxrmj .gt_asterisk { font-size: 100%; vertical-align: 0; } #cmkrduxrmj .gt_indent_1 { text-indent: 5px; } #cmkrduxrmj .gt_indent_2 { text-indent: 10px; } #cmkrduxrmj .gt_indent_3 { text-indent: 15px; } #cmkrduxrmj .gt_indent_4 { text-indent: 20px; } #cmkrduxrmj .gt_indent_5 { text-indent: 25px; } #cmkrduxrmj .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #cmkrduxrmj div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } orden_cuenta f cuenta_total 1 0.002 3.07 2 0.006 5.75 3 0.010 7.25 4 0.014 7.25 5 0.018 7.51 6 0.023 7.56 239 0.977 44.30 240 0.982 45.35 241 0.986 48.17 242 0.990 48.27 243 0.994 48.33 244 0.998 50.81 También podemos graficar los datos en orden, interpolando valores consecutivos. A esta función le llamamos la función de cuantiles para la variable cuenta_total. Nos sirve para comparar directamente los distintos valores que observamos los datos según el orden que ocupan. En particular, podemos estudiar la dispersión y valores centrales de los datos observados: El rango de datos va de unos 3 dólares hasta 50 dólares Los valores centrales, por ejemplo el 50% de los valores más centrales, están entre unos 13 y 25 dólares. El valor que divide en dos mitades iguales a los datos es de alrededor de 18 dólares. El cuantil \\(f\\), que denotamos por \\(q(f)\\) es valor a lo largo de la escala de medición de los datos tal que aproximadamente una fracción \\(f\\) de los datos son menores o iguales a \\(q(f)\\). Al cuantil \\(f=0.5\\) le llamamos la mediana. A los cuantiles \\(f=0.25\\) y \\(f=0.75\\) les llamamos cuartiles inferior y superior. En nuestro ejemplo: Los valores centrales —del cuantil 0.25 al 0.75, por decir un ejemplo— están entre unos 13 y 25 dólares. Estos dos cuantiles se llaman cuartil inferior y cuartil superior respectivamente El cuantil 0.5 (o también conocido como mediana) está alrededor de 18 dólares. Éste último puede ser utilizado para dar un valor central de la distribución de valores para cuenta_total. Asimismo podemos dar resúmenes más refinados si es necesario. Por ejemplo, podemos reportar que: El cuantil 0.95 es de unos 35 dólares — sólo 5% de las cuentas son de más de 35 dólares El cuantil 0.05 es de unos 8 dólares — sólo 5% de las cuentas son de 8 dólares o menos. Finalmente, la forma de la gráfica se interpreta usando su pendiente (tasa de cambio) haciendo comparaciones en diferentes partes de la gráfica: La distribución de valores tiene asimetría: el 10% de las cuentas más altas tiene considerablemente más dispersión que el 10% de las cuentas más bajas. Entre los cuantiles 0.2 y 0.7 es donde existe mayor densidad de datos: la pendiente (tasa de cambio) es baja, lo que significa que al avanzar en los valores observados, los cuantiles (el porcentaje de casos) aumenta rápidamente. Cuando la pendiente alta, quiere decir que los datos tienen más dispersión local o están más separados. Observación: Hay varias maneras de definir los cuantiles (ver (William S. Cleveland 1993)): Supongamos que queremos definir \\(q(f)\\), y denotamos los datos ordenados como \\(x_{(1)}, x_{(2)}, \\ldots, x_{(N)}\\), de forma que \\(x_{(1)}\\) es el dato más chico y \\(x_{(N)}\\) es el dato más grande. Para cada \\(x_{(i)}\\) definimos \\[f_i = i / N\\] entonces definimos el cuantil \\(q(f_i)=x_{(i)}\\). Para cualquier \\(f\\) entre 0 y 1, podemos definir \\(q(f)\\) como sigue: si \\(f\\) está entre \\(f_i\\) y \\(f_{i+1}\\) interpolamos linealmente los valores correspondientes \\(x_{(i)}\\) y \\(x_{(i+1)}\\). En la práctica, es más conveniente usar \\(f_i= \\frac{i - 0.5}{N}\\). La gráfica de cuantiles no cambia mucho comparado con la difinición anterior, y esto nos permitirá comparar de mejor manera con distribuciones teóricas que no tienen definido su cuantil 0 y el 1, pues tienen soporte en los números reales (como la distribución normal, por ejemplo). Asociada a la función de cuantiles \\(q\\) tenemos la distribución acumulada empírica de los datos, que es aproximadamente inversa de la función de cuantiles, y se define como: \\[\\hat{F}(x) = i/N\\] si \\(x_{(i)} \\leq x < x_{(i+1)}\\). Nótese que \\(\\hat{F}(q(f_i)) = i/N = f_i\\) (demuéstralo). acum_cuenta <- ecdf(cuenta$cuenta_total) cuenta <- cuenta |> mutate(dea_cuenta_total = acum_cuenta(cuenta_total)) g_acum <- ggplot(cuenta, aes(x = cuenta_total, y = dea_cuenta_total)) + geom_point() + labs(subtitle = "Distribución acum empírica de cuenta total", x = "") g_cuantiles + g_acum La función de distribución acumulada empírica es otra forma de graficar la dispersión de los datos. En su gráfica vemos que proporción de los datos que son iguales o están por debajo de cada valor en el eje horizontal. Nota: En análisis de datos, es más frecuente utilizar la función de cuantiles pues existen versiones más generales que son útiles, por ejemplo, para evaluar ajuste de modelos probabilísticos En la teoría, generalmente es más común utilizar la fda empírica, que tiene una única definición que veremos coincide con definiciones teóricas. Histogramas En algunos casos, es más natural hacer un histograma, donde dividimos el rango de la variable en cubetas o intervalos (en este caso de igual longitud), y graficamos por medio de barras cuántos datos caen en cada cubeta: Es una gráfica más popular, pero perdemos cierto nivel de detalle, y distintas particiones resaltan distintos aspectos de los datos. ¿Cómo se ve la gráfica de cuantiles de las propinas? ¿Cómo crees que esta gráfica se compara con distintos histogramas? g_1 <- ggplot(propinas, aes(sample = propina)) + geom_qq(distribution = stats::qunif) + labs(x = "f", y = "propina") g_1 Finalmente, una gráfica más compacta que resume la gráfica de cuantiles o el histograma es el diagrama de caja y brazos. Mostramos dos versiones, la clásica de Tukey (T) y otra versión menos común de Spear/Tufte (ST): library(ggthemes) cuartiles <- quantile(cuenta$cuenta_total) cuartiles |> round(2) ## 0% 25% 50% 75% 100% ## 3.07 13.35 17.80 24.13 50.81 g_1 <- ggplot(cuenta, aes(x = f, y = cuenta_total)) + labs(subtitle = "Gráfica de cuantiles: Cuenta total") + geom_hline(yintercept = cuartiles[2:4], colour = "gray") + geom_point(alpha = 0.5) + geom_line() g_2 <- ggplot(cuenta, aes(x = factor("ST", levels = "ST"), y = cuenta_total)) + geom_tufteboxplot() + labs(subtitle = "", x = "", y = "") g_3 <- ggplot(cuenta, aes(x = factor("T"), y = cuenta_total)) + geom_boxplot() + labs(subtitle = "", x = "", y = "") g_4 <- ggplot(cuenta, aes(x = factor("P"), y = cuenta_total)) + geom_jitter(height = 0, width =0.2, alpha = 0.5) + labs(subtitle = "", x = "", y = "") g_5 <- ggplot(cuenta, aes(x = factor("V"), y = cuenta_total)) + geom_violin() + labs(subtitle = "", x = "", y = "") g_1 + g_2 + g_3 + g_4 + plot_layout(widths = c(8, 2, 2, 2)) El diagrama de abajo explica los elementos de la versión típica del diagrama de caja y brazos (boxplot). RIC se refiere al Rango Intercuantílico, definido por la diferencia entre los cuantiles 25% y 75%. Figura: Jumanbar / CC BY-SA Ventajas en el análisis inicial En un principio del análisis, estos resúmenes (cuantiles) pueden ser más útiles que utilizar medias y varianzas, por ejemplo. La razón es que los cuantiles: Son cantidades más fácilmente interpretables Los cuantiles centrales son más resistentes a valores atípicos que medias o varianzas Permiten identificar valores extremos Es fácil comparar cuantiles de distintos bonches de datos en la misma escala Nota: Existen diferentes definiciones para calcular cuantiles de una muestra de datos, puedes leer más en este artículo. Media y desviación estándar Las medidas más comunes de localización y dispersión para un conjunto de datos son la media muestral y la desviación estándar muestral. En general, no son muy apropiadas para iniciar el análisis exploratorio, pues: Son medidas más difíciles de interpretar y explicar que los cuantiles. En este sentido, son medidas especializadas. Por ejemplo, compara una explicación intuitiva de la mediana contra una explicación intuitiva de la media. No son resistentes a valores atípicos. Su falta de resistencia los vuelve poco útiles en las primeras etapas de limpieza y descripción y en resúmenes deficientes para distribuciones irregulares (con colas largas por ejemplo). La media, o promedio, se denota por \\(\\bar x\\) y se define como \\[\\begin{align} \\bar x = \\frac1N \\sum_{n = 1}^N x_n. \\end{align}\\] La desviación estándar muestral se define como \\[\\begin{align} \\text{std}(x) = \\sqrt{\\frac1{N-1} \\sum_{n = 1}^N (x_n - \\bar x)^2}. \\end{align}\\] Observación: Si \\(N\\) no es muy chica, no importa mucho si dividimos por \\(N\\) o por \\(N-1\\) en la fórmula de la desviación estándar. La razón de que típicamente se usa \\(N-1\\) la veremos más adelante, en la parte de estimación. Por otro lado, ventajas de estas medidas de centralidad y dispersión son: La media y desviación estándar son computacionalmente convenientes. Por lo tanto regresaremos a estas medidas una vez que estudiemos modelos de probabilidad básicos. En muchas ocasiones conviene usar estas medidas pues permite hacer comparaciones históricas o tradicionales —pues análisis anteriores pudieran estar basados en éstas. Considera el caso de tener \\(N\\) observaciones y asume que ya tienes calculado el promedio para dichas observaciones. Este promedio lo denotaremos por \\(\\bar x_N\\). Ahora, considera que has obtenido \\(M\\) observaciones más. Escribe una fórmula recursiva para la media del conjunto total de datos \\(\\bar x_{N+M}\\) en función de lo que ya tenías precalculado \\(\\bar x_N.\\) ¿En qué situaciones esta propiedad puede ser conveniente? Ejemplos Precios de casas En este ejemplo consideremos los datos de precios de ventas de la ciudad de Ames, Iowa. En particular nos interesa entender la variación del precio de las casas. Por este motivo calculamos los cuantiles que corresponden al 25%, 50% y 75% (cuartiles), así como el mínimo y máximo de los precios de las casas: quantile(casas |> pull(precio_miles)) ## 0% 25% 50% 75% 100% ## 37.9 132.0 165.0 215.0 755.0 Comprueba que el mínimo y máximo están asociados a los cuantiles 0% y 100%, respectivamente. Una posible comparación es considerar los precios y sus variación en función de zona de la ciudad en que se encuentra una vivienda. Podemos usar diagramas de caja y brazos para hacer una comparación burda de los precios en distintas zonas de la ciudad: ggplot(casas, aes(x = nombre_zona, y = precio_miles)) + geom_boxplot() + coord_flip() La primera pregunta que nos hacemos es cómo pueden variar las características de las casas dentro de cada zona. Para esto, podemos considerar el área de las casas. En lugar de graficar el precio, graficamos el precio por metro cuadrado, por ejemplo: ggplot(casas, aes(x = nombre_zona, y = precio_m2)) + geom_boxplot() + coord_flip() Podemos cuantificar la variación que observamos de zona a zona y la variación que hay dentro de cada una de las zonas. Una primera aproximación es observar las variación del precio al calcular la mediana dentro de cada zona, y después cuantificar por medio de cuantiles cómo varía la mediana entre zonas: casas |> group_by(nombre_zona) |> summarise(mediana_zona = median(precio_m2), .groups = "drop") |> arrange(mediana_zona) |> pull(mediana_zona) |> quantile() |> round() ## 0% 25% 50% 75% 100% ## 963 1219 1298 1420 1725 Por otro lado, las variaciones con respecto a las medianas dentro de cada zona, por grupo, se resume como: quantile(casas |> group_by(nombre_zona) |> mutate(residual = precio_m2 - median(precio_m2)) |> pull(residual)) |> round() ## 0% 25% 50% 75% 100% ## -765 -166 0 172 1314 Nótese que este último paso tiene sentido pues la variación dentro de las zonas, en términos de precio por metro cuadrado, es similar. Esto no lo podríamos haber hecho de manera efectiva si se hubiera utilizado el precio de las casas sin ajustar por su tamaño. Podemos resumir este primer análisis con un par de gráficas de cuantiles (William S. Cleveland (1993)): mediana <- median(casas$precio_m2) resumen <- casas |> select(nombre_zona, precio_m2) |> group_by(nombre_zona) |> mutate(mediana_zona = median(precio_m2)) |> mutate(residual = precio_m2 - mediana_zona) |> ungroup() |> mutate(mediana_zona = mediana_zona - mediana) |> select(nombre_zona, mediana_zona, residual) |> pivot_longer(mediana_zona:residual, names_to = "tipo", values_to = "valor") ggplot(resumen, aes(sample = valor)) + geom_qq(distribution = stats::qunif) + facet_wrap(~ tipo) + ylab("Precio por m2") + xlab("f") + labs(subtitle = "Precio por m2 por zona", caption = paste0("Mediana total de ", round(mediana))) Vemos que la mayor parte de la variación del precio por metro cuadrado ocurre dentro de cada zona, una vez que controlamos por el tamaño de las casas. La variación dentro de cada zona es aproximadamente simétrica, aunque la cola derecha es ligeramente más larga con algunos valores extremos. Podemos seguir con otro indicador importante: la calificación de calidad de los terminados de las casas. Como primer intento podríamos hacer: Lo que indica que las calificaciones de calidad están distribuidas de manera muy distinta a lo largo de las zonas, y que probablemente no va ser simple desentrañar qué variación del precio se debe a la zona y cuál se debe a la calidad. Prueba Enlace Consideremos la prueba Enlace (2011) de matemáticas para primarias. Una primera pregunta que alguien podría hacerse es: ¿cuáles escuelas son mejores en este rubro, las privadas o las públicas? enlace_tbl <- enlace |> group_by(tipo) |> summarise(n_escuelas = n(), cuantiles = list(cuantil(mate_6, c(0.05, 0.25, 0.5, 0.75, 0.95)))) |> unnest(cols = cuantiles) |> mutate(valor = round(valor)) enlace_tbl |> spread(cuantil, valor) |> gt() #sykxxonvyi table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #sykxxonvyi thead, #sykxxonvyi tbody, #sykxxonvyi tfoot, #sykxxonvyi tr, #sykxxonvyi td, #sykxxonvyi th { border-style: none; } #sykxxonvyi p { margin: 0; padding: 0; } #sykxxonvyi .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #sykxxonvyi .gt_caption { padding-top: 4px; padding-bottom: 4px; } #sykxxonvyi .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #sykxxonvyi .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #sykxxonvyi .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #sykxxonvyi .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #sykxxonvyi .gt_column_spanner_outer:first-child { padding-left: 0; } #sykxxonvyi .gt_column_spanner_outer:last-child { padding-right: 0; } #sykxxonvyi .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #sykxxonvyi .gt_spanner_row { border-bottom-style: hidden; } #sykxxonvyi .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #sykxxonvyi .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #sykxxonvyi .gt_from_md > :first-child { margin-top: 0; } #sykxxonvyi .gt_from_md > :last-child { margin-bottom: 0; } #sykxxonvyi .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #sykxxonvyi .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #sykxxonvyi .gt_row_group_first td { border-top-width: 2px; } #sykxxonvyi .gt_row_group_first th { border-top-width: 2px; } #sykxxonvyi .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #sykxxonvyi .gt_first_summary_row.thick { border-top-width: 2px; } #sykxxonvyi .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #sykxxonvyi .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #sykxxonvyi .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_left { text-align: left; } #sykxxonvyi .gt_center { text-align: center; } #sykxxonvyi .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #sykxxonvyi .gt_font_normal { font-weight: normal; } #sykxxonvyi .gt_font_bold { font-weight: bold; } #sykxxonvyi .gt_font_italic { font-style: italic; } #sykxxonvyi .gt_super { font-size: 65%; } #sykxxonvyi .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #sykxxonvyi .gt_asterisk { font-size: 100%; vertical-align: 0; } #sykxxonvyi .gt_indent_1 { text-indent: 5px; } #sykxxonvyi .gt_indent_2 { text-indent: 10px; } #sykxxonvyi .gt_indent_3 { text-indent: 15px; } #sykxxonvyi .gt_indent_4 { text-indent: 20px; } #sykxxonvyi .gt_indent_5 { text-indent: 25px; } #sykxxonvyi .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #sykxxonvyi div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } tipo n_escuelas 0.05 0.25 0.5 0.75 0.95 Indígena/Conafe 13599 304 358 412 478 588 General 60166 380 454 502 548 631 Particular 6816 479 551 593 634 703 Para un análisis exploratorio podemos utilizar distintas gráficas. Por ejemplo, podemos utilizar nuevamente las gráficas de caja y brazos, así como graficar los percentiles. Nótese que en la gráfica 1 se utilizan los cuantiles 0.05, 0.25, 0.5, 0.75 y 0.95: ## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0. ## ℹ Please use `linewidth` instead. ## This warning is displayed once every 8 hours. ## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was ## generated. Se puede discutir qué tan apropiada es cada gráfica con el objetivo de realizar comparaciones. Sin duda, graficar más cuantiles es más útil para hacer comparaciones. Por ejemplo, en la Gráfica 1 podemos ver que la mediana de las escuelas generales está cercana al cuantil 5% de las escuelas particulares. Por otro lado, el diagrama de caja y brazos muestra también valores “atípicos”. Antes de contestar prematuramente la pregunta: ¿cuáles son las mejores escuelas? busquemos mejorar la interpretabilidad de nuestras comparaciones. Podemos comenzar por agregar, por ejemplo, el nivel del marginación del municipio donde se encuentra la escuela. Para este objetivo, podemos usar páneles (pequeños múltiplos útiles para hacer comparaciones) y graficar: Esta gráfica pone en contexto la pregunta inicial, y permite evidenciar la dificultad de contestarla. En particular: Señala que la pregunta no sólo debe concentarse en el tipo de “sistema”: pública, privada, etc. Por ejemplo, las escuelas públicas en zonas de marginación baja no tienen una distribución de calificaciones muy distinta a las privadas en zonas de marginación alta. El contexto de la escuela es importante. Debemos de pensar qué factores –por ejemplo, el entorno familiar de los estudiantes– puede resultar en comparaciones que favorecen a las escuelas privadas. Un ejemplo de esto es considerar si los estudiantes tienen que trabajar o no. A su vez, esto puede o no ser reflejo de la calidad del sistema educativo. Si esto es cierto, entonces la pregunta inicial es demasiado vaga y mal planteada. Quizá deberíamos intentar entender cuánto “aporta” cada escuela a cada estudiante, como medida de qué tan buena es cada escuela. Estados y calificaciones en SAT ¿Cómo se relaciona el gasto por alumno, a nivel estatal, con sus resultados académicos? Hay trabajo considerable en definir estos términos, pero supongamos que tenemos el siguiente conjunto de datos (Guber 1999), que son datos oficiales agregados por estado de Estados Unidos. Consideremos el subconjunto de variables sat, que es la calificación promedio de los alumnos en cada estado (para 1997) y expend, que es el gasto en miles de dólares por estudiante en (1994-1995). sat <- read_csv("data/sat.csv") sat_tbl <- sat |> select(state, expend, sat) |> gather(variable, valor, expend:sat) |> group_by(variable) |> summarise(cuantiles = list(cuantil(valor))) |> unnest(cols = c(cuantiles)) |> mutate(valor = round(valor, 1)) |> spread(cuantil, valor) sat_tbl |> gt() #sykxxonvyi table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #sykxxonvyi thead, #sykxxonvyi tbody, #sykxxonvyi tfoot, #sykxxonvyi tr, #sykxxonvyi td, #sykxxonvyi th { border-style: none; } #sykxxonvyi p { margin: 0; padding: 0; } #sykxxonvyi .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #sykxxonvyi .gt_caption { padding-top: 4px; padding-bottom: 4px; } #sykxxonvyi .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #sykxxonvyi .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #sykxxonvyi .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #sykxxonvyi .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #sykxxonvyi .gt_column_spanner_outer:first-child { padding-left: 0; } #sykxxonvyi .gt_column_spanner_outer:last-child { padding-right: 0; } #sykxxonvyi .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #sykxxonvyi .gt_spanner_row { border-bottom-style: hidden; } #sykxxonvyi .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #sykxxonvyi .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #sykxxonvyi .gt_from_md > :first-child { margin-top: 0; } #sykxxonvyi .gt_from_md > :last-child { margin-bottom: 0; } #sykxxonvyi .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #sykxxonvyi .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #sykxxonvyi .gt_row_group_first td { border-top-width: 2px; } #sykxxonvyi .gt_row_group_first th { border-top-width: 2px; } #sykxxonvyi .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #sykxxonvyi .gt_first_summary_row.thick { border-top-width: 2px; } #sykxxonvyi .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #sykxxonvyi .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #sykxxonvyi .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sykxxonvyi .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sykxxonvyi .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sykxxonvyi .gt_left { text-align: left; } #sykxxonvyi .gt_center { text-align: center; } #sykxxonvyi .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #sykxxonvyi .gt_font_normal { font-weight: normal; } #sykxxonvyi .gt_font_bold { font-weight: bold; } #sykxxonvyi .gt_font_italic { font-style: italic; } #sykxxonvyi .gt_super { font-size: 65%; } #sykxxonvyi .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #sykxxonvyi .gt_asterisk { font-size: 100%; vertical-align: 0; } #sykxxonvyi .gt_indent_1 { text-indent: 5px; } #sykxxonvyi .gt_indent_2 { text-indent: 10px; } #sykxxonvyi .gt_indent_3 { text-indent: 15px; } #sykxxonvyi .gt_indent_4 { text-indent: 20px; } #sykxxonvyi .gt_indent_5 { text-indent: 25px; } #sykxxonvyi .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #sykxxonvyi div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } variable 0 0.25 0.5 0.75 1 expend 3.7 4.9 5.8 6.4 9.8 sat 844.0 897.2 945.5 1032.0 1107.0 Esta variación es considerable para promedios del SAT: el percentil 75 es alrededor de 1050 puntos, mientras que el percentil 25 corresponde a alrededor de 800. Igualmente, hay diferencias considerables de gasto por alumno (miles de dólares) a lo largo de los estados. Ahora hacemos nuestro primer ejercico de comparación: ¿Cómo se ven las calificaciones para estados en distintos niveles de gasto? Podemos usar una gráfica de dispersión: library(ggrepel) ggplot(sat, aes(x = expend, y = sat, label = state)) + geom_point(colour = "red", size = 2) + geom_text_repel(colour = "gray50") + xlab("Gasto por alumno (miles de dólares)") + ylab("Calificación promedio en SAT") Estas comparaciones no son de alta calidad, solo estamos usando 2 variables —que son muy pocas— y no hay mucho que podamos decir en cuanto explicación. Sin duda nos hace falta una imagen más completa. Necesitaríamos entender la correlación que existe entre las demás características de nuestras unidades de estudio. Las unidades que estamos comparando pueden diferir fuertemente en otras propiedades importantes (o dimensiones), lo cual no permite interpretar la gráfica de manera sencilla. Una variable que tenemos es el porcentaje de alumnos de cada estado que toma el SAT. Podemos agregar como sigue: ggplot(sat, aes(x = expend, y = math, label=state, colour = frac)) + geom_point() + geom_text_repel() + xlab("Gasto por alumno (miles de dólares)") + ylab("Calificación en matemáticas") Esto nos permite entender por qué nuestra comparación inicial es relativamente pobre. Los estados con mejores resultados promedio en el SAT son aquellos donde una fracción relativamente baja de los estudiantes toma el examen. La diferencia es considerable. En este punto podemos hacer varias cosas. Una primera idea es intentar comparar estados más similares en cuanto a la población de alumnos que asiste. Podríamos hacer grupos como sigue: set.seed(991) k_medias_sat <- kmeans(sat |> select(frac), centers = 4, nstart = 100, iter.max = 100) sat$clase <- k_medias_sat$cluster sat <- sat |> group_by(clase) |> mutate(clase_media = round(mean(frac))) |> ungroup() |> mutate(clase_media = factor(clase_media)) sat <- sat |> mutate(rank_p = rank(frac, ties= "first") / length(frac)) ggplot(sat, aes(x = rank_p, y = frac, label = state, colour = clase_media)) + geom_point(size = 2) Estos resultados indican que es más probable que buenos alumnos decidan hacer el SAT. Lo interesante es que esto ocurre de manera diferente en cada estado. Por ejemplo, en algunos estados era más común otro examen: el ACT. Si hacemos clusters de estados según el % de alumnos, empezamos a ver otra historia. Para esto, ajustemos rectas de mínimos cuadrados como referencia: Esto da una imagen muy diferente a la que originalmente planteamos. Nota que dependiendo de cómo categorizamos, esta gráfica puede variar (puedes intentar con más o menos grupos, por ejemplo). Tablas de conteos Consideremos los siguientes datos de tomadores de té (del paquete FactoMineR (Lê et al. 2008)): tea <- read_csv("data/tea.csv") # nombres y códigos te <- tea |> select(how, price, sugar) |> rename(presentacion = how, precio = price, azucar = sugar) |> mutate( presentacion = fct_recode(presentacion, suelto = "unpackaged", bolsas = "tea bag", mixto = "tea bag+unpackaged"), precio = fct_recode(precio, marca = "p_branded", variable = "p_variable", barato = "p_cheap", marca_propia = "p_private label", desconocido = "p_unknown", fino = "p_upscale"), azucar = fct_recode(azucar, sin_azúcar = "No.sugar", con_azúcar = "sugar")) sample_n(te, 10) ## # A tibble: 10 × 3 ## presentacion precio azucar ## <fct> <fct> <fct> ## 1 bolsas marca sin_azúcar ## 2 bolsas variable sin_azúcar ## 3 bolsas marca con_azúcar ## 4 bolsas fino con_azúcar ## 5 mixto variable con_azúcar ## 6 mixto fino con_azúcar ## 7 bolsas marca sin_azúcar ## 8 bolsas fino sin_azúcar ## 9 mixto variable con_azúcar ## 10 mixto variable sin_azúcar Nos interesa ver qué personas compran té suelto, y de qué tipo. Empezamos por ver las proporciones que compran té según su empaque (en bolsita o suelto): precio <- te |> count(precio) |> mutate(prop = round(100 * n / sum(n))) |> select(-n) tipo <- te |> count(presentacion) |> mutate(pct = round(100 * n / sum(n))) tipo |> gt() #wiljiluquk table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #wiljiluquk thead, #wiljiluquk tbody, #wiljiluquk tfoot, #wiljiluquk tr, #wiljiluquk td, #wiljiluquk th { border-style: none; } #wiljiluquk p { margin: 0; padding: 0; } #wiljiluquk .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #wiljiluquk .gt_caption { padding-top: 4px; padding-bottom: 4px; } #wiljiluquk .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #wiljiluquk .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #wiljiluquk .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #wiljiluquk .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #wiljiluquk .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #wiljiluquk .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #wiljiluquk .gt_column_spanner_outer:first-child { padding-left: 0; } #wiljiluquk .gt_column_spanner_outer:last-child { padding-right: 0; } #wiljiluquk .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #wiljiluquk .gt_spanner_row { border-bottom-style: hidden; } #wiljiluquk .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #wiljiluquk .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #wiljiluquk .gt_from_md > :first-child { margin-top: 0; } #wiljiluquk .gt_from_md > :last-child { margin-bottom: 0; } #wiljiluquk .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #wiljiluquk .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #wiljiluquk .gt_row_group_first td { border-top-width: 2px; } #wiljiluquk .gt_row_group_first th { border-top-width: 2px; } #wiljiluquk .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #wiljiluquk .gt_first_summary_row.thick { border-top-width: 2px; } #wiljiluquk .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #wiljiluquk .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #wiljiluquk .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #wiljiluquk .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #wiljiluquk .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #wiljiluquk .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #wiljiluquk .gt_left { text-align: left; } #wiljiluquk .gt_center { text-align: center; } #wiljiluquk .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #wiljiluquk .gt_font_normal { font-weight: normal; } #wiljiluquk .gt_font_bold { font-weight: bold; } #wiljiluquk .gt_font_italic { font-style: italic; } #wiljiluquk .gt_super { font-size: 65%; } #wiljiluquk .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #wiljiluquk .gt_asterisk { font-size: 100%; vertical-align: 0; } #wiljiluquk .gt_indent_1 { text-indent: 5px; } #wiljiluquk .gt_indent_2 { text-indent: 10px; } #wiljiluquk .gt_indent_3 { text-indent: 15px; } #wiljiluquk .gt_indent_4 { text-indent: 20px; } #wiljiluquk .gt_indent_5 { text-indent: 25px; } #wiljiluquk .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #wiljiluquk div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } presentacion n pct bolsas 170 57 mixto 94 31 suelto 36 12 La mayor parte de las personas toma té en bolsas. Sin embargo, el tipo de té (en términos de precio o marca) que compran es muy distinto dependiendo de la presentación: tipo <- tipo |> select(presentacion, prop_presentacion = pct) tabla_cruzada <- te |> count(presentacion, precio) |> # porcentajes por presentación group_by(presentacion) |> mutate(prop = round(100 * n / sum(n))) |> select(-n) tabla_cruzada |> pivot_wider(names_from = presentacion, values_from = prop, values_fill = list(prop = 0)) |> gt() #sxkvcchtyg table { font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } #sxkvcchtyg thead, #sxkvcchtyg tbody, #sxkvcchtyg tfoot, #sxkvcchtyg tr, #sxkvcchtyg td, #sxkvcchtyg th { border-style: none; } #sxkvcchtyg p { margin: 0; padding: 0; } #sxkvcchtyg .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; } #sxkvcchtyg .gt_caption { padding-top: 4px; padding-bottom: 4px; } #sxkvcchtyg .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; } #sxkvcchtyg .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; } #sxkvcchtyg .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 6px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; } #sxkvcchtyg .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; } #sxkvcchtyg .gt_column_spanner_outer:first-child { padding-left: 0; } #sxkvcchtyg .gt_column_spanner_outer:last-child { padding-right: 0; } #sxkvcchtyg .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; } #sxkvcchtyg .gt_spanner_row { border-bottom-style: hidden; } #sxkvcchtyg .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; } #sxkvcchtyg .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; } #sxkvcchtyg .gt_from_md > :first-child { margin-top: 0; } #sxkvcchtyg .gt_from_md > :last-child { margin-bottom: 0; } #sxkvcchtyg .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; } #sxkvcchtyg .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; } #sxkvcchtyg .gt_row_group_first td { border-top-width: 2px; } #sxkvcchtyg .gt_row_group_first th { border-top-width: 2px; } #sxkvcchtyg .gt_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_first_summary_row { border-top-style: solid; border-top-color: #D3D3D3; } #sxkvcchtyg .gt_first_summary_row.thick { border-top-width: 2px; } #sxkvcchtyg .gt_last_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_first_grand_summary_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; } #sxkvcchtyg .gt_last_grand_summary_row_top { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_striped { background-color: rgba(128, 128, 128, 0.05); } #sxkvcchtyg .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; } #sxkvcchtyg .gt_footnotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_footnote { margin: 0px; font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; } #sxkvcchtyg .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; } #sxkvcchtyg .gt_left { text-align: left; } #sxkvcchtyg .gt_center { text-align: center; } #sxkvcchtyg .gt_right { text-align: right; font-variant-numeric: tabular-nums; } #sxkvcchtyg .gt_font_normal { font-weight: normal; } #sxkvcchtyg .gt_font_bold { font-weight: bold; } #sxkvcchtyg .gt_font_italic { font-style: italic; } #sxkvcchtyg .gt_super { font-size: 65%; } #sxkvcchtyg .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; } #sxkvcchtyg .gt_asterisk { font-size: 100%; vertical-align: 0; } #sxkvcchtyg .gt_indent_1 { text-indent: 5px; } #sxkvcchtyg .gt_indent_2 { text-indent: 10px; } #sxkvcchtyg .gt_indent_3 { text-indent: 15px; } #sxkvcchtyg .gt_indent_4 { text-indent: 20px; } #sxkvcchtyg .gt_indent_5 { text-indent: 25px; } #sxkvcchtyg .katex-display { display: inline-flex !important; margin-bottom: 0.75em !important; } #sxkvcchtyg div.Reactable > div.rt-table > div.rt-thead > div.rt-tr.rt-tr-group-header > div.rt-th-group:after { height: 0px !important; } precio bolsas mixto suelto marca 41 21 14 barato 3 1 3 marca_propia 9 4 3 desconocido 6 1 0 fino 8 20 56 variable 32 52 25 Estos datos podemos examinarlos un rato y llegar a conclusiones, pero esta tabla no necesariamente es la mejor manera de mostrar patrones en los datos. Tampoco son muy útiles gráficas como la siguiente: ggplot(tabla_cruzada |> ungroup() |> mutate(price = fct_reorder(precio, prop)), aes(x = precio, y = prop, group = presentacion, colour = presentacion)) + geom_point() + coord_flip() + geom_line() En lugar de eso, calcularemos perfiles columna. Esto es, comparamos cada una de las columnas con la columna marginal (en la tabla de tipo de estilo de té): num_grupos <- n_distinct(te |> select(presentacion)) tabla <- te |> count(presentacion, precio) |> group_by(presentacion) |> mutate(prop_precio = (100 * n / sum(n))) |> group_by(precio) |> mutate(prom_prop = sum(prop_precio)/num_grupos) |> mutate(perfil = 100 * (prop_precio / prom_prop - 1)) tabla ## # A tibble: 17 × 6 ## # Groups: precio [6] ## presentacion precio n prop_precio prom_prop perfil ## <fct> <fct> <int> <dbl> <dbl> <dbl> ## 1 bolsas marca 70 41.2 25.4 61.8 ## 2 bolsas barato 5 2.94 2.26 30.1 ## 3 bolsas marca_propia 16 9.41 5.48 71.7 ## 4 bolsas desconocido 11 6.47 2.51 158. ## 5 bolsas fino 14 8.24 28.0 -70.6 ## 6 bolsas variable 54 31.8 36.3 -12.5 ## 7 mixto marca 20 21.3 25.4 -16.4 ## 8 mixto barato 1 1.06 2.26 -52.9 ## 9 mixto marca_propia 4 4.26 5.48 -22.4 ## 10 mixto desconocido 1 1.06 2.51 -57.6 ## 11 mixto fino 19 20.2 28.0 -27.8 ## 12 mixto variable 49 52.1 36.3 43.6 ## 13 suelto marca 5 13.9 25.4 -45.4 ## 14 suelto barato 1 2.78 2.26 22.9 ## 15 suelto marca_propia 1 2.78 5.48 -49.3 ## 16 suelto fino 20 55.6 28.0 98.4 ## 17 suelto variable 9 25 36.3 -31.1 tabla_perfil <- tabla |> select(presentacion, precio, perfil, pct = prom_prop) |> pivot_wider(names_from = presentacion, values_from = perfil, values_fill = list(perfil = -100.0)) if_profile <- function(x){ any(x < 0) & any(x > 0) } marcar <- marcar_tabla_fun(25, "red", "black") tab_out <- tabla_perfil |> arrange(desc(bolsas)) |> select(-pct, everything()) |> mutate(across(where(is.numeric), \\(x) round(x, 0))) |> mutate(across(where(if_profile), \\(x) marcar(x))) |> knitr::kable(format_table_salida(), escape = FALSE, digits = 0, booktabs = T) |> kableExtra::kable_styling(latex_options = c("striped", "scale_down"), bootstrap_options = c( "hover", "condensed"), full_width = FALSE) tab_out precio bolsas mixto suelto pct desconocido 158 -58 -100 3 marca_propia 72 -22 -49 5 marca 62 -16 -45 25 barato 30 -53 23 2 variable -12 44 -31 36 fino -71 -28 98 28 Leemos esta tabla como sigue: por ejemplo, los compradores de té suelto compran té fino a una tasa casi el doble (98%) que el promedio. También podemos graficar como: tabla_graf <- tabla_perfil |> ungroup() |> mutate(precio = fct_reorder(precio, bolsas)) |> select(-pct) |> pivot_longer(cols = -precio, names_to = "presentacion", values_to = "perfil") g_perfil <- ggplot(tabla_graf, aes(x = precio, xend = precio, y = perfil, yend = 0, group = presentacion)) + geom_point() + geom_segment() + facet_wrap(~presentacion) + geom_hline(yintercept = 0 , colour = "gray")+ coord_flip() g_perfil Observación: hay dos maneras de construir la columna promedio: tomando los porcentajes sobre todos los datos, o promediando los porcentajes de las columnas. Si los grupos de las columnas están desbalanceados, estos promedios son diferentes. Cuando usamos porcentajes sobre la población, perfiles columna y renglón dan el mismo resultado Sin embargo, cuando hay un grupo considerablemente más grande que otros, las comparaciones se vuelven vs este grupo particular. No siempre queremos hacer esto. Interpretación En el último ejemplo de tomadores de té utilizamos una muestra de personas, no toda la población de tomadores de té. Eso quiere decir que tenemos cierta incertidumbre de cómo se generalizan o no los resultados que obtuvimos en nuestro análisis a la población general. Nuestra respuesta depende de cómo se extrajo la muestra que estamos considerando. Si el mecanismo de extracción incluye algún proceso probabilístico, entonces es posible en principio entender qué tan bien generalizan los resultados de nuestro análisis a la población general, y entender esto depende de entender qué tanta variación hay de muestra a muestra, de todas las posibles muestras que pudimos haber extraido. En las siguiente secciones discutiremos estos aspectos, en los cuales pasamos del trabajo de “detective” al trabajo de “juez” en nuestro trabajo analítico. Suavizamiento loess Las gráficas de dispersión son la herramienta básica para describir la relación entre dos variables cuantitativas, y como vimos en ejemplo anteriores, muchas veces podemos apreciar mejor la relación entre ellas si agregamos una curva loess que suavice. Los siguientes datos muestran los premios ofrecidos y las ventas totales de una lotería a lo largo de 53 sorteos (las unidades son cantidades de dinero indexadas). Graficamos en escalas logarítmicas y agregamos una curva loess. # cargamos los datos load(here::here("data", "ventas_sorteo.Rdata")) ggplot(ventas.sorteo, aes(x = premio, y = ventas.tot.1)) + geom_point() + geom_smooth(method = "loess", alpha = 0.5, degree = 1, se = FALSE) + scale_x_log10(breaks = c(20000, 40000, 80000)) + scale_y_log10(breaks = c(10000, 15000, 22000, 33000)) El patrón no era difícil de ver en los datos originales, sin embargo, la curva lo hace más claro, el logaritmo de las ventas tiene una relación no lineal con el logaritmo del premio: para premios no muy grandes no parece haber gran diferencia, pero cuando los premios empiezan a crecer por encima de 20,000, las ventas crecen más rápidamente que para premios menores. Este efecto se conoce como bola de nieve, y es frecuente en este tipo de loterías. Antes de adentrarnos a los modelos loess comenzamos explicando cómo se ajustan familias paramétricas de curvas a conjuntos de datos dados. El modelo de regresion lineal ajusta una recta a un conjunto de datos. Por ejemplo, consideremos la familia \\[f_{a,b}(x) = a x + b,\\] para un conjunto de datos bivariados \\(\\{ (x_1, y_1), \\ldots, (x_N, y_N)\\}\\). Buscamos encontrar \\(a\\) y \\(b\\) tales que \\(f_{a,b}\\) de un ajuste óptimo a los datos. Para esto, se minimiza la suma de errores cuadráticos \\[\\frac1N \\sum_{n = 1}^N ( y_n - a x_n - b)^2.\\] En este caso, las constantes \\(a\\) y \\(b\\) se pueden encontrar diferenciando la función de mínimos cuadrados. Nótese que podemos repetir el argumento con otras familias de funciones (por ejemplo cuadráticas). ggplot(ventas.sorteo, aes(x = premio, y = ventas.tot.1)) + geom_point() + geom_smooth(method = "lm", alpha = 0.5, se = FALSE) + scale_x_log10(breaks = c(20000, 40000, 80000)) + scale_y_log10(breaks = c(10000, 15000, 22000, 33000)) Si observamos la gráfica notamos que este modelo lineal (en los logaritmos) no resumen adecuadamente estos datos. Podríamos experimentar con otras familias (por ejemplo, una cuadrática o cúbica, potencias, exponenciales, etc.); sin embargo, en la etapa exploratoria es mejor tomar una ruta de ajuste más flexible y robusta. Regresión local nos provee de un método con estas características: Curvas loess (regresión local): Una manera de mejorar la flexibilidad de los modelos lineales es considerar rectas de manera local. Es decir, en cada \\(x\\) posible consideramos cuál es la recta que mejor ajusta a los datos, considerando solamente valores de \\(x_n\\) que están cercanos a \\(x\\). La siguiente gráfica muestra qué recta se ajusta alrededor de cada punto, y cómo queda el suavizador completo, con distintos valores de suavizamiento. El tono de los puntos indican en cada paso que ventana de datos es considerada: Escogiendo de los parámetros. El parámetro de suavizamiento se encuentra por ensayo y error. La idea general es que debemos encontrar una curva que explique patrones importantes en los datos (que ajuste los datos) pero que no muestre variaciones a escalas más chicas difíciles de explicar (que pueden ser el resultado de influencias de otras variables, variación muestral, ruido o errores de redondeo, por ejemplo). En el proceso de prueba y error iteramos el ajuste y en cada paso hacemos análisis de residuales, con el fin de seleccionar un suavizamiento adecuado. En lugar de usar ajustes locales lineales, podemos usar ajustes locales cuadráticos que nos permiten capturar formas locales cuadráticas sin tener que suavizar demasiado poco: Opcional: cálculo del suavizador La idea es producir ajustes locales de rectas o funciones lineales o cuadráticas. Consideremos especificar dos parámetros: Parámetro de suavizamiento \\(\\alpha\\): cuando \\(\\alpha\\) es más grande, la curva ajustada es más suave. Grado de los polinomios locales que ajustamos \\(\\lambda\\): generalmente se toma \\(\\lambda=1,2\\). Entonces, supongamos que los datos están dados por \\((x_1,y_1), \\ldots, (x_N, y_N)\\), y sean \\(\\alpha\\) un parámetro de suavizamiento fijo, y \\(\\lambda=1\\). Denotamos como \\(\\hat{g}(x)\\) la curva loess ajustada, y como \\(w_n(x)\\) a una función de peso (que depende de x) para la observación \\((x_n, y_n)\\). Para poder calcular \\(w_n(x)\\) debemos comenzar calculando \\(q=\\lfloor{N\\alpha}\\rfloor\\) que suponemos mayor que uno, esta \\(q\\) es el número de puntos que se utilizan en cada ajuste local. Ahora definimos la función tricubo: \\[\\begin{align} T(u)=\\begin{cases} (1-|u|^3)^3, & \\text{para $|u| < 1$}.\\\\ 0, & \\text{en otro caso}. \\end{cases} \\end{align}\\] entonces, para el punto \\(x\\) definimos el peso correspondiente al dato \\((x_n,y_n)\\), denotado por \\(w_n(x)\\) como: \\[w_n(x)=T\\bigg(\\frac{|x-x_n|}{d_q(x)}\\bigg)\\] donde \\(d_q(x)\\) es el valor de la \\(q\\)-ésima distancia más chica (la más grande entre las \\(q\\) más chicas) entre los valores \\(|x-x_j|\\), \\(j=1,\\ldots,N\\). De esta forma, las observaciones \\(x_n\\) reciben más peso cuanto más cerca estén de \\(x\\). En palabras, de \\(x_1,...,x_N\\) tomamos los \\(q\\) datos más cercanos a \\(x\\), que denotamos \\(x_{i_1}(x) \\leq x_{i_2}(x) \\leq \\cdots \\leq x_{i_q}(x)\\). Los re-escalamos a \\([0,1]\\) haciendo corresponder \\(x\\) a \\(0\\) y el punto más alejado de \\(x\\) (que es \\(x_{i_q}\\)) a 1. Aplicamos el tricubo (gráfica de abajo), para encontrar los pesos de cada punto. Los puntos que están a una distancia mayor a \\(d_q(x)\\) reciben un peso de cero, y los más cercanos un peso que depende de que tan cercanos están a \\(x\\). Nótese que \\(x\\) es el punto ancla en dónde estamos ajustando la regresión local. tricubo <- function(x) { ifelse(abs(x) < 1, (1 - abs(x) ^ 3) ^ 3, 0) } curve(tricubo, from = -1.5, to = 1.5) Finalmente, para cada valor de \\(x_k\\) que está en el conjunto de datos \\(\\{x_1,...,x_n\\}\\), ajustamos una recta de mínimos cuadrados ponderados por los pesos \\(w_n(x)\\), es decir, minimizamos (en el caso lineal): \\[\\sum_{i=1}^nw_n(x_k)(y_i-ax_n-b)^2.\\] Observaciones: Cualquier función (continua y quizás diferenciable) con la forma de flan del tricubo que se desvanece fuera de \\((-1,1),\\) es creciente en \\((-1,0)\\) y decreciente en \\((0, 1)\\) es un buen candidato para usarse en lugar del tricubo. La razón por la que escogemos precisamente esta forma algebráica no tiene que ver con el análisis exploratorio, sino con las ventajas teóricas adicionales que tiene en la inferencia. El caso \\(\\lambda=2\\) es similar. La única diferencia es en el paso de ajuste, donde usamos funciones cuadráticas, y obtendríamos entonces tres familias de parámetros \\(a(x_k), b_1(x_k), b_2(x_k),\\) para cada \\(k \\in \\{1, \\ldots, N\\}\\). Caso de estudio: nacimientos en México Podemos usar el suavizamiento loess para entender y describir el comportamiento de series de tiempo, en las cuáles intentamos entender la dependencia de una serie de mediciones indexadas por el tiempo. Típicamente es necesario utilizar distintas componentes para describir exitosamente una serie de tiempo, y para esto usamos distintos tipos de suavizamientos. Veremos que distintas componentes varían en distintas escalas de tiempo (unas muy lentas, como la tendencia, otras más rapidamente, como variación quincenal, etc.). Este caso de estudio esta basado en un análisis propuesto por A. Vehtari y A. Gelman, junto con un análisis de serie de tiempo de William S. Cleveland (1993). En nuestro caso, usaremos los datos de nacimientos registrados por día en México desde 1999. Los usaremos para contestar las preguntas: ¿cuáles son los cumpleaños más frecuentes? y ¿en qué mes del año hay más nacimientos? Podríamos utilizar una gráfica popular (ver por ejemplo esta visualización) como: Sin embargo, ¿cómo criticarías este análisis desde el punto de vista de los tres primeros principios del diseño analítico? ¿Las comparaciones son útiles? ¿Hay aspectos multivariados? ¿Qué tan bien explica o sugiere estructura, mecanismos o causalidad? Datos de natalidad para México library(lubridate) library(ggthemes) theme_set(theme_minimal(base_size = 14)) natalidad <- read_rds("./data/nacimientos/natalidad.rds") |> mutate(dia_semana = weekdays(fecha)) |> mutate(dia_año = yday(fecha)) |> mutate(año = year(fecha)) |> mutate(mes = month(fecha)) |> ungroup() |> mutate(dia_semana = recode(dia_semana, Monday = "Lunes", Tuesday = "Martes", Wednesday = "Miércoles", Thursday = "Jueves", Friday = "Viernes", Saturday = "Sábado", Sunday = "Domingo")) |> #necesario pues el LOCALE puede cambiar mutate(dia_semana = recode(dia_semana, lunes = "Lunes", martes = "Martes", miércoles = "Miércoles", jueves = "Jueves", viernes = "Viernes", sábado = "Sábado", domingo = "Domingo")) |> mutate(dia_semana = fct_relevel(dia_semana, c("Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"))) Consideremos los datos agregados del número de nacimientos (registrados) por día desde 1999 hasta 2016. Un primer intento podría ser hacer una gráfica de la serie de tiempo. Sin embargo, vemos que no es muy útil: Hay varias características que notamos. Primero, parece haber una tendencia ligeramente decreciente del número de nacimientos a lo largo de los años. Segundo, la gráfica sugiere un patrón anual. Y por último, encontramos que hay dispersión producida por los días de la semana. Sólo estas características hacen que la comparación entre días sea difícil de realizar. Supongamos que comparamos el número de nacimientos de dos miércoles dados. Esa comparación será diferente dependiendo: del año donde ocurrieron, el mes donde ocurrieron, si semana santa ocurrió en algunos de los miércoles, y así sucesivamente. Como en nuestros ejemplos anteriores, la idea del siguiente análisis es aislar las componentes que observamos en la serie de tiempo: extraemos componentes ajustadas, y luego examinamos los residuales. En este caso particular, asumiremos una descomposición aditiva de la serie de tiempo (William S. Cleveland 1993). En el estudio de series de tiempo una estructura común es considerar el efecto de diversos factores como tendencia, estacionalidad, ciclicidad e irregularidades de manera aditiva. Esto es, consideramos la descomposición \\[\\begin{align} y(t) = f_{t}(t) + f_{e}(t) + f_{c}(t) + \\varepsilon. \\end{align}\\] Una estrategia de ajuste, como veremos más adelante, es proceder de manera modular. Es decir, se ajustan los componentes de manera secuencial considerando los residuales de los anteriores. Tendencia Comenzamos por extraer la tendencia, haciendo promedios loess (William S. Cleveland 1979) con vecindades relativamente grandes. Quizá preferiríamos suavizar menos para capturar más variación lenta, pero si hacemos esto en este punto empezamos a absorber parte de la componente anual: mod_1 <- loess(n ~ as.numeric(fecha), data = natalidad, span = 0.2, degree = 1) datos_dia <- natalidad |> mutate(ajuste_1 = fitted(mod_1)) |> mutate(res_1 = n - ajuste_1) Notemos que a principios de 2000 el suavizador está en niveles de alrededor de 7000 nacimientos diarios, hacia 2015 ese número es más cercano a unos 6000. Componente anual Al obtener la tendencia podemos aislar el efecto a largo plazo y proceder a realizar mejores comparaciones (por ejemplo, comparar un día de 2000 y de 2015 tendria más sentido). Ahora, ajustamos los residuales del suavizado anterior, pero con menos suavizamiento. Así evitamos capturar tendencia: mod_anual <- loess(res_1 ~ as.numeric(fecha), data = datos_dia, degree = 2, span = 0.005) datos_dia <- datos_dia |> mutate(ajuste_2 = fitted(mod_anual)) |> mutate(res_2 = res_1 - ajuste_2) Día de la semana Hasta ahora, hemos aislado los efectos por plazos largos de tiempo (tendencia) y hemos incorporado las variaciones estacionales (componente anual) de nuestra serie de tiempo. Ahora, veremos cómo capturar el efecto por día de la semana. En este caso, podemos hacer suavizamiento loess para cada serie de manera independiente datos_dia <- datos_dia |> group_by(dia_semana) |> nest() |> mutate(ajuste_mod = map(data, ~ loess(res_2 ~ as.numeric(fecha), data = .x, span = 0.1, degree = 1))) |> mutate(ajuste_3 = map(ajuste_mod, fitted)) |> select(-ajuste_mod) |> unnest(cols = c(data, ajuste_3)) |> mutate(res_3 = res_2 - ajuste_3) |> ungroup() Residuales Por último, examinamos los residuales finales quitando los efectos ajustados: ## `geom_smooth()` using formula = 'y ~ x' Observación: nótese que la distribución de estos residuales presenta irregularidades interesantes. La distribución es de colas largas, y no se debe a unos cuantos datos atípicos. Esto generalmente es indicación que hay factores importantes que hay que examinar mas a detalle en los residuales: Reestimación Cuando hacemos este proceso secuencial de llevar el ajuste a los residual, a veces conviene iterarlo. La razón es que en una segunda o tercera pasada podemos hacer mejores estimaciones de cada componente, y es posible suavizar menos sin capturar componentes de más alta frecuencia. Así que podemos regresar a la serie original para hacer mejores estimaciones, más suavizadas: # Quitamos componente anual y efecto de día de la semana datos_dia <- datos_dia |> mutate(n_1 = n - ajuste_2 - ajuste_3) # Reajustamos mod_1 <- loess(n_1 ~ as.numeric(fecha), data = datos_dia, span = 0.02, degree = 2, family = "symmetric") Y ahora repetimos con la componente de día de la semana: Análisis de componentes Ahora comparamos las componentes estimadas y los residuales en una misma gráfica. Por definición, la suma de todas estas componentes da los datos originales. Este último paso nos permite diversas comparaciones que explican la variación que vimos en los datos. Una gran parte de los residuales está entre \\(\\pm 250\\) nacimientos por día. Sin embargo, vemos que las colas tienen una dispersión mucho mayor: quantile(datos_dia$res_6, c(00, .01,0.05, 0.10, 0.90, 0.95, 0.99, 1)) |> round() ## 0% 1% 5% 10% 90% 95% 99% 100% ## -2238 -1134 -315 -202 188 268 516 2521 ¿A qué se deben estas colas tan largas? Viernes 13? Podemos empezar con una curosidad. Los días Viernes o Martes 13, ¿nacen menos niños? Nótese que fue útil agregar el indicador de Semana santa por el Viernes 13 de Semana Santa que se ve como un atípico en el panel de los viernes 13. Residuales: antes y después de 2006 Veamos primero una agregación sobre los años de los residuales. Lo primero es observar un cambio que sucedió repentinamente en 2006: La razón es un cambio en la ley acerca de cuándo pueden entrar los niños a la primaria. Antes era por edad y había poco margen. Ese exceso de nacimientos son reportes falsos para que los niños no tuvieran que esperar un año completo por haber nacido unos cuantos días después de la fecha límite. Otras características que debemos investigar: Efectos de Año Nuevo, Navidad, Septiembre 16 y otros días feriados como Febrero 14. Semana santa: como la fecha cambia, vemos que los residuales negativos tienden a ocurrir dispersos alrededor del día 100 del año. Otros días especiales: más de residuales Ahora promediamos residuales (es posible agregar barras para indicar dispersión a lo largo de los años) para cada día del año. Podemos identificar ahora los residuales más grandes: se deben, por ejemplo, a días feriados, con consecuencias adicionales que tienen en días ajuntos (excesos de nacimientos): Semana santa Para Semana Santa tenemos que hacer unos cálculos. Si alineamos los datos por días antes de Domingo de Pascua, obtenemos un patrón de caída fuerte de nacimientos el Viernes de Semana Santa, y la característica forma de “valle con hombros” en días anteriores y posteriores estos Viernes. ¿Por qué ocurre este patrón? Nótese un defecto de nuestro modelo: el patrón de “hombros” alrededor del Viernes Santo no es suficientemente fuerte para equilibrar los nacimientos faltantes. ¿Cómo podríamos mejorar nuestra descomposición? Referencias "],["apéndice-principios-de-visualizacion.html", "Apéndice: Principios de visualizacion Introducción Visualización popular de datos Teoría de visualización de datos Ejemplo: gráfica de Minard", " Apéndice: Principios de visualizacion “The simple graph has brought more information to the data analyst’s mind than any other device.” — John Tukey El cuarteto de Anscombe En 1971 un estadístico llamado Frank Anscombe (fundador del departamento de Estadística de la Universidad de Yale) publicó cuatro conjuntos de dato. Cada uno consiste de 11 observaciones. La peculariedad de estos conjuntos es que tienen las mismas propiedades estadísticas. Sin embargo, cuando analizamos los datos de manera gráfica en un histograma encontramos rápidamente que los conjuntos de datos son muy distintos. Media de \\(x\\): 9 Varianza muestral de \\(x\\): 11 Media de \\(y\\): 7.50 Varianza muestral de \\(y\\): 4.12 Correlación entre \\(x\\) y \\(y\\): 0.816 Línea de regresión lineal: \\(y = 3.00 + 0.500x\\) En la gráfica del primer conjunto de datos, se ve clara una relación lineal simple con un modelo que cumple los supuestos de normalidad. La segunda gráfica (arriba a la derecha) muestra unos datos que tienen una asociación pero definitivamente no es lineal. En la tercera gráfica (abajo a la izquierda) están puntos alineados perfectamente en una línea recta, excepto por uno de ellos. En la última gráfica podemos ver un ejemplo en el cual basta tener una observación atípica para que se produzca un coeficiente de correlación alto aún cuando en realidad no existe una asociación lineal entre las dos variables. El cuarteto de Ascombe inspiró una técnica reciente para crear datos que comparten las mismas propiedades estadísticas al igual que en el cuarteto, pero que producen gráficas muy distintas (Matejka, Fitzmaurice). Introducción La visualización de datos no trata de hacer gráficas “bonitas” o “divertidas”, ni de simplificar lo complejo o ayudar a una persona “que no entiende mucho” a entender ideas complejas. Más bien, trata de aprovechar nuestra gran capacidad de procesamiento visual para exhibir de manera clara aspectos importantes de los datos. El siguiente ejemplo de (Tufte 2006), ilustra claramente la diferencia entre estos dos enfoques. A la izquierda están gráficas (más o menos típicas de Powerpoint) basadas en la filosofía de simplificar, de intentar no “ahogar” al lector con datos. El resultado es una colección incoherente, de bajo contenido, que no tiene mucho qué decir y que es, “indeferente al contenido y la evidencia”. A la derecha está una variación del rediseño de Tufte en forma de tabla, que en este caso particular es una manera eficiente de mostrar claramente los patrones que hay en este conjunto simple de datos. ¿Qué principios son los que soportan la efectividad de esta tabla sobre la gráfica de la derecha? Veremos que hay dos conjuntos de principios importantes: unos relacionados con el diseño y otros con la naturaleza del análisis de datos, independientemente del método de visualización. Visualización popular de datos Publicaciones populares (periódicos, revistas, sitios internet) muchas veces incluyen visualización de datos como parte de sus artículos o reportajes. En general siguen el mismo patrón que en la visión tradicionalista de la estadística: sirven más para divertir que para explicar, tienden a explicar ideas simples y conjuntos chicos de datos, y se consideran como una “ayuda” para los “lectores menos sofisticados”. Casi siempre se trata de gráficas triviales (muchas veces con errores graves) que no aportan mucho a artículos que tienen un nivel de complejidad mucho mayor (es la filosofía: lo escrito para el adulto, lo graficado para el niño). Teoría de visualización de datos Existe teoría fundamentada acerca de la visualización. Después del trabajo pionero de Tukey, los principios e indicadores de Tufte se basan en un estudio de la historia de la graficación y ejercicios de muestreo de la práctica gráfica a lo largo de varias disciplinas (¿cuáles son las mejores gráficas? ¿por qué?) El trabajo de Cleveland es orientado a la práctica del análisis de datos (¿cuáles gráficas nos han ayudado a mostrar claramente los resultados del análisis?), por una parte, y a algunos estudios de percepción visual. En resumen, hablaremos de las siguientes guías: Principios generales del diseño analítico Aplicables a una presentación o análisis completos, y como guía para construir nuevas visualizaciones (Tufte 2006). Principio 1. Muestra comparaciones, contrastes, diferencias. Principio 2. Muestra causalidad, mecanismo, explicación, estructura sistemática. Principio 3. Muestra datos multivariados, es decir, más de una o dos variables. Principio 4. Integra palabras, números, imágenes y diagramas. Principio 5. Describe la totalidad de la evidencia. Muestra fuentes usadas y problemas relevantes. Principio 6. Las presentaciones analíticas, a fin de cuentas, se sostienen o caen dependiendo de la calidad, relevancia e integridad de su contenido. Técnicas de visualización Esta categoría incluye técnicas específicas que dependen de la forma de nuestros datos y el tipo de pregunta que queremos investigar (Tukey (1977), William S. Cleveland (1993), W. S. Cleveland (1994), Tufte (2006)). Tipos de gráficas: cuantiles, histogramas, caja y brazos, gráficas de dispersión, puntos/barras/ líneas, series de tiempo. Técnicas para mejorar gráficas: Transformación de datos, transparencia, vibración, banking 45, suavizamiento y bandas de confianza. Pequeños múltiplos Indicadores de calidad gráfica Aplicables a cualquier gráfica en particular. Estas son guías concretas y relativamente objetivas para evaluar la calidad de una gráfica (Tufte 1986). Integridad Gráfica. El factor de engaño, es decir, la distorsión gráfica de las cantidades representadas, debe ser mínimo. Chartjunk. Minimizar el uso de decoración gráfica que interfiera con la interpretación de los datos: 3D, rejillas, rellenos con patrones. Tinta de datos. Maximizar la proporción de tinta de datos vs. tinta total de la gráfica. For non-data- ink, less is more. For data-ink, less is a bore. Densidad de datos. Las mejores gráficas tienen mayor densidad de datos, que es la razón entre el tamaño del conjunto de datos y el área de la gráfica. Las gráficas se pueden encoger mucho. Percepción visual. Algunas tareas son más fáciles para el ojo humano que otras (W. S. Cleveland 1994). Factor de engaño y Chartjunk El factor de engaño es el cociente entre el efecto mostrado en una gráfica y el efecto correspondiente en los datos. Idealmente, el factor de engaño debe ser 1 (ninguna distorsión). El chartjunk son aquellos elementos gráficos que no corresponden a variación de datos, o que entorpecen la interpretación de una gráfica. Estos son los indicadores de calidad más fáciles de entender y aplicar, y afortunadamente cada vez son menos comunes. Un diseño popular que califica como chartjunk y además introduce factores de engaño es el pie de 3D. En la gráfica de la derecha, podemos ver como la rebanada C se ve más grande que la rebanada A, aunque claramente ese no es el caso (factor de engaño). La razón es la variación en la perspectiva que no corresponde a variación en los datos (chartjunk). Crítica gráfica: Gráfica de pie Todavía elementos que pueden mejorar la comprensión de nuestra gráfica de pie: se trata de la decodificiación que hay que hacer categoría - color - cuantificación. Podemos agregar las etiquetas como se muestra en la serie de la derecha, pero entonces: ¿por qué no mostrar simplemente la tabla de datos? ¿qué agrega el pie a la interpretación? La deficiencias en el pie se pueden ver claramente al intentar graficar más categorías (13) . En el primer pie no podemos distinguir realmente cuáles son las categorías grandes y cuáles las chicas, y es muy difícil tener una imagen mental clara de estos datos. Agregar los porcentajes ayuda, pero entonces, otra vez, preguntamos cuál es el propósito del pie. La tabla de la izquierda hace todo el trabajo (una vez que ordenamos las categrías de la más grande a la más chica). Es posible hacer una gráfica de barras como la de abajo a la izquierda. Hay otros tipos de chartjunk comunes: uno es la textura de barras, por ejemplo. El efecto es la producción de un efecto moiré que es desagradable y quita la atención de los datos, como en la gráfica de barras de abajo. Otro común son las rejillas, como mostramos en las gráficas de la izquierda. Nótese como en estos casos hay efectos ópticos no planeados que degradan la percepción de los patrones en los datos. Pequeños múltiplos y densidad gráfica La densidad de una gráfica es el tamaño del conjunto de datos que se grafica comparado con el área total de la gráfica. En el siguiente ejemplo, graficamos en logaritmo-10 de millones de cabezas de ganado en Francia (cerdos, res, ovejas y caballos). La gráfica de la izquierda es pobre en densidad pues sólo representa 4 datos. La manera más fácil de mejorar la densidad es hacer más chica la gráfica: La razón de este encogimiento es una que tiene qué ver con las oportunidades perdidas de una gráfica grande. Si repetimos este mismo patrón (misma escala, mismos tipos de ganado) para distintos países obtenemos la siguiente gráfica: Esta es una gráfica de puntos. Es útil como sustituto de una gráfica de barras, y es superior en el sentido de que una mayor proporción de la tinta que se usa es tinta de datos. Otra vez, mayor proporción de tinta de datos representa más oportunidades que se pueden capitalizar. Más pequeños múltiplos Los pequeños múltiplos presentan oportunidades para mostrar más acerca de nuestro problema de interés. Consideramos por ejemplo la relación de radiación solar y niveles de ozono: En el ejemplo anterior incluyendo una variable adicional (velocidad del viento) podemos entender más acerca de la relación de radiación solar y niveles de ozono: Tinta de datos Maximizar la proporción de tinta de datos en nuestras gráficas tiene beneficios inmediatos. La regla es: si hay tinta que no representa variación en los datos, o la eliminación de esa tinta no representa pérdidas de significado, esa tinta debe ser eliminada. El ejemplo más claro es el de las rejillas en gráficas y tablas: ¿Por qué usar grises en lugar de negros? La respuesta tiene qué ver con el principio de tinta de datos: si marcamos las diferencias sutil pero claramente, tenemos más oportunidades abiertas para hacer énfasis en lo que nos interesa: a una gráfica o tabla saturada no se le puede hacer más - es difícil agregar elementos adicionales que ayuden a la comprensión. Si comenzamos marcando con sutileza, entonces se puede hacer más. Los mapas geográficos son un buen ejemplo de este principio. El espacio en blanco es suficientemente bueno para indicar las fronteras en una tabla, y facilita la lectura: Para un ejemplo del proceso de rediseño de una tabla, ver aquí. Finalmente, podemos ver un ejemplo que intenta incorporar los elementos del diseño analítico, incluyendo pequeños múltiplos: Decoración Percepción de escala Entre la percepción visual y la interpretación de una gráfica están implícitas tareas visuales específicas que las personas debemos realizar para ver correctamente la gráfica. En la década de los ochenta, William S. Cleveland y Robert McGill realizaron algunos experimentos identificando y clasificando estas tareas para diferentes tipos de gráficos (William S. Cleveland and McGill 1984). En estos, se le pregunta a la persona que compare dos valores dentro de una gráfica, por ejemplo, en dos barras en una gráfica de barras, o dos rebanadas de una gráfica de pie. Los resultados de Cleveland y McGill fueron replicados por Heer y Bostock en 2010 y los resultados se muestran en las gráficas de la derecha: Ejemplo: gráfica de Minard Concluimos esta sección con una gráfica que, aunque poco común, ejemplifica los principios de una buena gráfica, y es reconocida como una de las mejores visualizaciones de la historia. Una gráfica excelente, presenta datos interesantes de forma bien diseñada: es una cuestión de fondo, de diseño, y estadística… [Se] compone de ideas complejas comunicadas con claridad, precisión y eficiencia. … [Es] lo que da al espectador la mayor cantidad de ideas, en el menor tiempo, con la menor cantidad de tinta, y en el espacio más pequeño. … Es casi siempre multivariado. … Una excelente gráfica debe decir la verdad acerca de los datos. (Tufte, 1983) La famosa visualización de Charles Joseph Minard de la marcha de Napoleón sobre Moscú, ilustra los principios de una buena gráfica. Tufte señala que esta imagen “bien podría ser el mejor gráfico estadístico jamás dibujado”, y sostiene que “cuenta una historia rica y coherente con sus datos multivariados, mucho más esclarecedora que un solo número que rebota en el tiempo”. Se representan seis variables: el tamaño del ejército, su ubicación en una superficie bidimensional, la dirección del movimiento del ejército y la temperatura en varias fechas durante la retirada de Moscú”. Hoy en día Minard es reconocido como uno de los principales contribuyentes a la teoría de análisis de datos y creación de infografías con un fundamento estadístico. Se grafican 6 variables: el número de tropas de Napoleón, la distancia, la temperatura, la latitud y la longitud, la dirección en que viajaban las tropas y la localización relativa a fechas específicas. La gráfica de Minard, como la describe E.J. Marey, parece “desafiar la pluma del historiador con su brutal elocuencia”, la combinación de datos del mapa, y la serie de tiempo, dibujados en 1869, “retratan una secuencia de pérdidas devastadoras que sufrieron las tropas de Napoleón en 1812”. Comienza en la izquierda, en la frontera de Polonia y Rusia, cerca del río Niemen. La línea gruesa dorada muestra el tamaño de la Gran Armada (422,000) en el momento en que invadía Rusia en junio de 1812. El ancho de esta banda indica el tamaño de la armada en cada punto del mapa. En septiembre, la armada llegó a Moscú, que ya había sido saqueada y dejada desértica, con sólo 100,000 hombres. El camino del retiro de Napoleón desde Moscú está representado por la línea oscura (gris) que está en la parte inferior, que está relacionada a su vez con la temperatura y las fechas en el diagrama de abajo. Fue un invierno muy frío, y muchos se congelaron en su salida de Rusia. Como se muestra en el mapa, cruzar el río Berezina fue un desastre, y el ejército de Napoleón logró regresar a Polonia con tan sólo 10,000 hombres. También se muestran los movimientos de las tropas auxiliaries, que buscaban proteger por atrás y por la delantera mientras la armada avanzaba hacia Moscú. La gráfica de Minard cuenta una historia rica y cohesiva, coherente con datos multivariados y con los hechos históricos, y que puede ser más ilustrativa que tan sólo representar un número rebotando a lo largo del tiempo. Referencias "],["referencias.html", "Referencias", " Referencias "],["404.html", "Page not found", " Page not found The page you requested cannot be found (perhaps it was moved or renamed). You may want to try searching to find the page's new location, or use the table of contents to find the page you are looking for. "]]