Unidad 3: Descripción y Visualización de Datos
2025-09-08
character, numeric, logical) y el concepto de coerción.En las clases pasadas, establecimos el camino teórico de la medición:
Conceptualización → Operacionalización → Variables e Indicadores
Hoy, damos el salto a la práctica: ¿Cómo se organizan esas mediciones en el mundo real de los datos?
Esta unidad se centrará en los primeros y más cruciales pasos del proceso de análisis:
En R, cada columna de nuestra base de datos tendrá un “tipo” de dato específico. Comprender estos tipos es crucial para evitar errores. Los más comunes son:
| Tipo en R | Descripción | Nivel de Medición Típico |
|---|---|---|
character |
Texto o cadenas de caracteres. | Nominal |
numeric |
Números, ya sean enteros o con decimales. | Intervalo / Razón |
logical |
Valores de Verdadero (TRUE) o Falso (FALSE). |
Nominal (Dicotómica) |
factor |
Variable categórica con niveles predefinidos. | Nominal / Ordinal |
Podemos inspeccionar el tipo de una variable con la función class().
Una regla fundamental en R es que todos los elementos de un vector deben ser del mismo tipo.
Si intentamos combinar diferentes tipos, R forzará o “coercerá” los elementos al tipo más flexible para no perder información. La jerarquía de flexibilidad es:
logical < numeric < character.
¡Cuidado! La coerción implícita puede causar errores silenciosos. Si una columna de ingresos tiene un valor de texto (“No responde”), toda la columna puede ser leída como character, impidiendo cálculos matemáticos.
Para evitar problemas, la mejor práctica es realizar una coerción explícita: nosotros le decimos a R a qué tipo de dato debe convertir una variable.
Usamos la familia de funciones as.*():
- as.numeric(): Convierte a número.
- as.character(): Convierte a texto.
- as.factor(): Convierte a factor.
# Un vector de texto que en realidad son números
edad_texto <- c("25", "42", "37")
class(edad_texto)
# [1] "character"
# No podemos calcular el promedio
mean(edad_texto)
# Error: 'trim' must be numeric
# Lo solucionamos con coerción explícita
edad_numerica <- as.numeric(edad_texto)
class(edad_numerica)
# [1] "numeric"
mean(edad_numerica)
# [1] 34.66667Una vez que entendemos los tipos de datos (numeric, character, etc.), necesitamos saber cómo se organizan. En R, los datos se guardan en diferentes “contenedores” o estructuras.
Cada estructura tiene sus propias reglas y usos. Pasaremos de la más simple a la más compleja y útil para nosotros.
El vector es la estructura de datos más fundamental en R. Piénsalo como una sola columna o “variable” de nuestra base de datos.
c() (concatenar o combinar).Ejemplos de vectores:
La mayoría de las operaciones en R están “vectorizadas”, es decir, se aplican a cada elemento del vector a la vez.
Una lista es un contenedor que puede guardar cualquier tipo de objeto, incluso de diferentes tipos y tamaños.
list().Las listas son extremadamente poderosas para organizar resultados complejos, aunque no las usaremos tanto para guardar datos primarios.
Ambos son estructuras de dos dimensiones (filas y columnas), como una hoja de cálculo, pero con una diferencia crucial.
Matriz (matrix)
- Regla: Es homogénea. Todas las celdas deben contener el mismo tipo de dato (generalmente numérico).
- Uso: Principalmente para operaciones matemáticas y álgebra lineal. Menos común para datos de encuesta.
Data Frame (data.frame)
- Regla: Es heterogéneo por columnas. Cada columna (vector) puede tener un tipo de dato diferente, pero todas deben tener la misma longitud.
- Uso: Es la estructura estándar para almacenar y analizar datos en sociología. Es nuestra tabla de datos.
Un data.frame es, conceptualmente, una lista de vectores de igual longitud.
Un data.frame organiza nuestros datos de la manera “ordenada” (tidy) que discutimos: cada fila es una observación y cada columna es una variable.
# Creamos vectores individuales
id_sujeto <- c(1, 2, 3)
edad_sujeto <- c(28, 45, 33)
satisfaccion_vida <- c("Alta", "Media", "Alta")
# Los combinamos en un data.frame
mi_encuesta <- data.frame(
id = id_sujeto,
edad = edad_sujeto,
satisfaccion = satisfaccion_vida
)
# Así se ve nuestra base de datos
mi_encuesta
# id edad satisfaccion
# 1 1 28 Alta
# 2 2 45 Media
# 3 3 33 AltaAl importar datos de un archivo (como haremos en el práctico), R los cargará directamente como un data.frame (o un tibble, su versión moderna del tidyverse).
Independientemente de la encuesta o la fuente, los datos cuantitativos se organizan en una estructura tabular con una lógica universal:
| folio | region | sexo | edad | esc | ingreso_hog |
|---|---|---|---|---|---|
| 101 | 13 | Mujer | 45 | 16 | 1,500,000 |
| 102 | 5 | Hombre | 32 | 12 | 800,000 |
| 102 | 5 | Mujer | 30 | 14 | 800,000 |
| 103 | 8 | Hombre | 67 | 8 | 450,000 |
Para que el análisis de datos sea eficiente y libre de errores, buscamos un formato estándar conocido como “datos ordenados”. Este formato sigue tres reglas simples:
Afortunadamente, la mayoría de las encuestas (como CASEN o EBS) ya vienen en este formato. Nuestro trabajo es mantener este orden.
Antes de analizar, es crucial establecer un flujo de trabajo reproducible.
La Consola
- Es la ventana donde R ejecuta los comandos.
- Es interactiva y útil para pruebas rápidas y experimentos.
- No guarda un registro de tu trabajo. Lo que escribes en la consola se pierde cuando cierras RStudio.
El Script (.R) o R Markdown (.qmd)
- Son archivos de texto plano donde escribimos y guardamos nuestro código.
- Crean un registro permanente y reproducible de cada paso de nuestro análisis.
- Siempre debemos trabajar en un script o en un R Markdown.
Sugerencia: Usar Proyectos de RStudio (.Rproj) para mantener todos los archivos de una investigación (datos, scripts, informes) organizados en una sola carpeta.
La regla de oro de la reproducibilidad es: todo debe estar en el script. Una vez que nos comprometemos con eso, el siguiente paso es asegurarnos de que nuestro código sea claro, robusto y portable.
Para que TÚ (y otros) entiendan tu código:
#):
mean() ya dice que calcula una media; el comentario debe explicar por qué necesitas esa media.snake_case (minúsculas y guiones bajos).x <- mean(v1)edad_promedio <- mean(edad_encuestados)%>%. RStudio lo hace en gran parte de forma automática.Para que tu código SIEMPRE funcione:
library(tidyverse)). Así, cualquiera que ejecute tu script sabrá qué necesita instalar."C:/Users/Gabriel/Desktop/datos.csv"). Este código fallará en cualquier otro computador."datos/casen2022.csv"), que funcionarán en cualquier máquina.Cuando recibimos una nueva base de datos, nuestro primer paso es siempre realizar una exploración inicial para entender su estructura y contenido. Estas funciones son nuestro “kit de diagnóstico” básico:
| Función | ¿Qué hace? |
|---|---|
dim(datos) |
Muestra las dimensiones (filas, columnas). |
names(datos) |
Lista los nombres de todas las variables. |
head(datos) |
Muestra las primeras 6 filas. |
tail(datos) |
Muestra las últimas 6 filas. |
str(datos) |
Muestra la estructura detallada del objeto. |
str()La función str() (de structure) es quizás la más informativa al principio. Nos da un resumen compacto y detallado de cualquier objeto de R, especialmente de las bases de datos (data.frame).
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 ...
$ Species : Factor w/ 3 levels "setosa",..: 1 1 1 1 1 ...
'data.frame': El tipo de objeto que estamos inspeccionando.150 obs. of 5 variables: Las dimensiones del data.frame. Tiene 150 observaciones (filas) y 5 variables (columnas).$ Variable.Name: El signo $ precede al nombre de cada una de las 5 variables.: tipo de dato Después del nombre de la variable, nos indica su tipo (num para numérico, Factor para categórica, chr para texto, etc.).... valores ... Finalmente, nos muestra los primeros valores de esa variable para que tengamos una idea de su contenido. Para los factores, también nos indica sus “niveles” o categorías.summary() y table()Una vez que entendemos la estructura, pasamos a revisar la calidad del contenido.
summary(datos):
NA's) hay en cada variable.table(datos$variable):
Resumen de la sesión de hoy:
dim, str, summary, etc.).En el práctico de hoy:
Adelanto de la próxima clase:
dplyr para seleccionar, filtrar y transformar nuestros datos.