[1] 4
Curso dirigido a personas de las Ciencias Sociales
2026-03-25
Bastián Olea Herrera
Encuentra todo sobre el curso en este post de mi blog.
Puedes encontrar más contenidos para aprender R en este sitio, y más cosas de R en mi sitio web.
Existen muchas diferencias entre hacer algo y programarlo:
R es un lenguaje de programación enfocado al análisis de datos, las estadísticas y la visualización de datos.

Gratuito
R es un lenguaje de programación abierto y gratuito, y es parte de la comunidad del software libre, así que nunca tendrás que pagar nada!
Amigable
R fue creado para personas de distintas disciplinas, y al centrarse en los datos resulta más intuitivo que otros lenguajes.
Reproducible
La gracia de R es guardar todos los pasos de tu análisis, lo que facilita corregirlos, reutilizarlos para nuevos casos, y compartirlo con otros.

Muestra de algunas aplicaciones, gráficos, tablas, y mapas hechos con R. También algunos trabajos que he hecho.
![]()
Archivo de texto .R en el que escribimos nuestro código, en pasos, y siguiendo un orden lógico.
![]()
Es la forma directa de interactuar con R, un comando a la vez, con resultados efímeros.
![]()
Archivo .Rproj que marca nuestro espacio de trabajo: una carpeta específica que reúne todas las piezas de nuestro análisis.
RStudio es una IDE (entorno de desarrollo integrado) que nos permite escribir código en R de forma más cómoda, organizada, y visual.

1 Scripts
2 Consola
3 Entorno
4 Archivos
1 Panel de scripts: los archivos de texto con nuestro código. Podemos tener varias pestañas. Ejecutamos el código poniendo el cursor en la línea y presionando control + enter, o el botón Run.
2 Panel de consola: en la consola se imprimen los resultados del código que ejecutamos. También podemos ejecutar código directamente en ella escribiendo y presionando enter.
3 Panel de entorno: acá veremos los objetos que vayamos creando o cargando, que pueden ser números, texto, tablas de datos, funciones, gráficos y otros.
4 Panel de archivos: en este panel podemos navegar los archivos y carpetas de nuestro proyecto y/o computador. La idea es que todo esté dentro del proyecto!


Crear un nuevo script de R

Botón para ejecutar código

Botón para ejecutar todo el script

Configurar paneles de RStudio

Cambiar de proyecto o crear uno nuevo
Veamos ahora los elementos más básicos del lenguaje R, para luego avanzar a su aplicación al análisis de datos.

control + enter.| esté en cualquier lugar de la línea.Lo que podemos hacer siempre va a depender del tipo de cada objeto.
En R existen varios tipos:
Se le llama objeto a cualquier dato, variable, o elemento que tengas en R.
Podemos guardar todo como un objeto.
Para crear un objeto, simplemente le damos un nombre y le asignamos un contenido.
nombre ← contenido
Con el operador de asignación creamos objetos nuevos.
->
Se escribe con:
Windows:

Mac:

Al asignar algo, creamos o modificamos un objeto con el valor que le estamos asignando.
Al ejecutar un objeto, obtenemos su valor.
Podemos usar el objeto creado para lo que queramos.
Crear objetos es como asignar variables, y podemos usar estas variables para llevar a cabo operaciones!
Los vectores son secuencias de elementos. Un objeto que contiene cero o más datos.
Podemos realizar cualquier operación sobre los elementos de un vector:
función(argumento = 123)
Algunas funciones comunes:
Para cargar datos, tenemos que:

{readxl} es uno de los paquetes de lectura de planillas Excel. Para escribir un archivo Excel está {writexl}{readr} lee y escribe datos de múltiples formatos (csv, rds, rdata), usualmente de forma más veloz y cómoda{haven} permite cargar archivos SPSS, Stata, y SAS{arrow} es un formato moderno de datos columnares, optimizado para grandes volúmenes y velocidad de carga, y pensado para usarse en distintos softwaresProbemos cargando unos datos!
Cargamos los datos usando una función del paquete {readxl}:
# A tibble: 6 × 10
codigo region comuna personas_proy personas porcentaje limite_inferior
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 1101 Tarapacá Iquique 229674 41967. 0.183 0.162
2 1107 Tarapacá Alto Hospic… 138527 45162. 0.326 0.295
3 1401 Tarapacá Pozo Almonte 18290 4563. 0.250 0.199
4 1402 Tarapacá Camiña 1380 308. 0.223 0.138
5 1403 Tarapacá Colchane 1575 473. 0.300 0.187
6 1404 Tarapacá Huara 3072 1185. 0.386 0.319
# ℹ 3 more variables: limite_superior <dbl>, casen <chr>, tipo_estimacion <chr>
{dplyr}|>
{dplyr}?Para explorar y modificar los datos.
Seleccionar columnas:
# A tibble: 4 × 3
region comuna porcentaje
<chr> <chr> <dbl>
1 Tarapacá Iquique 0.183
2 Tarapacá Alto Hospicio 0.326
3 Tarapacá Pozo Almonte 0.250
4 Tarapacá Camiña 0.223
Ordenar observaciones:
# A tibble: 4 × 3
region comuna porcentaje
<chr> <chr> <dbl>
1 Magallanes Río Verde 0.00113
2 Magallanes Laguna Blanca 0.00353
3 Magallanes Cabo De Hornos 0.0158
4 Metropolitana Vitacura 0.0244
Filtrar datos:
# A tibble: 4 × 3
region comuna porcentaje
<chr> <chr> <dbl>
1 Tarapacá Alto Hospicio 0.326
2 Tarapacá Colchane 0.300
3 Tarapacá Huara 0.386
4 Atacama Tierra Amarilla 0.345
Crear variables:
# A tibble: 4 × 3
comuna porcentaje ranking
<chr> <dbl> <int>
1 General Lagos 0.586 1
2 Saavedra 0.445 2
3 Ercilla 0.416 3
4 Galvarino 0.399 4
Y más!
El conector o pipe |> (o también %>%) nos permite encadenar varias funciones de forma más legible.
|> o %>%
Se escribe con:
Windows:

Mac:

Se lee: al objeto le aplicamos la funcion()
Luego podemos encadenar varias funciones:
Usaremos los datos de pobreza del Ministerio Desarrollo Social y Familia que vimos antes. Si no los cargaste, descárgalos y los cargas así:
# A tibble: 6 × 3
region comuna personas
<chr> <chr> <dbl>
1 Metropolitana Puente Alto 125235.
2 Metropolitana Santiago 87355.
3 Metropolitana Maipú 86976.
4 Antofagasta Antofagasta 73103.
5 Metropolitana San Bernardo 64276.
6 Valparaíso Valparaíso 60901.
Al aplicar una función sobre un dataframe, por ejemplo, select() para seleccionar columnas, no estamos modificando los datos, sino que estamos trabajando con una copia de los datos para no afectar los datos originales.
Todo lo que hagamos con {dplyr} serán pruebas y exploración de los datos, hasta que decidamos que los cambios que hagamos deben guardarse, así que entonces los asignamos a un objeto nuevo.
Como asignamos los resultados a un objeto nuevo, tampoco estamos modificando ni afectando los datos originales. Así mantenemos un proceso reproducible!
Podemos usar cifras u objetos para compararlas entre sí: la respuesta será TRUE (verdadero) o FALSE (falso).
Las comparaciones son el principio que luego nos permitirá filtrar datos, crear variables, y más!
También podemos realizar comparaciones sobre los valores de un vector:
En el fondo, cuando filtremos datos, las columnas de un dataframe serán vectores, y las comparaciones se harán sobre cada uno de los valores de la columna, entregando un resultado TRUE o FALSE para cada fila, que luego usaremos para quedarnos sólo con las filas que cumplen la condición que queremos.
# A tibble: 6 × 10
codigo region comuna personas_proy personas porcentaje limite_inferior
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 15202 Arica y Parin… Gener… 668 392. 0.586 0.435
2 9116 La Araucanía Saave… 12717 5654. 0.445 0.361
3 9204 La Araucanía Ercil… 8422 3503. 0.416 0.361
4 9106 La Araucanía Galva… 12594 5029. 0.399 0.313
5 8314 Biobío Alto … 6784 2640. 0.389 0.319
6 10306 Los Lagos San J… 7521 2923. 0.389 0.314
# ℹ 3 more variables: limite_superior <dbl>, casen <chr>, tipo_estimacion <chr>
Algunas de las funciones más comunes de usar en {dplyr}, que son también las que usaremos para interactuar con los datos.
head(), tail(), glimpse(): vistazos a los datosselect(): seleccionar columnas o variables de una tablaslice(): extraer filas de una tabla por su posición o distintos criteriospull(): extraer una columna como vectorfilter(): filtrar observaciones en base a condiciones personalizadasdistinct(): filtrar observaciones repetidas en una o más columnascount(): conteo de casos únicos en una o más columnasmutate(): crear columnas entregando valores, funciones sobre columnas, o calculando a partir de otras columnas
El paquete {stringr} se especializa en texto.
Con mutate() para crear una nueva variable o columna
Le aplicamos mutate() a un data frame conectando los datos a la función con un conector (|> o %>%)
Las funciones realizan operaciones sobre todos los datos de una columna, reemplazando los datos existentes, o rellenando datos de una columna nueva.
Dependiendo de lo que queramos hacer, las funciones que apliquemos con mutate() pueden hacer referencia a una o a varias columnas:
datos |>
select(comuna, personas) |>
arrange(desc(personas)) |>
head() |>
mutate(total_personas = sum(personas)) |> # aplicada a una columna
mutate(letras = nchar(comuna)) |> # aplicada a otra columna
mutate(orden = row_number()) |> # hace algo por sí misma
mutate(porcentaje = round(personas/total_personas, 2)) # función con argumento# A tibble: 6 × 6
comuna personas total_personas letras orden porcentaje
<chr> <dbl> <dbl> <int> <int> <dbl>
1 Puente Alto 125235. 497846. 11 1 0.25
2 Santiago 87355. 497846. 8 2 0.18
3 Maipú 86976. 497846. 5 3 0.17
4 Antofagasta 73103. 497846. 11 4 0.15
5 San Bernardo 64276. 497846. 12 5 0.13
6 Valparaíso 60901. 497846. 10 6 0.12
ifelse()Si ocurre esto, entonces retorno lo primero, y si no, lo segundo.
# A tibble: 6 × 3
comuna porcentaje nivel
<chr> <dbl> <chr>
1 Iquique 0.183 baja
2 Alto Hospicio 0.326 alta
3 Pozo Almonte 0.250 baja
4 Camiña 0.223 baja
5 Colchane 0.300 alta
6 Huara 0.386 alta
case_when()Recodificación avanzada con múltiples condicionales.
# A tibble: 6 × 3
comuna porcentaje miles
<chr> <dbl> <chr>
1 Iquique 0.183 baja
2 Alto Hospicio 0.326 alta
3 Pozo Almonte 0.250 media
4 Camiña 0.223 media
5 Colchane 0.300 alta
6 Huara 0.386 alta
Aplicar una función para resumir todas las filas de una tabla en un sólo resultado:
Veamos los datos de educación del Censo 2024, que contienen la escolaridad promedio de cada comuna, por sexo.
# A tibble: 4 × 4
region escolaridad escolaridad_mayores_…¹ n_comunas
<chr> <dbl> <dbl> <int>
1 Antofagasta 9.77 11.6 9
2 Arica y Parinacota 8.6 9.85 4
3 Atacama 9.5 11.1 9
4 Aysén del General Carlos Ibáñez … 9.45 11.0 10
# ℹ abbreviated name: ¹escolaridad_mayores_edad
Para cruzar dos tablas de datos
usamos left_join() de {dplyr}

Veamos un ejemplo donde cruzamos dos tablas, la de pobreza y una nueva de clasificación comunal (urbana, mixta, rural según la PNDR), a partir de la columna que tienen en común: codigo
# A tibble: 3 × 5
codigo comuna personas porcentaje clasificacion
<dbl> <chr> <dbl> <dbl> <chr>
1 1101 Iquique 41967. 0.183 Urbana
2 1107 Alto Hospicio 45162. 0.326 Urbana
3 1401 Pozo Almonte 4563. 0.250 Rural
{tidyr} se especializa en transformar la estructura de los datos.sum(valores)) que en columnas (y tener que sumar a+b+c+d…)
pivot_longer()pivot_wider()

Veamos un ejemplo donde transformamos los datos de estimaciones de población del INE, desde un formato ancho (años en columnas) a uno largo (años en filas).
# A tibble: 6 × 6
edad sexo `1992` `1993` `1994` `1995`
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 0 Hombres 151857 148533 146443 144016
2 1 Hombres 153970 151413 148142 146101
3 2 Hombres 153669 153837 151313 148047
4 3 Hombres 147481 153581 153800 151266
5 4 Hombres 140829 147469 153571 153785
6 5 Hombres 134445 140838 147461 153551
# A tibble: 6 × 4
edad sexo año poblacion
<chr> <chr> <chr> <dbl>
1 0 Hombres 1992 151857
2 0 Hombres 1993 148533
3 0 Hombres 1994 146443
4 0 Hombres 1995 144016
5 0 Hombres 1996 139539
6 0 Hombres 1997 138013
{dplyr}Para que puedan repasar o guiarse con casos básicos de uso de {dplyr} con datos reales, dejo un par de tutoriales:
Algunos conjuntos de datos limpios para practicar
{ggplot2}

Conceptos que constituyen la gramática de los gráficos:
Conceptos de la gramática de gráficos aplicados al código:
Podemos configurar y agregar textos del gráfico con la capa labs():
Configuración completa de cualquier aspecto o elemento del gráfico.
Agregar un tema prediseñado que cambia la apariencia general del gráfico:
theme_minimal()theme_classic()theme_void()theme_linedraw()En theme() podemos cambiar aspectos específicos. Los principales empiezan con:
panelgridscalesaxisstriplegendCada aspecto del gráfico es de un tipo distinto, y cada tipo se configura mediante una función:
element_text(), txtoselement_line(), líneaselement_rect(), rectánguloselement_blank(), ocultarHoja de referencia de los elementos de temas en {ggplot2}, fuente: Isabella Benabaye
grafico_textos +
theme(plot.title = element_text(face = "bold", size = 16),
plot.subtitle = element_text(family = "Arial", face = "italic"),
panel.grid.major = element_line(linewidth = 0.5, color = "#C2A1D6"),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "#DBBFEC", color = NA),
axis.title = element_text(face = "bold"),
axis.title.x = element_text(margin = margin(t = 8)),
axis.text.x = element_text(angle = 90, vjust = 0.5),
legend.title = element_text(face = "bold", size = 14, margin = margin(b = 10)),
legend.text = element_text(margin = margin(l = 4)),
legend.key = element_rect(fill = "#DBBFEC", color = "#C2A1D6"),
legend.key.spacing.y = unit(1.8, "mm"))
{ggplot2}
Existen muchos paquetes que extienden las capacidades de {ggplot2}:
{ggforce}: nuevas geometrías{patchwork}: combinación de gráficos{ggrepel}: separación de textos sobrepuestos{gganimate}: gráficos animados{marquee} y {ggtext}: textos con formato, color, y más{ggiraph} y {plotly}: gráficos interactivos{ggplot2} en inglés{sf} entrega herramientas para trabajar con datos geoespaciales en R{ggplot2}
El paquete {chilemapas} ofrece funciones que simplifican la obtención de mapas de Chile en R.
# A tibble: 12 × 4
codigo_comuna codigo_provincia codigo_region geometry
<chr> <chr> <chr> <MULTIPOLYGON [°]>
1 14203 142 14 (((-71.65597 -40.35386, -71.657…
2 14204 142 14 (((-71.88915 -40.55144, -71.891…
3 14201 142 14 (((-73.15077 -40.06596, -73.147…
4 14202 142 14 (((-71.81459 -40.08101, -71.820…
5 14104 141 14 (((-72.02965 -39.93203, -72.034…
6 14105 141 14 (((-72.61245 -39.62475, -72.607…
7 14103 141 14 (((-72.32959 -39.51024, -72.327…
8 14106 141 14 (((-72.83588 -39.41328, -72.841…
9 14107 141 14 (((-72.92395 -39.94016, -72.916…
10 14108 141 14 (((-71.81459 -40.08101, -71.815…
11 14102 141 14 (((-73.39203 -39.88653, -73.389…
12 14101 141 14 (((-73.2668 -39.88605, -73.2621…
Sólo basta con cruzar una tabla con las geometrías
# cargar datos de pobreza por comuna
pobreza <- read_xlsx("datos/pobreza/estimaciones_pobreza.xlsx") |>
mutate(codigo = as.numeric(codigo))
# filtrar mapa en una región específica
mapa_region <- mapa_comunas |>
filter(codigo_region == "04") |>
mutate(codigo = as.numeric(codigo_comuna))
# unir el mapa con los datos
mapa_datos <- mapa_region |>
left_join(pobreza, by = "codigo")
# visualizar
mapa_datos |>
ggplot() +
aes(geometry = geometry,
fill = porcentaje * 100) +
geom_sf(linewidth = 0) +
scale_fill_gradient(low = "#9F69C7", high = "#23102A") +
labs(fill = "Pobreza")
Puedes encontrar más datos en mi repositorio de datos sociales, en el banco integrado de datos del Ministerio de Desarrollo, en los datos abiertos del Estado Chile, y muchos más.
Puedes escribirme cualquier duda o comentario por aquí