datos <- read.csv("datos_MOLEC_clean.csv", stringsAsFactors = FALSE)
cat("Filas:", nrow(datos), " Columnas:", ncol(datos), "\n")
## Filas: 9986  Columnas: 8
print(names(datos))
## [1] "year"                  "nivel_aprobado"        "condicion_actividad"  
## [4] "libros_origen"         "internet_motivo"       "no_lectura_motivo"    
## [7] "libros_gasto_num"      "libros_leidos_12m_num"
str(datos)
## 'data.frame':    9986 obs. of  8 variables:
##  $ year                 : int  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 ...
##  $ nivel_aprobado       : int  2 3 3 7 6 3 6 3 2 2 ...
##  $ condicion_actividad  : int  1 7 1 1 7 1 1 1 1 8 ...
##  $ libros_origen        : int  2 0 0 2 2 0 0 0 0 2 ...
##  $ internet_motivo      : chr  "4" "4" "0" "4" ...
##  $ no_lectura_motivo    : chr  "0" "0" "3" "0" ...
##  $ libros_gasto_num     : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ libros_leidos_12m_num: int  1 0 0 2 2 0 0 0 0 1 ...
porc_nulos <- sapply(datos, function(x) mean(is.na(x))*100)
print(round(porc_nulos, 2))
##                  year        nivel_aprobado   condicion_actividad 
##                     0                     0                     0 
##         libros_origen       internet_motivo     no_lectura_motivo 
##                     0                     0                     0 
##      libros_gasto_num libros_leidos_12m_num 
##                     0                     0
dup_count <- sum(duplicated(datos))
cat("Duplicados:", dup_count, "\n")
## Duplicados: 6154
datos <- datos[!duplicated(datos), ]

es_texto <- sapply(datos, is.character)
datos[es_texto] <- lapply(datos[es_texto], function(x) trimws(tolower(x)))

if ("nivel" %in% names(datos)) datos$nivel[datos$nivel %in% c(99)] <- NA
if ("p7_3"  %in% names(datos)) datos$p7_3[datos$p7_3 %in% c(0, 999999)] <- NA
if ("p4"    %in% names(datos)) datos$p4[datos$p4 == 0] <- NA

#write.csv(datos, "datos_limpios.csv", row.names = FALSE)
diccionario <- data.frame(
  variable    = names(datos),
  tipo        = sapply(datos, function(x) class(x)[1]),
  porc_nulos  = round(colMeans(is.na(datos)) * 100, 2),
  stringsAsFactors = FALSE
)

desc <- c(
  year = "Año del dato.",
  nivel_aprobado = "Nivel de escolaridad. ¿Hasta qué año o grado aprobó en la escuela?.",
  condicion_actividad = "Condición de actividad: ¿La semana pasada...?",
  libros_origen = "¿El (Los) libro(s) que leyó fue(ron) ...? (provenientes de).",
  internet_motivo = "Motivo principal por el que leyó páginas de internet, foros o blogs.",
  no_lectura_motivo = "Motivo principal por el que no lee los materiales de lectura mencionados.",
  libros_gasto_num = "Aproximadamente, ¿cuánto gastó?",
  libros_leidos_12m_num = "¿Cuántos libros leyó en los últimos doce meses?"
)

View(diccionario)

diccionario$descripcion <- desc[diccionario$variable]
diccionario$descripcion[is.na(diccionario$descripcion)] <- ""
#write.csv(diccionario, "diccionario_variables.csv", row.names = FALSE)
tabla <- datos[,c(2,7,8)]
nums <- Filter(is.numeric, tabla)
res_num <- t(sapply(nums, function(x) c(
  n = sum(!is.na(x)),
  media = mean(x, na.rm=TRUE),
  mediana = median(x, na.rm=TRUE),
  min = min(x, na.rm=TRUE),
  max = max(x, na.rm=TRUE),
  rango_medio = (min(x, na.rm=TRUE) + max(x, na.rm=TRUE))/2,
  sd = sd(x, na.rm=TRUE),
  coef_var = ifelse(mean(x,na.rm=TRUE)==0, NA, sd(x,na.rm=TRUE)/mean(x,na.rm=TRUE)),
  q25 = quantile(x, .25, na.rm=TRUE),
  q75 = quantile(x, .75, na.rm=TRUE)
)))
round(res_num, 3)
##                          n    media mediana min    max rango_medio        sd
## nivel_aprobado        3832    5.554       6   0     99        49.5     6.936
## libros_gasto_num      3832 6660.278       0   0 999999    499999.5 78904.063
## libros_leidos_12m_num 3832    3.178       2   0     99        49.5     5.964
##                       coef_var q25.25% q75.75%
## nivel_aprobado           1.249       3       7
## libros_gasto_num        11.847       0     300
## libros_leidos_12m_num    1.877       0       4
cats <- datos[,c(1,3,4,5,6)]
res_cat <- lapply(cats, function(v){
  tb <- table(v, useNA="ifany")
  list(freq = tb, prop = round(prop.table(tb), 4))
})
res_cat
## $year
## $year$freq
## v
## 2020 2021 2022 2023 2024 
##  750  787  791  758  746 
## 
## $year$prop
## v
##   2020   2021   2022   2023   2024 
## 0.1957 0.2054 0.2064 0.1978 0.1947 
## 
## 
## $condicion_actividad
## $condicion_actividad$freq
## v
##    1    2    3    4    5    6    7    8    9   10   99 
## 1927   48   87  189   31  297  748  424   32   48    1 
## 
## $condicion_actividad$prop
## v
##      1      2      3      4      5      6      7      8      9     10     99 
## 0.5029 0.0125 0.0227 0.0493 0.0081 0.0775 0.1952 0.1106 0.0084 0.0125 0.0003 
## 
## 
## $libros_origen
## $libros_origen$freq
## v
##    0    1    2    3 
##  985  537  892 1418 
## 
## $libros_origen$prop
## v
##      0      1      2      3 
## 0.2570 0.1401 0.2328 0.3700 
## 
## 
## $internet_motivo
## $internet_motivo$freq
## v
##    0    1    2    3    4    5 otro 
## 1796  328  281  721  636   37   33 
## 
## $internet_motivo$prop
## v
##      0      1      2      3      4      5   otro 
## 0.4687 0.0856 0.0733 0.1882 0.1660 0.0097 0.0086 
## 
## 
## $no_lectura_motivo
## $no_lectura_motivo$freq
## v
##    0    1    2    3    4    5 otro 
## 3329  128   95  123   28  110   19 
## 
## $no_lectura_motivo$prop
## v
##      0      1      2      3      4      5   otro 
## 0.8687 0.0334 0.0248 0.0321 0.0073 0.0287 0.0050
library(tidyverse)
## Warning: package 'ggplot2' was built under R version 4.4.3
## Warning: package 'purrr' was built under R version 4.4.3
## Warning: package 'lubridate' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── 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
library(forcats)
library(scales)
## Warning: package 'scales' was built under R version 4.4.3
## 
## Adjuntando el paquete: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
theme_set(theme_minimal(base_size = 12))
datos <- datos %>% mutate(
  year = as.integer(year),                       
  lee_algo = libros_leidos_12m_num > 0           
)
datos %>%
  filter(year %in% c(2020, 2022, 2024)) %>% 
  group_by(year) %>%
  summarise(prom_libros = mean(libros_leidos_12m_num, na.rm = TRUE), .groups = "drop") %>%
  ggplot(aes(year, prom_libros)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  geom_text(aes(label = round(prom_libros, 2)),
            vjust = -0.6, size = 3) +             
  scale_y_continuous(expand = expansion(mult = c(0.02, 0.12))) +  
  labs(title = "Promedio de libros leídos por año",
       x = "Año", y = "Libros (promedio)")

datos %>%
  filter(year %in% c(2020, 2022, 2024)) %>% 
  group_by(year) %>%
  summarise(pct_lee = mean(lee_algo, na.rm = TRUE)) %>%
  ggplot(aes(year, pct_lee)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  geom_text(aes(label = round(pct_lee, 4)),
            vjust = -0.6, size = 3) + 
  scale_y_continuous(labels = percent_format(accuracy = 1.2)) +
  labs(title = "% que leyó ≥1 libro en los últimos 12 meses",
       x = "Año", y = "Porcentaje")

# 3) Motivos para leer en internet (barras horizontales, ordenado)
datos <- datos %>%
  filter(year %in% c(2020, 2022, 2024)) %>% 
  mutate(internet_motivo = recode(as.character(internet_motivo),
    "1" = "Trabajo",
    "2" = "Estudio",
    "3" = "Cultura General/estar al día",
    "4" = "Gusto/entretenimiento",
    .default = "Otro"
  ))
datos %>%
  filter(!is.na(internet_motivo)) %>%
  count(internet_motivo, sort = TRUE) %>%
  mutate(internet_motivo = fct_reorder(internet_motivo, n)) %>%
  ggplot(aes(x = internet_motivo, y = n, fill=internet_motivo)) +
  geom_text(aes(label = round(n, 4)),
            vjust = -0.6, size = 3) +
  geom_col() +
  coord_flip() +
  labs(title = "Motivos para leer en internet",
       x = NULL, y = "Frecuencia")

datos <- datos %>%
  filter(year %in% c(2020, 2022, 2024)) %>% 
  mutate(no_lectura_motivo = recode(as.character(no_lectura_motivo),
    "1" = "Falta interés/gusto",
    "2" = "Prefiere otras actividades",
    "3" = "Falta de tiempo",
    "4" = "Falta de dinero",
    "5" = "Problemas de salud",
    "6" = "otro",
    .default = "pase"
  ))

datos %>%
  filter(!is.na(no_lectura_motivo)) %>%
  count(no_lectura_motivo, sort = TRUE) %>%
  mutate(no_lectura_motivo = fct_reorder(no_lectura_motivo, n)) %>%
  ggplot(aes(x = no_lectura_motivo, y = n, fill= no_lectura_motivo)) +
  geom_text(aes(label = round(n, 4)),
            vjust = -0.6, size = 3) +
  geom_col() +
  coord_flip() +
  labs(title = "Motivos para NO leer",
       x = NULL, y = "Frecuencia")

datos %>%
  filter(no_lectura_motivo != "pase") %>%
  count(no_lectura_motivo) %>%
  mutate(no_lectura_motivo = fct_reorder(no_lectura_motivo, n)) %>%
  ggplot(aes(no_lectura_motivo, n, fill = no_lectura_motivo)) +
  geom_text(aes(label = round(n, 4)),
            vjust = -0.6, size = 3) +
  geom_col() + coord_flip() +
  labs(title = "Motivos para NO leer (sin ‘Otro’)", x = NULL, y = "Frecuencia")

datos %>%
  filter(!is.na(internet_motivo), !is.na(year)) %>%
  group_by(year, internet_motivo) %>%
  summarise(n = n(), .groups = "drop") %>%
  group_by(year) %>%
  mutate(p = n / sum(n)) %>%
  ggplot(aes(x = factor(year), y = p, fill = internet_motivo)) +
  geom_text(aes(label = round(n, 4)),
            vjust = -0.6, size = 3) +
  geom_col() +
  scale_y_continuous(labels = percent_format()) +
  labs(title = "% de motivos para leer internet por año",
       x = "Año", y = "Proporción", fill = "Motivo") +
  guides(fill = guide_legend(ncol = 2))

datos <- datos %>%
  mutate(libros_origen = recode(as.character(libros_origen),
    "1" = "Comprados",
    "2" = "Prestados",
    "3" = "Biblioteca",
    "4" = "Digital",
    .default = "Otro"
  ))

datos %>%
  filter(!is.na(libros_origen)) %>%
  count(libros_origen, sort = TRUE) %>%
  mutate(libros_origen = fct_reorder(libros_origen, n)) %>%
  ggplot(aes(libros_origen, n,fill=libros_origen)) +
  geom_text(aes(label = round(n, 4)),
            vjust = -0.6, size = 3) +
  geom_col() +
  coord_flip() +
  labs(title = "Origen de los libros leídos", x = NULL, y = "Frecuencia")

datos %>%
  filter(!is.na(libros_origen)) %>%
  mutate(libros_origen = fct_infreq(libros_origen)) %>%
  ggplot(aes(x = libros_origen, y = libros_leidos_12m_num,fill=libros_origen)) +
  geom_col() +
  coord_flip() +
  labs(title = "Libros leídos por origen", x = NULL, y = "Libros en 12 meses")

datos <- datos %>%
  mutate(nivel_aprobado = recode(as.character(nivel_aprobado),
    "0" = "Ninguno",
    "1" = "Preescolar",
    "2" = "Primaria",
    "3" = "Secundaria",
    "4" = "Preparatoria",
    "5" = "Normal básica",
    "6" = "Carrera técnica",
    "7" = "Profesional",
    "8" = "Maestría",
    "9" = "Doctorado",
    "99" = "No sabe",
    .default = "Otro"
  ))

datos %>%
  filter(!is.na(nivel_aprobado)) %>%
  mutate(nivel_aprobado = fct_infreq(nivel_aprobado)) %>%
  ggplot(aes(nivel_aprobado, libros_leidos_12m_num,fill=nivel_aprobado)) +
  geom_text(aes(label = round(libros_leidos_12m_num, 4)),
            vjust = -0.6, size = 3) +
  geom_col() +
  coord_flip() +
  labs(title = "Libros leídos por nivel educativo",
       x = "Nivel aprobado", y = "Libros en 12 meses")

cor.test(datos$libros_gasto_num, datos$libros_leidos_12m_num, use="complete.obs")
## 
##  Pearson's product-moment correlation
## 
## data:  datos$libros_gasto_num and datos$libros_leidos_12m_num
## t = -0.27761, df = 2285, p-value = 0.7813
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.04678427  0.03518896
## sample estimates:
##          cor 
## -0.005807411
cor.test(datos$libros_gasto_num, datos$libros_leidos_12m_num, method="spearman", use="complete.obs")
## Warning in cor.test.default(datos$libros_gasto_num,
## datos$libros_leidos_12m_num, : Cannot compute exact p-value with ties
## 
##  Spearman's rank correlation rho
## 
## data:  datos$libros_gasto_num and datos$libros_leidos_12m_num
## S = 1265241221, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.3653619
datos%>%
  group_by(year) %>%
  summarise(rho = cor(libros_gasto_num, libros_leidos_12m_num,
                      method="spearman", use="complete.obs"))
## # A tibble: 3 × 2
##    year   rho
##   <int> <dbl>
## 1  2020 0.363
## 2  2022 0.338
## 3  2024 0.397
ggplot(datos, aes(x = libros_gasto_num, y = libros_leidos_12m_num)) +
  geom_point(alpha=.25) +
  scale_x_continuous(trans = "log1p") +
  labs(title="Gasto vs Libros (escala log1p)", x="Gasto (log1p)", y="Libros en 12m")

datos <- datos %>%
  mutate(condicion_actividad = recode(as.character(condicion_actividad),
    "1" = "trabajo para obtener ingresos",
    "2" = "trabajo sin pago",
    "3" = "tenía trabajo",
    "4" = "busca trabajo",
    "5" = "espera de solicitud de trabajo",
    "6" = "estudiante",
    "7" = "quehaceres del hogar",
    "8" = "jubilado(a)/pensionado(a)",
    "9" = "incapacitado(a)",
    "10" = "Otra situación",
    "99" = "No especificado",
    .default = "Otro"
  ))

datos %>%
  filter(!is.na(condicion_actividad)) %>%
  group_by(condicion_actividad) %>%
  summarise(pct = mean(lee_algo, na.rm = TRUE)) %>%
  mutate(condicion_actividad = fct_reorder(condicion_actividad, pct)) %>%
  ggplot(aes(condicion_actividad, pct, fill=condicion_actividad)) +
  geom_col() +
  geom_text(aes(label = percent(pct, 1)), hjust = -0.05, size = 3.5) +
  coord_flip(clip = "off") +
  scale_y_continuous(labels = percent_format(), expand = expansion(mult = c(0, .1))) +
  labs(title = "% que leyó ≥1 libro por condición de actividad",
       x = NULL, y = "Porcentaje")

datos %>%
  ggplot(aes(libros_leidos_12m_num)) +
  geom_histogram(bins = 30) +
  facet_wrap(~ year, scales = "free_y") +
  labs(title = "Distribución de libros leídos por año",
       x = "Libros en 12 meses", y = "Frecuencia")

datos %>%
  filter(!is.na(libros_origen)) %>%
  group_by(year, libros_origen) %>%
  summarise(media = mean(libros_leidos_12m_num, na.rm = TRUE), .groups = "drop") %>%
  ggplot(aes(x = factor(year), y = media, fill = libros_origen)) +
  geom_text(aes(label = round(media, 4)),
            vjust = -0.6, size = 3) +
  geom_col(position = position_dodge(width = .75)) +
  labs(title = "Libros promedio por año y origen",
       x = "Año", y = "Libros (promedio)", fill = "Origen")

res_nivel <- datos%>%
  group_by(nivel_aprobado) %>%
  summarise(
    n = n(),
    pct_lee = mean(lee_algo, na.rm=TRUE)*100,
    media_lectores   = mean(libros_leidos_12m_num[lee_algo], na.rm=TRUE),
    mediana_lectores = median(libros_leidos_12m_num[lee_algo], na.rm=TRUE)
  )
res_nivel
## # A tibble: 11 × 5
##    nivel_aprobado      n pct_lee media_lectores mediana_lectores
##    <chr>           <int>   <dbl>          <dbl>            <dbl>
##  1 Carrera técnica   194    66.0           3.05                2
##  2 Doctorado          35    91.4          10.6                 4
##  3 Maestría          148    85.8           5.41                4
##  4 Ninguno            52    17.3           1.22                1
##  5 No sabe            10     0           NaN                  NA
##  6 Normal básica      36    50             3.5                 2
##  7 Preescolar          2     0           NaN                  NA
##  8 Preparatoria      442    77.8           3.92                3
##  9 Primaria          236    58.5           3.46                2
## 10 Profesional       783    87.2           4.90                3
## 11 Secundaria        349    67.6           3.39                2
res_act <- datos %>%
  group_by(condicion_actividad) %>%
  summarise(
    n = n(),
    pct_lee = mean(lee_algo, na.rm=TRUE)*100,
    media_lectores   = mean(libros_leidos_12m_num[lee_algo], na.rm=TRUE),
    mediana_lectores = median(libros_leidos_12m_num[lee_algo], na.rm=TRUE)
  )
res_act
## # A tibble: 11 × 5
##    condicion_actividad                n pct_lee media_lectores mediana_lectores
##    <chr>                          <int>   <dbl>          <dbl>            <dbl>
##  1 No especificado                    1   100             1                 1  
##  2 Otra situación                    31    32.3           3.6               2  
##  3 busca trabajo                     91    47.3           3.65              3  
##  4 espera de solicitud de trabajo    18    38.9           4.14              5  
##  5 estudiante                       178    88.8           5.04              3.5
##  6 incapacitado(a)                   14    14.3           2                 2  
##  7 jubilado(a)/pensionado(a)        254    65.7           4.08              2  
##  8 quehaceres del hogar             444    68.2           3.50              2  
##  9 tenía trabajo                     46    45.7           5.57              2  
## 10 trabajo para obtener ingresos   1179    83.8           4.59              3  
## 11 trabajo sin pago                  31    48.4           3.27              3
ggplot(datos, aes(nivel_aprobado, libros_leidos_12m_num, fill=nivel_aprobado)) +
  geom_boxplot(outlier.alpha=.3) + coord_flip() +
  labs(title="Libros en 12m por nivel educativo", x=NULL, y="Libros en 12 meses")

ggplot(datos, aes(condicion_actividad, libros_leidos_12m_num,fill=condicion_actividad)) +
  geom_boxplot(outlier.alpha=.3) + coord_flip() +
  labs(title="Libros en 12m por condición de actividad", x=NULL, y="Libros en 12 meses")

datos %>%
  group_by(nivel_aprobado) %>%
  summarise(pct = mean(lee_algo, na.rm=TRUE)) %>%
  ggplot(aes(fct_reorder(nivel_aprobado, pct), pct,fill=nivel_aprobado)) +
  geom_col() +
  geom_text(aes(label=percent(pct,1)), hjust=-0.05, size=3.5) +
  coord_flip(clip="off") +
  labs(title="% que leyó ≥1 libro por nivel educativo", x=NULL, y="Porcentaje")

datos %>%
  group_by(condicion_actividad) %>%
  summarise(pct = mean(lee_algo, na.rm=TRUE)) %>%
  ggplot(aes(fct_reorder(condicion_actividad, pct), pct,fill=condicion_actividad)) +
  geom_col() +
  geom_text(aes(label=percent(pct,1)), hjust=-0.05, size=3.5) +
  coord_flip(clip="off") +
  labs(title="% que leyó ≥1 libro por condición de actividad", x=NULL, y="Porcentaje")

datos %>%
  group_by(condicion_actividad) %>%
  filter(condicion_actividad != "No especificado") %>%
  summarise(pct = mean(lee_algo, na.rm=TRUE)) %>%
  ggplot(aes(fct_reorder(condicion_actividad, pct), pct,fill=condicion_actividad)) +
  geom_col() +
  geom_text(aes(label=percent(pct,1)), hjust=-0.05, size=3.5) +
  coord_flip(clip="off") +
  labs(title="% que leyó ≥1 libro por condición de actividad", x=NULL, y="Porcentaje")