🏠↩︎ De vuelta a la página principal del curso


Inicio

🚀 Objetivo de la unidad

Que el estudiante sea capaz de importar y exportar conjuntos de datos de y en diferentes formatos, así como ejecutar transformaciones básicas sobre estas utilizando dataframes y el paquete data.table.

🗂 ⬇ Descargar datos a utilizar en la práctica y los ejercicios

  • Los archivos pob_censo_2020_inegi.csv, pob_censo_2020_inegi.txt y pob_censo_2020_inegi.xlsx contienen el mismo conjunto de datos de población de hombres y mujeres por entidad federativa y edad. La fuente de los datos es el Censo de Población y Vivienda 2020 del INEGI.

  • El archivo pob_censo_2020_inegi.csv contiene datos de población de hombres y mujeres que estudiaron una licenciatura (o equivalente) por entidad federativa y edad. La fuente de los datos es el Censo de Población y Vivienda 2020 del INEGI.


🇷 ⬇ Descargar projecto de R de la práctica 🇷 ⬇ Descargar projecto de R de los ejercicios resueltos


3.1. Instalando y cargando paquetes

Las siguientes instrucciones descargan los paquetes que utilizaremos en la práctica a tu equipo de cómputo. Por lo tanto, solo se debe correr una única vez (por equipo de cómputo).

# install.packages("data.table")
# install.packages("curl")
# install.packages("readxl")
# install.packages("foreign")
# install.packages("lubridate")


Cargando un paquete Esta instrucción carga las funciones de los paquetes que utilizaremos a tu sesión de R actual. Por lo tanto, debemos correrla cada que vayamos a utilizar las funciones del paquete en una nueva sesión de R.

library(data.table)
library(readxl)
library(foreign)
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:data.table':
## 
##     hour, isoweek, mday, minute, month, quarter, second, wday, week,
##     yday, year
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union


3.2. Creando un data table

  • Desde 0

Recuerde que un data frame (y por lo tanto, un data table también) se compone de vectores. En el siguiente bloque de código, se instancian dos vectores inicialmente para después utilizarlos al crear un nuevo data table desde 0. 💡 Recordemos que los data tables heredan todas las propiedades de un data frame.

x <- 1:200
y <- rnorm(200, mean = 70, sd = 10)
dt <- data.table(id = x, age = y) 

Es importante denotar que los vectores que conformaran las columnas de un data table al crearlo desde 0, deben ser del mismo tamaño.


  • A partir de un data frame

Para convertir un dataframe a un datatable, utilizamos la misma función que empleamos para instanciar un data table desde 0.

x <- 1:200
y <- rnorm(200, mean = 70, sd = 10)
df <- data.frame(id = x, age = y ) 
dt <- data.table(df)


  • A partir de un archivo con formato tabular

Utilizamos la función fread(), que lee y convierte el contenido del archivo en un data table.
💡 El formato ideal para leer y escribir datos en un entorno de desarrollo orientado al análisis de conjuntos de datos (como R) es el csv (“valores separados por comas” por sus siglas en inglés).

dt <- fread("./data/pob_censo_2020_inegi.csv", encoding = "UTF-8")

Note que la ruta para leer el archivo comienza en el directorio de trabajo de RStudio y que termina con el nombre completo (incluyendo sufijo) del archivo.

💡 El parámetro enconding de la función fread() permite especificar una codificación de caracteres Unicode. La codificación [UTF-8(https://es.wikipedia.org/wiki/UTF-8) es la que comúnmente se utiliza para la correcta lectura de acentos y otros caracteres especiales en spañol.


También es posible utilizar hipervínculos como ruta de lectura de un archivo.

dt_link <- fread("https://raw.githubusercontent.com/sarahiaguilar/R-4-SocialSci/gh-pages/data/pob_censo_2020_inegi.csv")


La función fread tiene parámetros que facilita la lectura de archivos con formatos más complejos. 💡 Recuerde que para conocer más acerca de una función específica (incluyendo sus parámetros y valores predeterminados), corra “?” + el nombre de la función.

Por ejemplo, si el archivo no contiene un encabezado (nombres de columnas), podemos utilizar el parámetro header para indicarlo, o si el archivo está separado por un caracter distinto a una coma, podemos utilizar el parámetro sep para indicarlo.

dt_txt <- fread("./data/pob_censo_2020_inegi.txt", header = FALSE, sep = ";")


Para archivos xlsx utilizamos la función read_xlsx del paquete readxl. Es necesario indicar como parámetro de esta función el número de hoja que deseamos leer. También, es importante destacar que esta función, a diferencia de la función fread(), no convierte el contenido del archivo en un data table, por lo que es necesario hacer dicha conversión posteriormente.

df_xlsx <- read_xlsx("./data/pob_censo_2020_inegi.xlsx", sheet = 1) # Lee hoja número 1
df_xlsx <- data.table(df_xlsx) # Convierte a data table


Para archivos sav de SPSS o dta de STATA utilizamos funciones del paquete foreign.

# df_spss <- read.spss("example.sav", to.data.frame = TRUE, use.value.labels = FALSE)
# df_stata <- read.dta("example.dta")


3.3. Exportando un data table

Para exportar un data table utilizamos la función write.csv() de R Base, que recibe como parámetro el objeto del data table que deseamos exportar y la ruta para escribir el archivo, que comienza en el directorio de trabajo de RStudio y termina con el nombre completo (incluyendo sufijo) del archivo.

# write.csv(dt, file = "./data/new_pob_censo_2020_inegi.xlsx", row.names = FALSE)

De forma predeterminada, la función write.csv() escribirá el data table con una variable adicional de índice. El parámetro row.names permite definir si queremos o no agregar dicha variable adicional al escribir el data table.


3.4. Conociendo a un data table


Las siguientes funciones nos permiten explorar rápidamente la composición de un data table. Este es un paso crucial para tener un entendimiento general de “cómo luce” el conjunto de datos y qué tipo de procesamiento requeriremos hacer sobre él.

💡 Es buena práctica mantener nuestro ambiente libre de variables que ya no vamos a utilizar activamente. Es posible eliminar variables desde nuestro ambiente desde la ventana de Environment de RStudio o con la función rm() de forma programática.

rm(df, df_xlsx, dt_link, dt_txt, x, y)


Las siguientes funciones nos permiten explorar


La función head() devuelve las primeras 6 observaciones de un data table.

head(dt)
##          entidad_federativa edad hombres mujeres
## 1: Estados Unidos Mexicanos    0  916140  896837
## 2: Estados Unidos Mexicanos    1  967223  942735
## 3: Estados Unidos Mexicanos    2 1031816      NA
## 4: Estados Unidos Mexicanos    3 1060809      NA
## 5: Estados Unidos Mexicanos    4 1101494      NA
## 6: Estados Unidos Mexicanos    5 1106361 1072540


La función tail() devuelve las últimas 6 observaciones de un data table.

tail(dt)
##    entidad_federativa      edad hombres mujeres
## 1:          Zacatecas        95     210     308
## 2:          Zacatecas        96     193     253
## 3:          Zacatecas        97     142     158
## 4:          Zacatecas        98     119     166
## 5:          Zacatecas        99      74     100
## 6:          Zacatecas 100 y más     102     137


Tanto head() como tail(), pueden recibir el argumento adicional n, que indicará cuántas observaciones devolverá.

tail(dt, n=2) # Imprime las 2 últimas observaciones
##    entidad_federativa      edad hombres mujeres
## 1:          Zacatecas        99      74     100
## 2:          Zacatecas 100 y más     102     137


La función colnames() devuelve los nombres de las variables de un data table.

colnames(dt)
## [1] "entidad_federativa" "edad"               "hombres"           
## [4] "mujeres"


La función dim() devuelve un vector de tamaño 2 con las dimensiones del data table. En la primer posición del vector, se devolverá el número de observaciones, y en la segunda posición, el número de variables.

dim(dt)
## [1] 3333    4


La función nrow() devuelve el número de observaciones, y la función ncol(), el número de variables.

nrow(dt)
## [1] 3333


ncol(dt)
## [1] 4


La función str() devuelve el tipo y tamaño de cada vector que compone a un data table A esto se le conoce como la “estructura” de un data frame.

str(dt)
## Classes 'data.table' and 'data.frame':   3333 obs. of  4 variables:
##  $ entidad_federativa: chr  "Estados Unidos Mexicanos" "Estados Unidos Mexicanos" "Estados Unidos Mexicanos" "Estados Unidos Mexicanos" ...
##  $ edad              : chr  "0" "1" "2" "3" ...
##  $ hombres           : int  916140 967223 1031816 1060809 1101494 1106361 1057642 1087091 1140496 1061501 ...
##  $ mujeres           : int  896837 942735 NA NA NA 1072540 1037707 1059203 1093999 1047839 ...
##  - attr(*, ".internal.selfref")=<externalptr>


La función summary() devuelve algunas de las medidas de dispersón de las variables numéricas de un data table e incluso el número de NAs por columna (en caso de que haya).

summary(dt)
##  entidad_federativa     edad              hombres           mujeres       
##  Length:3333        Length:3333        Min.   :     12   Min.   :     28  
##  Class :character   Class :character   1st Qu.:   4157   1st Qu.:   4662  
##  Mode  :character   Mode  :character   Median :  12771   Median :  13578  
##                                        Mean   :  36806   Mean   :  37741  
##                                        3rd Qu.:  26646   3rd Qu.:  27476  
##                                        Max.   :1174026   Max.   :1218303  
##                                                          NA's   :3


Para data tables no muy grandes, podemos utilizar la función View() que nos permite obtener una visualización tabular completa de cómo se ve el conjunto de datos. La visualización desplegada también la podemos obtener dando click sobre el nombre del data table en la venta de Environment de RStudio.

3.5. Renombrando columnas de un data.table

Para simplificar el código, es muy importante asegurarnos que los nombres de columna de nuestro data table sean adecuados (comienzan con una letra, utilizan únicamente letras, números y guiones bajos (_) en lugar de espacios, no utilizar caracteres epeciales, y son nombres cortos, claros y concretos).

setnames() es una función que nos permitirá cambiar uno o varios nombres de columna de un data.table de forma segura.

setnames(dt, old = c("hombres", "mujeres"), new = c("pob_hombres", "pob mujeres"))


colnames(dt)
## [1] "entidad_federativa" "edad"               "pob_hombres"       
## [4] "pob mujeres"

💡 Para sustituir un valor y reemplazarlo por otro valor en un vector, la gsub() resulta muy útil. En contexto, podemos utilizar gsub() para reemplazar un caracter especial que se repita en los nombres de columna de un data table.


setnames(dt,
         old = colnames(dt), 
         new = gsub(" ", "_", colnames(dt))) # Reemplaza espacios por un guión bajo en los nombres de columna del data table


colnames(dt)
## [1] "entidad_federativa" "edad"               "pob_hombres"       
## [4] "pob_mujeres"


3.6. Utilizando i en un data table

💡 Recordemos que la forma general de sintaxis de un data table es DT[i, j, by = k], y textualmente, se leería de la siguiente forma:

  1. Toma DT
  2. Toma el subconjunto de filas i u ordena las filas usando las columnas i
  3. Toma el subconjunto de columnas j o calcula las nuevas columnas j
  4. Agrupando por las columnas k


  • Tomando el subconjunto de filas i

Una única observación basándonos en su índice

dt[41, ]
##          entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos   40     1059322     1146683


Una secuencia de observaciones basándonos en sus índices

dt[41:52, ]
##           entidad_federativa edad pob_hombres pob_mujeres
##  1: Estados Unidos Mexicanos   40     1059322     1146683
##  2: Estados Unidos Mexicanos   41      624905      690335
##  3: Estados Unidos Mexicanos   42      928285      997622
##  4: Estados Unidos Mexicanos   43      768115      850194
##  5: Estados Unidos Mexicanos   44      681677      756448
##  6: Estados Unidos Mexicanos   45      919327      976618
##  7: Estados Unidos Mexicanos   46      718647      790847
##  8: Estados Unidos Mexicanos   47      725378      782495
##  9: Estados Unidos Mexicanos   48      763098      828232
## 10: Estados Unidos Mexicanos   49      685894      751877
## 11: Estados Unidos Mexicanos   50      890709      974467
## 12: Estados Unidos Mexicanos   51      519757      580730


Un conjunto de observaciones no secuenciales basándonos en su índices

dt[c(41, 950, 1556), ]
##          entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos   40     1059322     1146683
## 2:         Ciudad de México   40       84548       93207
## 3:                   México   40      148354      165687


Un conjunto de observaciones basándonos en una condición

dt[entidad_federativa %in% c("Estados Unidos Mexicanos", "Ciudad de México", "México") & edad == 40, ]
##          entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos   40     1059322     1146683
## 2:         Ciudad de México   40       84548       93207
## 3:                   México   40      148354      165687


  • Ordenando las filas usando las columnas i

Con una variable de forma ascendente

head(dt[order(pob_hombres), ])
##     entidad_federativa      edad pob_hombres pob_mujeres
## 1: Baja California Sur        99          12          35
## 2: Baja California Sur 100 y más          18          37
## 3: Baja California Sur        98          21          28
## 4: Baja California Sur        97          22          35
## 5:              Colima        99          24          41
## 6:      Aguascalientes        99          27          50


Con una variable de forma descendente

head(dt[order(-pob_hombres), ])
##          entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos   10     1174026     1125241
## 2: Estados Unidos Mexicanos   18     1172693     1134982
## 3: Estados Unidos Mexicanos   30     1148015     1218303
## 4: Estados Unidos Mexicanos   20     1146232     1161603
## 5: Estados Unidos Mexicanos   12     1146128     1103439
## 6: Estados Unidos Mexicanos    8     1140496     1093999


Con dos variables de forma ascendente

head(dt[order(entidad_federativa, pob_hombres), ])
##    entidad_federativa      edad pob_hombres pob_mujeres
## 1:     Aguascalientes        99          27          50
## 2:     Aguascalientes 100 y más          36          76
## 3:     Aguascalientes        98          39          94
## 4:     Aguascalientes        97          53          85
## 5:     Aguascalientes        96          72         118
## 6:     Aguascalientes        95          93         165


3.7. Utilizando j en un data table

  • Tomando el subconjunto de columnas j

Una única variable basándonos en su índice

head(dt[, 2])
##    edad
## 1:    0
## 2:    1
## 3:    2
## 4:    3
## 5:    4
## 6:    5


Una secuencia de variables basándonos en sus índices

head(dt[, 3:4])
##    pob_hombres pob_mujeres
## 1:      916140      896837
## 2:      967223      942735
## 3:     1031816          NA
## 4:     1060809          NA
## 5:     1101494          NA
## 6:     1106361     1072540


Un conjunto de variables no secuenciales basándonos en su índices

head(dt[, c(1, 3:4)])
##          entidad_federativa pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos      916140      896837
## 2: Estados Unidos Mexicanos      967223      942735
## 3: Estados Unidos Mexicanos     1031816          NA
## 4: Estados Unidos Mexicanos     1060809          NA
## 5: Estados Unidos Mexicanos     1101494          NA
## 6: Estados Unidos Mexicanos     1106361     1072540


Una única variable basándonos en su nombre de columna

head(dt[, .(entidad_federativa)])
##          entidad_federativa
## 1: Estados Unidos Mexicanos
## 2: Estados Unidos Mexicanos
## 3: Estados Unidos Mexicanos
## 4: Estados Unidos Mexicanos
## 5: Estados Unidos Mexicanos
## 6: Estados Unidos Mexicanos


También es posible escribir la instrucción así: dt[, .(entidad_federativa)]. Observe que al ejecutar la instrucción sin el .(), el resultado es un vector.


💡 La función unique() devuelve todos los valores únicos de un vector. Esta función resulta útil para explorar rápidamente los valores únicos de una variable categórica.

unique(dt[, entidad_federativa])
##  [1] "Estados Unidos Mexicanos"        "Aguascalientes"                 
##  [3] "Baja California"                 "Baja California Sur"            
##  [5] "Campeche"                        "Coahuila de Zaragoza"           
##  [7] "Colima"                          "Chiapas"                        
##  [9] "Chihuahua"                       "Ciudad de México"               
## [11] "Durango"                         "Guanajuato"                     
## [13] "Guerrero"                        "Hidalgo"                        
## [15] "Jalisco"                         "México"                         
## [17] "Michoacán de Ocampo"             "Morelos"                        
## [19] "Nayarit"                         "Nuevo León"                     
## [21] "Oaxaca"                          "Puebla"                         
## [23] "Querétaro"                       "Quintana Roo"                   
## [25] "San Luis Potosí"                 "Sinaloa"                        
## [27] "Sonora"                          "Tabasco"                        
## [29] "Tamaulipas"                      "Tlaxcala"                       
## [31] "Veracruz de Ignacio de la Llave" "Yucatán"                        
## [33] "Zacatecas"


Un conjunto de variables no secuenciales basándonos en su nombre de columna.

head(dt[, .(entidad_federativa, pob_hombres, pob_mujeres)]) 
##          entidad_federativa pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos      916140      896837
## 2: Estados Unidos Mexicanos      967223      942735
## 3: Estados Unidos Mexicanos     1031816          NA
## 4: Estados Unidos Mexicanos     1060809          NA
## 5: Estados Unidos Mexicanos     1101494          NA
## 6: Estados Unidos Mexicanos     1106361     1072540

💡 También es posible reordenar las columnas de un conjunto de datos de esta forma.


Esta otra forma es también válida y debe ser utilizada en caso de que los nombres de columnas tengan caracteres especiales.

head(dt[, c("entidad_federativa", "pob_hombres", "pob_mujeres")]) 
##          entidad_federativa pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos      916140      896837
## 2: Estados Unidos Mexicanos      967223      942735
## 3: Estados Unidos Mexicanos     1031816          NA
## 4: Estados Unidos Mexicanos     1060809          NA
## 5: Estados Unidos Mexicanos     1101494          NA
## 6: Estados Unidos Mexicanos     1106361     1072540


  • Calculando las nuevas columnas j

Al calcular una nueva columna en un data table, una iteración por cada fila ocurre de forma implícita.


Calculando nueva variable desde 0

dt[, indice := 1:nrow(dt)]
head(dt)
##          entidad_federativa edad pob_hombres pob_mujeres indice
## 1: Estados Unidos Mexicanos    0      916140      896837      1
## 2: Estados Unidos Mexicanos    1      967223      942735      2
## 3: Estados Unidos Mexicanos    2     1031816          NA      3
## 4: Estados Unidos Mexicanos    3     1060809          NA      4
## 5: Estados Unidos Mexicanos    4     1101494          NA      5
## 6: Estados Unidos Mexicanos    5     1106361     1072540      6


Calculando nueva variable con variables ya existentes

dt[, pob_total := pob_hombres + pob_mujeres]
head(dt)
##          entidad_federativa edad pob_hombres pob_mujeres indice pob_total
## 1: Estados Unidos Mexicanos    0      916140      896837      1   1812977
## 2: Estados Unidos Mexicanos    1      967223      942735      2   1909958
## 3: Estados Unidos Mexicanos    2     1031816          NA      3        NA
## 4: Estados Unidos Mexicanos    3     1060809          NA      4        NA
## 5: Estados Unidos Mexicanos    4     1101494          NA      5        NA
## 6: Estados Unidos Mexicanos    5     1106361     1072540      6   2178901

💡 En R, las operaciones con NA siempre resultan en NA.


Calculando variable con variables ya existentes y condicionales

# Se sobreescribe una variable ya existente (pob_total)
dt[, pob_hombres := ifelse(test = pob_hombres < 0, # ¿La población de hombres en la fila es menor a 0?
                         yes = 0, # Si la condición es verdadera, devuelve 0 
                         no = pob_hombres)] # Si la condición es falsa, devuelve la misma población de hombres en la fila
head(dt)
##          entidad_federativa edad pob_hombres pob_mujeres indice pob_total
## 1: Estados Unidos Mexicanos    0      916140      896837      1   1812977
## 2: Estados Unidos Mexicanos    1      967223      942735      2   1909958
## 3: Estados Unidos Mexicanos    2     1031816          NA      3        NA
## 4: Estados Unidos Mexicanos    3     1060809          NA      4        NA
## 5: Estados Unidos Mexicanos    4     1101494          NA      5        NA
## 6: Estados Unidos Mexicanos    5     1106361     1072540      6   2178901


Para eliminar una variable, esta se debe de igualar al valor NULL.

colnames(dt)
## [1] "entidad_federativa" "edad"               "pob_hombres"       
## [4] "pob_mujeres"        "indice"             "pob_total"


dt[, indice := NULL]
colnames(dt)
## [1] "entidad_federativa" "edad"               "pob_hombres"       
## [4] "pob_mujeres"        "pob_total"


3.8. Utilizando k en un data table

Antes de agrupar por las columnas k, es necesario indicar al menos una operación con una columna j.

  • Operando con las columnas j

Una única operación

dt[entidad_federativa != "Estados Unidos Mexicanos", sum(pob_hombres)]
## [1] 61337196


dt[, .N] # .N es un conteo de observaciones
## [1] 3333


Múltiples operaciones

dt[entidad_federativa == "Estados Unidos Mexicanos", .(sum(pob_hombres), sum(pob_mujeres))]
##          V1 V2
## 1: 61337196 NA


Renombrando las operaciones

dt[entidad_federativa != "Estados Unidos Mexicanos", .(sum_pob_h = sum(pob_hombres), sum_pob_m = sum(pob_mujeres))]
##    sum_pob_h sum_pob_m
## 1:  61337196  64403442


  • Agrupando por las columnas k

Por una única variable

head(dt[, .(sum_pob_h = sum(pob_hombres), sum_pob_m = sum(pob_mujeres)), by = entidad_federativa])
##          entidad_federativa sum_pob_h sum_pob_m
## 1: Estados Unidos Mexicanos  61337196        NA
## 2:           Aguascalientes    695934    728165
## 3:          Baja California   1896493   1864308
## 4:      Baja California Sur    403966    390639
## 5:                 Campeche    454789    469280
## 6:     Coahuila de Zaragoza   1560595   1580017


Por múltiples variables

head(dt[, .(sum_pob_h = sum(pob_hombres), sum_pob_m = sum(pob_mujeres)), by = .(entidad_federativa, edad)])
##          entidad_federativa edad sum_pob_h sum_pob_m
## 1: Estados Unidos Mexicanos    0    916140    896837
## 2: Estados Unidos Mexicanos    1    967223    942735
## 3: Estados Unidos Mexicanos    2   1031816        NA
## 4: Estados Unidos Mexicanos    3   1060809        NA
## 5: Estados Unidos Mexicanos    4   1101494        NA
## 6: Estados Unidos Mexicanos    5   1106361   1072540

En este caso, el resultado a la instrucción anterior luce igual al data table original.


Es posible hacer operaciones de conteo de observaciones aplicando filtros específicos por operación con la función sum(), que recibirá como parámetro el filtro específico.

head(dt[, .(obs_cdmx_edomex = sum(entidad_federativa %in% c("Ciudad de México", "México"))), by = .(edad)])
##    edad obs_cdmx_edomex
## 1:    0               2
## 2:    1               2
## 3:    2               2
## 4:    3               2
## 5:    4               2
## 6:    5               2


3.9. Unión de data tables

Para esta sección, retomamos el inciso 8 del Ejercicio.

dt_lic <- fread("./data/lic_censo_2020_inegi.csv", encoding = "UTF-8")


dt_pob_ags <- dt[entidad_federativa == "Aguascalientes", .(edad, pob_mujeres)]
dt_lic_ags <- dt_lic[ent_fed == "Aguascalientes" & sexo == "Mujeres", .(edad, estudiaron_licenciatura)]


Antes de unir dos data tables, debemos asegurarnos que la variable llave en ambos data tables sea del mismo tipo de dato.

typeof(dt_pob_ags[, edad])
## [1] "character"


typeof(dt_lic_ags[, edad])
## [1] "integer"


dt_pob_ags[, edad := ifelse(edad == "100 y más", yes = "101", no = edad)]
dt_pob_ags[, edad := as.integer(edad)]


Unimos los data tables dt_pob_ags y dt_lic_ags conservando todos los valores del primer data table.

dt_merge <- merge(x = dt_pob_ags, # Primer conjunto de datos
                  y = dt_lic_ags, # Segundo conjunto de datos
                  by.x = "edad", # Nombre de la variable llave en el primer conjunto de datos
                  by.y = "edad", # Nombre de la variable llave en el segundo conjunto de datos
                  all.x = TRUE)


Unimos los data tables dt_pob_ags y dt_lic_ags conservando todos los valores del segundo data table.

dt_merge <- merge(x = dt_pob_ags, # Primer conjunto de datos
                  y = dt_lic_ags, # Segundo conjunto de datos
                  by.x = "edad", # Nombre de la variable llave en el primer conjunto de datos
                  by.y = "edad", # Nombre de la variable llave en el segundo conjunto de datos
                  all.y = TRUE)


Unimos los data tables dt_pob_ags y dt_lic_ags conservando todos los valores de ambos data tables.

dt_merge <- merge(x = dt_pob_ags, # Primer conjunto de datos
                  y = dt_lic_ags, # Segundo conjunto de datos
                  by.x = "edad", # Nombre de la variable llave en el primer conjunto de datos
                  by.y = "edad", # Nombre de la variable llave en el segundo conjunto de datos
                  all = TRUE)


En los ejemplos de unión anteriores solo había una variable llave (edad), pero bien podrían ser más de una. En esos casos, en lugar de mandar en los parámetros by un solo nombre de variable, debemos mandar un vector de nombres de variables.


3.10. Reorientación de data tables

  • De formato largo a ancho

Utilizamos la función dcast(), que recibe como parámetros:

  1. data: el objeto del data table que deseamos reorientar

  2. formula: la fórmula que indica el nombre de las variables que:

    • permaneceran como columnas (a la izquierda del ~ y separadas por un +)

    • serán reorientadas como nuevas columnas (a la derecha del ~ y separadas por un +)

  3. value.var: el nombre de la variable que contiene los valores de las variables que serán reorientadas como nuevas columnas

  4. fun.aggregate (en caso de que se esté haciendo una agrupación de valores): el nombre de la función que se utilizará para agregar los valores de la variable indicada en value.var


Sin agrupación de valores

dt_lic_short <- dcast(data = dt_lic,
                      formula = ent_fed+edad~sexo, 
                      value.var = "estudiaron_licenciatura")
head(dt_lic_short)
##           ent_fed edad Hombres Mujeres
## 1: Aguascalientes    3       0       0
## 2: Aguascalientes    4       0       0
## 3: Aguascalientes    5       0       0
## 4: Aguascalientes    6       0       0
## 5: Aguascalientes    7       0       0
## 6: Aguascalientes    8       0       0


Con agrupación de valores

Observe que si omitimos mencionar una variable (de las que queremos que permanezcan como columnas) del lado izquierdo del ~, entonces se ejecutará una agrupación. Por ello, será necesario emplear el parámetro fun.aggregate.

dt_lic_short <- dcast(data = dt_lic,
                      formula = ent_fed~sexo, 
                      value.var = "estudiaron_licenciatura",
                      fun.aggregate = sum)
head(dt_lic_short)
##                ent_fed Hombres Mujeres
## 1:      Aguascalientes   22427   26099
## 2:     Baja California   53039   60735
## 3: Baja California Sur   10316   12028
## 4:            Campeche   12290   13417
## 5:             Chiapas   51308   54810
## 6:           Chihuahua   52670   61012


  • De formato largo a ancho

Utilizamos la función melt(), que recibe como parámetros:

  1. data: el objeto del data table que deseamos reorientar
  2. id.vars: qué variables permaneceran como columnas
  3. variable.name (opcional): el nuevo nombre de la variable que contendrá los nombres de las variables que serán reorientadas como nuevas filas
  4. vvalue.name (opcional): el nuevo nombre de la variable que contendrá los valores de las variables que serán reorientadas como nuevas filas


dt_lic_long <- melt(data = dt_lic_short, 
                    id.vars = "ent_fed", 
                    variable.name = "sexo",
                    value.name = "estudiaron_lic")
head(dt_lic_long)
##                ent_fed    sexo estudiaron_lic
## 1:      Aguascalientes Hombres          22427
## 2:     Baja California Hombres          53039
## 3: Baja California Sur Hombres          10316
## 4:            Campeche Hombres          12290
## 5:             Chiapas Hombres          51308
## 6:           Chihuahua Hombres          52670


3.11. Manejo de variables categóricas (¡Bonus #1! 😊)

Cuando exportamos conjuntos de datos como data table, R lee no es capaz de identificar de forma predeterminada valores categóricos.

str(dt_lic)
## Classes 'data.table' and 'data.frame':   1408 obs. of  4 variables:
##  $ ent_fed                : chr  "Aguascalientes" "Aguascalientes" "Aguascalientes" "Aguascalientes" ...
##  $ sexo                   : chr  "Hombres" "Hombres" "Hombres" "Hombres" ...
##  $ edad                   : int  3 4 5 6 7 8 9 10 11 12 ...
##  $ estudiaron_licenciatura: int  0 0 0 0 0 0 0 0 0 0 ...
##  - attr(*, ".internal.selfref")=<externalptr> 
##  - attr(*, "index")= int(0) 
##   ..- attr(*, "__sexo__ent_fed")= int [1:1408] 1 2 3 4 5 6 7 8 9 10 ...


En R, para poder identificar una varable categórica como tal, deben ser convertidas en factores. Esta conversión trae muchos beneficios a la hora de preprocesar y visualizar los datos, e incluso construir modelos estadísticos con ellos.

Los factores son variables en R que toman un número limitado de valores diferentes y se almacenan como un vector de valores enteros con un conjunto correspondiente de cadenas de caracteres para usar cuando se muestra el factor.

La función de factor se utiliza para crear un factor. El único parámetro necesario para factorizar es un vector de valores que se devolverá como un vector de valores de factor.

Tanto las variables numéricas como las de cadenas caracteres se pueden convertir en factores, pero los niveles de un factor siempre serán cadenas de caracteres en un orden predeterminado. Los niveles son otro parámetro de la función.

Los niveles de un factor se utilizan cuando se muestran los valores del factor. Puede cambiar estos niveles en el momento de crear un factor pasando un vector con los nuevos valores a través del paraámetro labels.


sex_levels <- c("Hombres", "Mujeres")
sex_labels <- c("h", "m")
sex_var <- dt_lic[, sexo]
sex_factor <- factor(x = sex_var, levels = sex_levels, labels = sex_labels)


dt_lic[, sexo := sex_factor]
str(dt_lic)
## Classes 'data.table' and 'data.frame':   1408 obs. of  4 variables:
##  $ ent_fed                : chr  "Aguascalientes" "Aguascalientes" "Aguascalientes" "Aguascalientes" ...
##  $ sexo                   : Factor w/ 2 levels "h","m": 1 1 1 1 1 1 1 1 1 1 ...
##  $ edad                   : int  3 4 5 6 7 8 9 10 11 12 ...
##  $ estudiaron_licenciatura: int  0 0 0 0 0 0 0 0 0 0 ...
##  - attr(*, ".internal.selfref")=<externalptr> 
##  - attr(*, "index")= int(0)


3.12. Manejo de fechas (¡Bonus #2! 😎)

Lubridate es un paquete de R que facilita el trabajo con fechas y horas.

Una fecha-hora es un punto en la línea de tiempo, almacenado como el número de segundos desde 1970-01-01 00:00:00 UTC en ese mismo formato estandarizado.

as_datetime(1658736000)
## [1] "2022-07-25 08:00:00 UTC"


Una fecha es un día almacenado como el número de días desde 1970-01-01.

as_date(19198)
## [1] "2022-07-25"


  • Formateando

Lograr que R acepte que nuestros datos contienen las fechas-horas que nosotros creemos que contienen puede ser complicado. Lubridate simplifica eso.

Identifique el orden en que aparecen el año, el mes, el día, la hora y los minutos en sus fechas-horas y ordene las letras “y” (año), “m” (mes), “d” (día), “h” (hora) y “m” (minuto) en el mismo orden. El resultado será el nombre de la función en lubridate que le dará el formato correcto a sus fechas.


Año, mes y día

ymd("2022/07/25")
## [1] "2022-07-25"


Día, mes y año

dmy("25-07-2022") 
## [1] "2022-07-25"


Día, mes y año

mdy("07-25-2022")
## [1] "2022-07-25"


También funciona si hacen elemento o ceros, o si tiene otros separadores distintos al -.

ym("2022/07")
## [1] "2022-07-01"


ymd("2022-7-5")
## [1] "2022-07-05"


ymd("2022.07.25")
## [1] "2022-07-25"


Para hora y minutos, se utiliza _hm().

ymd_hm("2022-07-25 8:00")
## [1] "2022-07-25 08:00:00 UTC"


  • Accediendo a componentes

Use las función de acceso para obtener un componente. Dichas funciones de acceso tienen el nombre del componente.

year("2022-07-25 8:00")
## [1] 2022


month("2022-07-25 8:00")
## [1] 7


day("2022-07-25 8:00")
## [1] 25


🏋 Ejercicio

  1. Cree un nuevo proyecto.

  2. Cree una nueva carpeta dentro del proyecto que se llame “datos” y ubique dentro de esta a los archivos pob_censo_2020_inegi.txt y lic_censo_2020_inegi.csv.

  3. Cree una nueva carpeta dentro del proyecto que se llame “scripts” y cree un nuevo script dentro de esta.

  4. En el script, cargue el conjunto de datos del archivo pob_censo_2020_inegi.txt a R como data table.

  5. En el script, utilizando el data table, programe el código correspondiente para resolver lo siguiente:

    5.1. Asigne nuevos nombres de columnas a cada variable.

    5.2. Verifique que haya el mismo número de observaciones por cada entidad federativa.

    5.3. Ubique las observaciones y variables que contienen NAs y reempláce los NAs por un valor que considere pertinente.

    5.4. Responda: ¿cuál es la entidad federativa cuya relación hombres-mujeres es la más alta a nivel nacional? La relación hombres-mujeres refiere a cuántos hombres hay por cada mujer en la entidad federativa).

    5.5. Cree un nuevo data table con la población total de mujeres entre 18 y 65 años por región geográfica y guárdelo en un nuevo archivo csv dentro de la carpeta “datos” del proyecto. Puede consultar las entidades federativas que conforman cada región geográfica en el Glosario del INEGI.

    5.6. Cree un nuevo data table con la población total de 18 años por entidad federativa y en él cree una nueva variable que refiera al porcentaje que representa la población de 18 años de cada entidad federativa de la población total de 18 años a nivel nacional.

    5.7. Responda: ¿cuál es la media de edad a nivel nacional?

  6. Cree un segundo script dentro de la carpeta “scripts”.

  7. En este segundo script, cargue los conjuntos de datos de los archivos pob_censo_2020_inegi.txt y lic_censo_2020_inegi.csv a R como data tables.

  8. En este segundo script, utilizando cada data table en donde corresponda, programe el código correspondiente para resolver lo siguiente:

    8.1. Cree un nuevo data table con la población total que estudiaron una licenciatura (o equivalente) por entidad federativa, edad y sexo, en donde la entidad federativa y la edad tienen formato largo y el sexo tiene formato ancho.

    8.2. Cree un nuevo data table con dos variables: una que refiera al porcentaje que representa la población total de mujeres que estudiaron una licenciatura (o equivalente) de la población total de mujeres por entidad federativa, y otra que refiera al porcentaje que representa la población total de hombres que estudiaron una licenciatura (o equivalente) de la población total de hombres por entidad federativa.