Procesando datos con {tidyverse} - Parte I

Módulo 3 - Importación, select() y filter()

Pablo Tiscornia

Estación R

2026-03-10

Bienvenidos y bienvenidas

Contacto con Estación R



¿Qué vimos hasta ahora?


✅ La EPH: qué mide, cómo se estructura, cuestionarios


✅ Conceptos básicos de R: valores, vectores, funciones, objetos


✅ Cómo usar la IA como asistente para aprender R


RStudio: consola, scripts, entorno

Hoja de Ruta - Hoy


📦 {tidyverse}: un universo de paquetes


📥 Importar datos: la EPH en R


🔗 La pipa (|>)

🔧 select() - elegir columnas


🔧 filter() - filtrar filas

Paquetes en R

¿Qué son los paquetes?


R viene con funciones básicas (c(), mean(), class()…), pero su verdadero poder está en los paquetes.


Un paquete es un conjunto de funciones que alguien creó para resolver un problema específico.


Pensalo como una caja de herramientas: R es el taller, y los paquetes son cajas con herramientas especializadas que podemos agregar.

¿Cómo se usan los paquetes?


Paso 1: Instalar (una sola vez, como descargar una app):

install.packages("nombre_del_paquete")


Paso 2: Cargar (cada vez que abrimos R, como abrir la app):

library(nombre_del_paquete)


Primero se instala (una vez), después se carga (cada sesión).

{tidyverse}

¿Qué es {tidyverse}?


  • Una colección de paquetes de R.
  • Comparten una filosofía acerca de los datos y la programación en R (“tidy” - ordenado).
  • Tienen una coherencia para ser utilizados en conjunto.
  • Orientado a ser leído y escrito por y para seres humanos.
  • Una comunidad, basada en los principios del código abierto y trabajo colaborativo.

¿Qué es {tidyverse}?


{tidyverse} - Instalación y carga


  • Instalación (una sola vez):
install.packages("tidyverse")


  • Cargo el paquete (cada vez que abro R):
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.6
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.1     ✔ tibble    3.3.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.2
✔ purrr     1.2.1     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Importar datos: la EPH en R

¿Cómo traemos datos a R?


Hasta ahora creamos datos “a mano” con c() y data.frame().


Pero en la práctica, los datos ya existen: en archivos .csv, .xlsx, bases de datos…


Hoy vamos a importar datos reales de la EPH.

Opción 1: Descargar desde INDEC



  1. Buscar “Encuesta Permanente de Hogares” > Bases trimestrales


  1. Descargar el archivo .zip del trimestre deseado


  1. Descomprimir y usar read.csv() o read_csv() para leer el archivo .txt

Opción 1: Importar con read.csv()


# Opción con R base
eph_ind <- read.csv("datos/usu_individual_T124.txt",
                     sep = ";")


# Opción con tidyverse (readr) - más rápida
library(readr)

eph_ind <- read_csv2("datos/usu_individual_T124.txt")

Opción 2: El paquete {eph}


El paquete {eph} fue creado por la comunidad R argentina para facilitar el trabajo con la EPH.


# Instalar (una sola vez)
install.packages("eph")


# Descargar datos directamente desde R
library(eph)

eph_ind <- get_microdata(year = 2024,
                         trimester = 1,
                         type = "individual")

Nuestros datos para hoy

library(readr)
eph_ind <- read_csv("datos/eph_individual.csv")


# ¿Cuántas filas y columnas?
dim(eph_ind)
[1] 46050   235


46.050 personas y 235 variables. Cada fila es una persona encuestada.

Explorando la base


# ¿Qué columnas tiene? (mostramos las primeras 20)
head(colnames(eph_ind), 20)
 [1] "CODUSU"     "ANO4"       "TRIMESTRE"  "NRO_HOGAR"  "COMPONENTE"
 [6] "H15"        "REGION"     "MAS_500"    "AGLOMERADO" "PONDERA"   
[11] "CH03"       "CH04"       "CH05"       "CH06"       "CH07"      
[16] "CH08"       "CH09"       "CH10"       "CH11"       "CH12"      

head() nos muestra los primeros elementos de un resultado (acá, las primeras 20 columnas).


Los nombres de las variables son códigos (CH04, CH06, ESTADO…). Para entender qué significan, necesitamos el diseño de registro de la EPH.

Variables clave de la EPH


Variable Significado Valores
CH04 Sexo 1=Varón, 2=Mujer
CH06 Edad Años cumplidos
ESTADO Condición de actividad 1=Ocupado, 2=Desocupado, 3=Inactivo
CAT_OCUP Categoría ocupacional 1=Patrón, 2=Cta. propia, 3=Asalariado
NIVEL_ED Nivel educativo 1 a 7 (de primaria incompleta a superior completa)
P21 Ingreso ocupación principal En pesos
REGION Región estadística 1=GBA, 40=NOA, 41=NEA, 42=Cuyo, 43=Pampeana, 44=Patagonia

La pipa

Un operador llamado pipa




base_de_datos |>
  funcion1 |>
  funcion2 |>
  funcion3

Un operador llamado pipa


  • Pipa de R base: |> (atajo: Ctrl + Shift + M)


  • Pipa de {magrittr}: %>%


Ambas hacen lo mismo: pasan el resultado de la izquierda como primer argumento de la función de la derecha

Ejemplo sin pipa



datos <- data.frame(nombre = c("Pirulanzo", "Rodogovia", "Rodogovia", "Rodogovia"),
                    edad = c(23, 12, 87, 32))

datos
     nombre edad
1 Pirulanzo   23
2 Rodogovia   12
3 Rodogovia   87
4 Rodogovia   32

Ejemplo sin pipa


  • Quiero calcular qué proporción de personas se llaman Rodogovia


  • Antes (sin el pipe):
round(prop.table(table(datos$nombre)), digits = 1)

Pirulanzo Rodogovia 
      0.2       0.8 


Se lee de adentro hacia afuera… 🤯

Ejemplo con pipa


  • Después (con el pipe):
datos$nombre |>
  table() |>
  prop.table() |>
  round(digits = 1)

Pirulanzo Rodogovia 
      0.2       0.8 


Se lee de arriba hacia abajo, paso a paso ✨

select()

Funciones del paquete {dplyr}


Función Acción
select() selecciona o descarta columnas
filter() selecciona filas
mutate() crea / edita variables
rename() renombra variables
group_by() segmenta en función de una variable
summarize() genera una tabla de resumen

Hoy nos enfocamos en select() y filter(). El resto, la semana que viene.

select() - Elige o descarta columnas


  • La función tiene la siguiente estructura:
base_de_datos |>
  select(variable1, variable2)

Caso práctico


  • Pedido: La directora de investigación nos pidió analizar la edad y el sexo de la población encuestada, junto con su condición de actividad.


  • Variables de trabajo:

    • CH04 (sexo)
    • CH06 (edad)
    • ESTADO (condición de actividad)

Caso práctico - Selecciono columnas


eph_ind |>
  select(CH04, CH06, ESTADO)
# A tibble: 46,050 × 3
    CH04  CH06 ESTADO
   <dbl> <dbl>  <dbl>
 1     2    86      3
 2     1    68      1
 3     1    20      2
 4     2    75      3
 5     2    41      1
 6     1    42      1
 7     2    20      3
 8     1    14      3
 9     1    29      1
10     2    27      2
# ℹ 46,040 more rows

Caso práctico - Guardo en un objeto


eph_sel <- eph_ind |>
  select(CH04, CH06, ESTADO)


colnames(eph_sel)
[1] "CH04"   "CH06"   "ESTADO"

Ahora eph_sel tiene solo 3 columnas, en vez de las 235 originales.

select() - por posición


# Selecciono las columnas 1, 12 y 14 (CODUSU, CH04, CH06)
eph_ind |>
  select(1, 12, 14) |>
  colnames()
[1] "CODUSU" "CH04"   "CH06"  


# Selecciono un rango de columnas consecutivas
eph_ind |>
  select(11:16) |>
  colnames()
[1] "CH03" "CH04" "CH05" "CH06" "CH07" "CH08"

select() - Por patrones de texto


Trío muy útil:

  • starts_with() –> empieza con…
  • ends_with() –> termina con…
  • contains() –> contiene…

select() + starts_with()


# Todas las variables del cuestionario de Hogar (empiezan con "CH")
eph_ind |>
  select(starts_with("CH")) |>
  colnames()
 [1] "CH03"     "CH04"     "CH05"     "CH06"     "CH07"     "CH08"    
 [7] "CH09"     "CH10"     "CH11"     "CH12"     "CH13"     "CH14"    
[13] "CH15"     "CH15_COD" "CH16"     "CH16_COD"

select() + ends_with()


# Variables que terminan en "_COD" (códigos de clasificación)
eph_ind |>
  select(ends_with("_COD")) |>
  colnames()
[1] "CH15_COD"  "CH16_COD"  "PP04B_COD" "PP04D_COD" "PP11B_COD" "PP11D_COD"

select() + contains()


# Variables que contienen "ING" (relacionadas a ingresos)
eph_ind |>
  select(contains("ING")) |>
  colnames()
character(0)

La combinación final


Se pueden combinar todas las formas:

eph_ind |>
  select(CODUSU, CH04, CH06, starts_with("P21"), ESTADO, REGION) |>
  colnames()
[1] "CODUSU" "CH04"   "CH06"   "P21"    "ESTADO" "REGION"

Ejercitación

Ejercitación select()


Usando la base de la EPH:

  1. Seleccionar las variables CH04 (sexo), CH06 (edad) y P21 (ingreso) y guardar en un objeto.


  1. Seleccionar todas las variables que empiecen con “CH” y guardar en otro objeto. ¿Cuántas hay?


  1. Seleccionar las columnas 1 a 5 y verificar con colnames().

filter()

filter() - Define filas en base a una condición


  • La función tiene la siguiente estructura:
base_de_datos |>
  filter(condicion)

Caso práctico


  • Para un informe de empleo, necesitamos quedarnos solo con la población ocupada (ESTADO == 1).


  • Primero, chequeamos los valores de la variable:
unique(eph_ind$ESTADO)
[1] 3 1 2 4 0

Recordar: 1=Ocupado, 2=Desocupado, 3=Inactivo, 4=Menor de 10 años

Caso práctico - Aplico filtro


eph_ocupados <- eph_ind |>
  filter(ESTADO == 1)


  • Chequeo que funcionó:
unique(eph_ocupados$ESTADO)
[1] 1
# ¿Cuántas personas ocupadas hay?
nrow(eph_ocupados)
[1] 20325

Operadores de comparación


Condición Acción
== igual
%in% incluye
!= distinto
> mayor que
< menor que
>= mayor o igual que
<= menor o igual que
Operador Descripción
& y - Ambas condiciones se cumplen
\| o - Una u otra condición se cumple

Caso práctico - Filtro numérico


  • Queremos analizar a la población mayor de 65 años:
eph_mayores <- eph_ind |>
  filter(CH06 > 65)

nrow(eph_mayores)
[1] 5744

Caso práctico - Múltiples condiciones


  • Para un estudio de género y empleo: mujeres ocupadas.


  • Opción 1 (con &):
eph_mujeres_ocup <- eph_ind |>
  filter(CH04 == 2 & ESTADO == 1)

nrow(eph_mujeres_ocup)
[1] 9112

Caso práctico - Operador %in%


  • Queremos analizar solo GBA y Patagonia (REGION 1 y 44):
eph_gba_pat <- eph_ind |>
  filter(REGION %in% c(1, 44))

table(eph_gba_pat$REGION)

   1   44 
7051 5527 


%in% es más prolijo que escribir REGION == 1 | REGION == 44, especialmente cuando son varias categorías.

Novedad: filter_out()


Desde febrero 2026, dplyr incluye filter_out(): el complemento de filter().


  • filter() = me quedo con las filas que cumplen la condición
  • filter_out() = saco las filas que cumplen la condición


# Estas dos líneas hacen lo mismo:
eph_ind |> filter(ESTADO != 4)

eph_ind |> filter_out(ESTADO == 4)


Para usarlo, actualizar dplyr: install.packages("dplyr")

Combinando select() + filter()

select() + filter()


eph_ind |>
  select(CH04, CH06,
         ESTADO, P21)
# A tibble: 46,050 × 4
    CH04  CH06 ESTADO    P21
   <dbl> <dbl>  <dbl>  <dbl>
 1     2    86      3      0
 2     1    68      1 150000
 3     1    20      2      0
 4     2    75      3      0
 5     2    41      1 250000
 6     1    42      1 650000
 7     2    20      3      0
 8     1    14      3      0
 9     1    29      1 280000
10     2    27      2      0
# ℹ 46,040 more rows

select() + filter()


eph_ind |>
  select(CH04, CH06,
         ESTADO, P21) |>
  filter(ESTADO == 1)
# A tibble: 20,325 × 4
    CH04  CH06 ESTADO    P21
   <dbl> <dbl>  <dbl>  <dbl>
 1     1    68      1 150000
 2     2    41      1 250000
 3     1    42      1 650000
 4     1    29      1 280000
 5     2    31      1  50000
 6     1    33      1 300000
 7     2    63      1 250000
 8     1    61      1     -9
 9     1    25      1 180000
10     1    51      1     -9
# ℹ 20,315 more rows

La pipa nos permite encadenar operaciones paso a paso 🔗

Un análisis más completo


# Mujeres ocupadas de GBA, con sus ingresos
eph_ind |>
  select(CH04, CH06, ESTADO, REGION, P21) |>
  filter(ESTADO == 1,
         CH04 == 2,
         REGION == 1,
         P21 > 0)
# A tibble: 1,043 × 5
    CH04  CH06 ESTADO REGION    P21
   <dbl> <dbl>  <dbl>  <dbl>  <dbl>
 1     2    38      1      1 400000
 2     2    29      1      1 380000
 3     2    31      1      1 180000
 4     2    56      1      1 120000
 5     2    33      1      1 100000
 6     2    70      1      1 100000
 7     2    38      1      1  72000
 8     2    33      1      1 320000
 9     2    32      1      1  78000
10     2    33      1      1  30000
# ℹ 1,033 more rows

Ejercitación

Ejercitación select() + filter()


  1. Crear un objeto con las variables CH04, CH06, NIVEL_ED y ESTADO. Filtrar solo la población inactiva (ESTADO == 3).


  1. Del objeto anterior, ¿cuántas personas inactivas hay? (tip: nrow())


  1. Crear un objeto con varones mayores de 18 años (CH04 == 1 y CH06 > 18), seleccionando las variables CH06, ESTADO y P21.


  1. Desafío: Filtrar la población ocupada de la región Pampeana (REGION == 43) que tenga un ingreso (P21) mayor a 0. ¿Cuántas personas son?

Para la semana que viene…

Próximo encuentro: tidyverse II (18/02)


🔧 mutate() + case_when() - crear y recodificar variables


🔧 summarise() - resumir información


🔧 group_by() - operar por grupos


🎯 Combinando todo: tidyverse en acción con la EPH

¡Gracias!



Nos vemos el martes 18 de febrero


📧 pablotiscornia@estacion-r.com

💬 Slack de Estación R