Introducción a R para Ciencias Sociales

Sesión 01: Introducción a la programación

Javier Emmanuel Anguiano Pita

CONAHCYT-Universidad de Guadalajara

6 de enero de 2025

¡Bienvenidos al curso!

Introducción

Instructor:

  • Economista y Doctor en Estudios Económicos por la UDG (2022).

  • Líneas de investigación:

    • Economía Internacional.

    • Macroeconomía.

    • Desarrollo económico.

  • Usuario de R desde hace + 7 años.

Presentación de los asistentes

  • ¿Cuál es tu nombre?
  • Antecedentes académicos (Lic/MS)
  • ¿Qué tema están/pretenden investigar?
  • ¿Tienes experiencia con algún software?

Sobre el curso

Objetivo principal Aprender a programar en R para desarrollar nuestras propias investigaciones.

Estructura del curso 5 sesiones (~3.5 h cada una) diseñadas para introducirnos a los principales pasos en el flujo de trabajo para el análisis de datos (investigación empírica):

  1. Introducción a la interfaz y el lenguaje de R.

  2. Administración y manipulación de datos.

  3. Visualización de datos.

  4. Investigación reproducible.

🚨Las políticas de la clase están disponibles en el sitio en internet del curso.

Agenda del día

  1. Introducción a R y RStudio
  2. Anatomía de los objetos en R
  3. Tipos de datos en R
  4. Lenguaje R base.

R

¿Qué es R?

R es un lenguaje de programación que se utiliza principalmente para el análisis estadístico y la visualización de datos.

Breve historia del lenguaje R

  • R se basa en el lenguaje de programación denominado S desarrollado por John Chambers en 1976.
  • R fue desarrollado por Ross Ihaka y Robert Gentleman (Universidad de Auckland). Fue documentado por primera vez en un artículo en 1996.
  • El mismo año se libera el código bajo una licencia GNU GPL.
  • Desde 1997 se comenzó a gestar una comunidad muy activa que desarrolla librerías y aplicaciones en R.

¿Por qué usar R?

  1. R es un lenguaje muy flexible y poderoso- adaptable a casi cualquier tarea de investigación (análisis de datos, econometría, análisis espacial, machine learning, web scraping, etc.).
  2. R tiene una comunidad en línea que colabora para resolver cualquier problema.
  3. R permite crear investigación reproducible, mostrando el flujo completo del processamiento de datos. 😉
  4. R es gratuito y de código abierto 💰💵💰.

Diferencias entre R y Python

Características R Python
Alcance Análisis y modelación estadística Escalable. Desarrollo de aplicaciones y análisis de datos
Usado por Analistas, investigadores, científicos de datos Desarrolladores, programadores e ingenieros de datos
Útil para Personas sin experiencia previa en programación Novatos y profesionales de IT
Repositorio central CRAN PyPI
Herramientas de visualización ggplot2, plotly, ggiraph Matplotlib, seaborn, ggplot

RStudio

  • Es un entorno de desarrollo integrado (IDE, en inglés) desarrollado por Posit que nos permite tener una interfaz amigable para R 😁
  • R = 🧠
  • RStudio = 🖱️

Interfaz de RStudio

Editor de código fuente (I)

¡Estaremos la mayor parte del tiempo aquí! En este panel escribimos y guardamos nuestro código. (File > New File > R Script) 📌 Recordatorio: Siempre guarda tu código.

  • Usamos # para hacer comentarios en el código. Todo lo que esté después de este símbolo es ignorado por R hasta la línea siguiente.
  • Para mejorar la claridad de nuestro script separamos los comandos con saltos de línea.
  • Los espacios en una misma línea no implican cambiar de comando.

Editor de código fuente (II)

  • Los botones y envían el código a la consola para ejecutarse:
  • nos permite seleccionar partes del código y ejecutarlo. (Ctr + Enter)
  • ejecuta el código completo.

Ejemplo:

1 + 1 # ¿Es igual a dos?
1 +   # ¿También es igual a dos?
  1   # R sigue esperando instrucciones
1
+ 1   # Es igual a uno

Consola

El medio de comunicación entre nuestro código y el cerebro de R 🤖

  • Escribimos las instrucciones después del símbolo >. Esto significa que R está listo para nuestras instrucciones.
  • Podemos escribir instrucciones directamente en la consola e incluso hacer cálculos rápidos.
  • Los resultados se guardan temporalmente en la memoria de R.

Escribe todo tu código como script para poder replicarlo

Entorno de trabajo

Aquí podemos hacer un seguimiento de lo que hacemos 🖇️

  • El análisis de datos requiere que manipulemos distintos tipos de objetos. El registro de lo que hacemos se guarda temporalmente en este panel.

  • R es un lenguaje orientado a objetos. Esto significa que nosotros manipulamos y modificamos las características de dichos objetos.

  • Para guardar un objeto podemos usar dos tipos de operadores de asignación:<- y =.

Ejemplo: Entorno de trabajo

5 + 1 # No es un objeto
x <- 5 # Asignamos un valor al objeto X
x
x = 5 
5 -> x  # Asignación direccional

x + 1  # No es un objeto
y <- 1
x + y 

mensaje <- "Texo"
mensaje 

str(mensaje)
str(x)

Files / Plots / Help / Packages/ etc.

Este panel tiene muchas cosas útiles 🏆

  • La pestaña Files nos indica el directorio de trabajo de R.
  • La pestaña Plots muestra los gráficos que generamos en nuestro script.
  • La pestaña Help es útil para conocer la documentación de las librerías y funciones que podemos usar en R.
  • Podemos usar el comando ? antes del nombre de cualquier función o librería para obtener ayuda. P.ej. ?getwd()
  • La pestaña Packages nos muestra todas las librerías que tenemos instaladas y podemos invocar/desactivar en la sesión activa de R.

Sintáxis básica en R

Objetos y funciones

  • En R usamos dos tipos de elementos básicos:
  1. Objetos: Permiten almacenar información para realizar procedimientos.
  2. Funciones: Son los procedimientos que aplicamos a los objetos.

Ejemplo: Objetos y funciones

ventana <- "Esto es una ventana"
puerta <- "Esto es una puerta"
cien <- 100
doscientos <- 2000

View(cien)

Programar en R es definir objetos y aplicar funciones a dichos objetos ad infinitum.

# Esto es programar en R
calificaciones <- c(7, 8 , 9, 6, 10, 9)
mean(calificaciones)

Funciones básicas

Al instalar R, se incluyen automáticamente un conjunto de paquetes “básicos” que son escenciales para su funcionamiento:

  • base: es el núcleo de R y contiene las funciones fundamentales para realizar cálculos y manipular datos.
  • stats: contiene funciones básicas para realizar análisis estadísticos.
  • graphics: herramientas para crear gráficos y visualizaciones de datos.
  • utils: incluye funciones para la manipulación de datos y gestión de archivos.
  • datasets: conjunto de datos de ejemplo para aprender R.

Para ver todas las funciones del paquete base podemos escribir el siguiente comando en la consola:

help(base)
?base

Operadores binarios

En R se pueden hacer diversas operaciones usando operadores binarios que sirven también como funciones.

  • + operador de suma.
  • - operador de resta.
  • / operador para dividir.
  • ^ operador de potencia.
  • %/% obtener el cociente de una división (entero).
  • %% obtener residuo de una división.
6 + 4
a <- 5
b <- 2 
a + b 
a - b
a * b 
a / b 
a ^ b

Operadores lógicos

En R se puede verificar si un objeto cumple una condición dada usando las siguientes pruebas lógicas:

  • < un número es menor que otro.
  • > un número es mayor que otro.
  • == un número es igual a otro.
  • <= un numero es menor o igual que otro.
  • >= un numero es mayor o igual que otro.
5 > 2
5 == 5
5 == 4

x <- 5
y <- 20/4
x == y  # ¿Será X = a Y?

Importando e inspeccionando datos reales

Para esta sección deben descargar los datos del siguiente enlace 💻

  • La base de datos contiene información sobre las 250 películas mejor calificadas en IMDB 🎥

  • Abre el archivo en tu computadora e inspeccionalo. ¿Qué información contiene? Las columnas son variables y las filas observaciones.

¿Cómo podemos importar este archivo a R?

  • Podemos importarlo usando las funciones read, que toman como insumo la ruta en donde está guardado el archivo en nuestra computadora y nos entregan el archivo como resultado en la memoria de R.

⚠️ Los usuarios de Windows debemos usar diagonales normales / p.ej. "/Documents/file.csv” en lugar de \

Ejemplo: Importar datos reales

imdb <- read.csv("C:/Users/jeptt/Documents/IMDB.csv")

# Exploramos los datos
head(imdb, 4) # Muestras las primeras 4 filas
tail(imdb, 4) # Muestra las últimas 4 filas
View(imdb)    # Muestra la base de datos completa

Uso de funciones en R

  • Lean la documentación antes de usar una función ?csv.read()
    • Descripción.
    • Uso.
    • Argumentos: valores por defecto que requiere la función.
    • Ejemplos
read.csv(file, header = TRUE, sep = ",", quote = "\"",
dec = ".", fill = TRUE, comment.char = "", ...)
  • R está optimizado para que no tengamos que poner todos los argumentos de las funciones.

Errores comunes

Revisen línea por línea cuando tengan un error al ejecutar un script

La mayoría de las veces tenemos problemas por este tipo de errores:

  • R no está listo: El símbolo > debe aparecer en la consola. Si aparece un + significa que no se ha terminado de escribir un comando.
    • Si escribimos un comando incompleto R esperará hasta que terminemos la instrucción. Para detener el proceso podemos presionar Esc.
  • Error al escribir el nombre de las funciones o los objetos. Las mayusculas y el orden de las letras importan.
    • mean(1, 2, 3) es distinto de maen(1, 2, 3)
  • Problemas de puntuación. Mezclar comas , y puntos . o el uso incorrecto de " " o c(1,2.3)
  • Errores en el orden o ausencia de argumentos en las funciones.

DEBEMOS TENER PRECAUCIÓN AL PROGRAMAR.

Anatomía de los principales objetos en R

Anatomía de los principales objetos en R

En R existen varios tipos de objetos que permiten que el usuario pueda almacenar la información para realizar procedimientos estadísticos y gráficos. 💁

Escalares

Númerico

a <- 100
b <- 3 / 100
c <- (a + b) / b

Prueba: class(a)

  • int: Números enteros.

  • dbl: 2 decimales.

Caracteres

d <- "Ventana"
e <- "4"
f <- "Esto es una letra"

Prueba: class(d)

  • También se denominan strings.

Operadores lógicos

g <- TRUE
h <- (3 <= 4)
i <- (c == (a + b) / b)

Prueba: class(g) - Producido con operadores == > < <= >= & | !.

Ejercicio: Escalares

Prueba que sucede si ejecutamos el siguiente código:

a + b
a + e #Error en a + e: argumento no-numérico para operador binario
a + as.numeric(e)
as.numeric(d)
as.character(a) #NAs introducidos por coerción 
  • Es importante tener en cuenta el tipo de datos que contiene un objeto.

Estructura de datos

Vectores

Son objetos unidimensionales que almacenan una secuencia de valores del mismo tipo.

c("Hola mundo!", 35, FALSE)
c("Hola mundo!", "35", "FALSE") # Equivalente a la primera línea
  • Por coerción, R convierte todos los elementos del vector al mismo tipo (strings).
  • Tener los mismos tipos de valores permite que las operaciones se apliquen a todos los elementos del vector.
v1 <- c(1, 2, 3)
v1 
v1 / v3
v1 * v1 # Multiplicación de elemento por elemento
v1 %*% v1 # Multiplicación de matrices

Ejemplo: Operaciones con vectores

# Creación de vectores
v1 <- c(1, 1, 3, 5)  # Especificar elementos
v1
v2 <- c(1:5)     # Generados en secuencia
v2
v3 <- c(v1, v2)  # Combinando
v3

Propiedades de los vectores

  • Tipo. Un vector tiene el mismo tipo que los datos que contiene.

    • Si tenemos un vector que contiene objetos numéricos el vector es de tipo numérico.

    • Los vectores son atómicos. Es decir, solo pueden contener datos de un solo tipo.

  • Largo. Es el número de elementos que contiene el vector lenght(v1).

  • Atributos. Los vectores pueden tener metadatos de muchos tipos, los cuales describen características de los datos que contienen.

Ejercicio

05:00

Necesito que generen el siguiente objeto:

  • Genera un vector que contenga 20 números aleatorios obtenidos de una distribución normal con una media de 2 y una desviación estándar de 3).

  • Calcula el promedio, la mediana y la desviación estándar del vector.

Pista: Comienza leyendo la documentación de ayuda de la función rnorm()

Solución:

v1 <- rnorm(20, mean = 2, sd = 3)
mean(v1)
median(v1)
sd(v1)

Factores

En R los factores de usan para trabajar con variables categóricas. Es decir, que tienen un conjunto fijo y conocido de valores posibles.

  • Los factores son distintos a los datos tipo string.
# Creación de factores
x1 <- c("Dic", "Abr", "Ene", "Mar")
sort(x1)  # No se ordena de forma útil

niveles_meses <- c("Ene", "Feb", "Mar", "Abr","May",
                   "Jun", "Jul", "Ago", "Sep", "Nov",
                   "Dic")

y1 <- factor(x1, levels = niveles_meses)
sort(y1)

Matrices y arreglos

Las matrices y arreglos pueden ser descritas como vectores multidimensionales. Únicamente pueden tener un solo tipo de datos pero incluyen un largo y más dimensiones.

  • Las matrices solo tienen dos dimensiones: Largo y Alto. Rectangulares.

  • Los arreglos pueden tener múltiples dimensiones (Su uso no es común en R).

Podemos crear matrices usando la función matrix() que acepta dos argumentos, nrow y ncol.

# Matriz ordenada con valores del 1 al 12
matrix(1:12)
matrix(1:12, nrow = 3, ncol = 3)

# ¿Qué sucede aquí?
matrix(1:12, nrow = 5, ncol = 4)

Alternativas para matrices

Otro procedimiento para crear matrices es la unión de vectores con las siguientes funciones:

  • cbind() para unir vectores, usando cada uno como columna.

  • rbind() para unir vectores, usando cada uno como fila.

Ejercicio 🎮

Utiliza las funciones anteriores para unir cuatro vectores como una matriz.

vector_1 <- 1:4
vector_2 <- 5:8
vector_3 <- 9:12
vector_4 <- 13:16

matriz <- rbind(vector_1, vector_2, vector_3, vector_4)
matriz

Dataframes

Los dataframes son estructuras de datos de dos dimensiones (rectangulares) que pueden contener datos de diferentes tipos, por lo tanto, son heterogéneas.

# Conjunto de datos sobre flores de Ronald Fisher
data("iris")
head(iris, 5)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa

Un data frame está compuesto por vectores y forman una unión rectangular

Creación de dataframes

mi_df <- data.frame(
  "entero" = 1:4, 
  "factor" = c("a", "b", "c", "d"), 
  "numero" = c(1.2, 3.4, 4.5, 5.6),
  "cadena" = as.character(c("a", "b", "c", "d"))
)

mi_df
# Determinar la dimensión del objeto
dim(mi_df)

# El largo de un data frame es igual a su número de columnas
length(mi_df)

# names() nos permite ver los nombres de las columnas
names(mi_df)

# La clase de un data frame es data.frame
class(data.frame) 

Listas

Las listas en R son un tipo de estructura de datos fundamental y muy flexible, que permiten almacenar colecciones de objetos de diferentes tipos y tamaños, a diferencia de los vectores, que requieren que todos los elementos sean del mismo tipo.

  • Podemos tener listas que contengan datos atómicos, vectores, matrices, arrays, data frames u otras listas. Esta última característica es la razón por la que una lista puede ser considerada un vector recursivo, pues es un objeto que puede contener objetos de su misma clase.

  • Para crear una lista usamos la función list(), que nos pedirá los elementos que deseamos incluir en nuestra lista.

  • Para esta estructura, no importan las dimensiones o largo de los elementos que queramos incluir en ella.

Creación de listas

mi_vector <- 1:10
mi_matriz <- matrix(1:4, nrow = 2)
mi_df     <- data.frame("num" = 1:3, "let" = c("a", "b", "c"))

mi_lista <- list("un_vector" = mi_vector, "una_matriz" = mi_matriz, "un_df" = mi_df)

mi_lista

# Extraer elemento de una lista
vector <- mi_lista$un_vector

Subconjuntos e Indexación

Exploremos los atributos de la base de datos del IMDB usando la función str()

imdb <- read.csv("C:/Users/jeptt/Documents/IMDB.csv")
str(imdb)

Podemos usar el operador $ para crear y reemplazar variables:

# Ordenar de menor a mayor
imdb$rank <- sort(imdb$rank, decreasing = F)

imdb[2]  # Indexación por columnas
imdb[20,]  # Indexación por filas
imdb[40,3] # Indexación por filas y columnas

También podemos acceder al contenido del dataframe usando índices: df[fila, columna]

# Primera fila y columnas name y year
imdb[1, c("name", "year")]
imdb[1, c(2, 4)]

Uso de condicionales

  • Los condicionales nos permiten obtener subconjuntos de datos para los que una o más condiciones son verdaderas (TRUE).
  • Para este tipo de operaciones usamos operadores lógicos y condicionales. Los aplicamos a dataframes.
  • Esta operación tiene la siguiente estructura:
objeto[condición, columnas_devueltas] 

En donde:

  • objeto es un dataframe.
  • condición es un subconjunto del objeto al que se le aplica una prueba lógica.
  • columnas_devueltas el índice o nombre de la columna que deseamos que sea devuelta.

Ejemplo: Uso de condicionales

  • Supongamos que queremos identificar en el dataset del IMDB el nombre de las películas rankeadas en las posiciones 11 a 14:
imdb[imdb$rank > 10 & imdb$rank < 15, "name"]
  • Ahora supon que queremoc conocer los nombres de las películas que han tenido un rating > 8.5:
imdb[imdb$rating > 8.5, "name"]

La función subset()

  • Una alternativa al uso de condicionales, sin necesidad de corchetes, es la función subset().

  • Sintáxis de uso:

subset(x = objeto, subset = condicional, columna_mostrar)
  • Esta función tiene los siguientes argumentos:
    • x: Un objeto, generalmente un dataframe.
    • subset: Una condición expresada usando operaciones relacionales o condicionales que se aplicaran a x.
    • select: Un vector con los nombres de las columas a conservar en el resultado. (Todas por defecto)

Ejemplo: Uso de la función subset()

  • Supongamos que queremos conocer el listado de películas que han obtenido un rating mayor que 8.5:
subset(x = imdb, subset = imdb$rating > 8.5, "name")
subset(x = imdb, subset = imdb$rating > 8.5, 2)

# Podemos llamar a una respuesta con más columnas
subset(x = imdb, subset = imdb$rating > 8.5, c("name", "year"))

Datos faltantes (NA)

  • Crea el siguiente dataframe:
nombre <- c("Juan", "Paola", "Pedro", "Luis")
edad <- c(21, 23, 32, 17)
nacionalidad <- c("MXN", "US", "UK", "ARG")
mascota <- c("gato", "none", "", NA)
df <- as.data.frame(cbind(nombre, edad, nacionalidad, mascota))
df

¿Qué sabemos sobre las mascotas de estas personas?

  • Juan tiene un gato.
  • Paola no tienen ninguna mascota.
  • No sabemos si pedro tiene mascota. ( string vacío "")
  • El valor del campo mascota de Luis está vacío.

Ejercicio

15:00
  • Crea el vector c(7, 7, 8, 8, 7, 7, 8, 8) usando la función rep().
  • Modifica el código seq(1,6) para obtener el vector c(0, 2, 4, 6).

Usando la base de datos del IMDB realiza lo siguiente:

  • Obten el nombre de la película con la menor duración (en minutos):
    • Puedes usar la función min().
  • En el dataset hay 6 películas con una duración de 132 minutos ¿Cuáles son?

Soluciones

# Crea el vector `c(7, 7, 8, 8, 7, 7, 8, 8) usando la función `rep()`.
rep(c(7,8), times = 2, each = 2)

# Modifica el código `seq(1,6)` para obtener el vector `c(0, 2, 4, 6)`.
seq(from = 0, to = 6, by = 2)

# seq(0, 6, 2)

Soluciones

imdb <- read.csv("C:/Users/jeptt/Documents/IMDB.csv")
# Obten el nombre de la película con la menor duración (en minutos):
# min(imdb$duration_minutes)
min(imdb$duration_minutes, na.rm = TRUE)

# ¿Cómo se llama está película? 
imdb[imdb$duration_minutes == 67, "name"]
imdb[!is.na(imdb$duration_minutes) & imdb$duration_minutes == 67, "name"]

# En el dataset hay 6 películas con una duración de 132 minutos ¿Cuáles son?
imdb[imdb$duration_minutes == 132, "name"]
imdb[!is.na(imdb$duration_minutes) & imdb$duration_minutes == 132, "name"]

# Las respuestas muestran NA porque hay películas con información incompleta sobre su duración. 

Funciones en R

Funciones personalizadas

  • La instalación de R base tiene suficientes funciones para que realicemos las tareas básicas de análisis de datos.
  • Es común que necesitemos realizar tareas para las que no existe una función específica o tengamos que combinar funciones de varias librerías.
  • Las funciones definidas por el usuario deben ser creadas usando la siguiente estructura:
nombre <- function(){
  Operaciones
}

Una función tiene un nombre, argumento y un cuerpo.

Ejemplo: Funciones personalizadas

Supongamos que necesitamos escribir una función en Rpara calcular el área de un cuadrilatero: lado x lado

area_cuad <- function(lado1, lado2){
  lado1 * lado2
}
  • Para ejecutar nuestra función escribimos el siguiente código:
area_cuad(lado1 = 4, lado2 = 6)
area_cuad(4,6) # ¿Es lo mismo?
  • Nota: Si no asignamos valores a los dos argumentos de nuestra función se mostrará un error.
area_cuad(lado1 = 4)

Ejercicio

10:00
  • Supongamos que se levantó una encuesta a 1500 personas en donde se les preguntó su nivel de ingresos.
    • Supon que los datos se obtuvieron del siguiente DGP: \(Ingreso \sim N(\mu = 15000, \sigma = 4500)\)
  • Escribe una función que grafique la distribución de los ingresos de las personas mediante un histograma. Señala cual es la media de la distribución (en color rojo) y su desviación estándar (en azul).

Solución

# Primero simulamos el DGP
set.seed(123)  # Para tener los mismos valores
ingreso <- rnorm(1500, mean = 15000, sd = 4500)
ingreso[1:10]

hist(ingreso)
# Escribimos nuestra función para gráficar la distribución 

crear_histograma <- function(datos, nombre) {
  media <- mean(datos)  # Calculamos la media 
  desv_est <- sd(datos) # Calculamo la desv.est. 
  
  hist(datos, main = nombre, xlab = "Datos", ylab = "Frecuencia", col = "gold")
  abline(v = media, col = "red") # Marcar media en rojo
  abline(v = media + (desv_est * c(1, -1)), col = "blue") # sd en azul
}


crear_histograma(ingreso, "Ingreso")

Fin de la sesión