library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(forcats)
library(stringr)
library(scales)
library(knitr)
library(kableExtra)
library(patchwork)
# ── Paleta de azules ─────────────────────────────────────────────
azul1 <- "#084594"
azul2 <- "#2171B5"
azul3 <- "#4292C6"
azul4 <- "#6BAED6"
azul5 <- "#9ECAE1"
azul6 <- "#C6DBEF"
azul7 <- "#DEEBF7"

escala_blues <- c(azul1, azul2, azul3, azul4, azul5, azul6, azul7)

# Colores por contexto: Cataluña (azul oscuro), España resto (azul claro), Total (navy)
col_ctx <- c("Cataluña" = azul2, "España (resto)" = azul5, "Total" = azul1)

tema_epjg <- theme_minimal(base_size = 12) +
  theme(
    plot.title       = element_text(face = "bold", colour = azul1, size = 14),
    plot.subtitle    = element_text(colour = azul2, size = 11),
    axis.title       = element_text(colour = azul1),
    axis.text        = element_text(colour = "#333333"),
    legend.position  = "bottom",
    legend.title     = element_text(colour = azul1, face = "bold"),
    panel.grid.major = element_line(colour = "#e8f0f7"),
    panel.grid.minor = element_blank(),
    strip.text       = element_text(face = "bold", colour = azul1),
    plot.caption     = element_text(colour = "#888888", size = 9)
  )
ruta_cat <- read_excel("Cataluña Professió Docent i Justícia Global (1-538).xlsx")
ruta_esp <- read_excel("ESPAÑA Profesión Docente y Justicia Global (2)(1-483).xlsx")
raw_cat  <- ruta_cat
raw_esp  <- ruta_esp
# ── Funciones de limpieza ─────────────────────────────────────────
limpiar_tipologia <- function(x) {
  x <- str_trim(x)
  case_when(
    str_detect(x, regex("rural|poble",          ignore_case = TRUE)) ~ "Rural",
    str_detect(x, regex("urban|ciudad|ciutat",  ignore_case = TRUE)) ~ "Urbana",
    str_detect(x, regex("Institut|instituto|IES|IFE", ignore_case = TRUE)) ~ "Instituto/IES",
    str_detect(x, regex("complexit|complexa|complejidad|alta", ignore_case = TRUE)) ~ "Alta complejidad",
    TRUE ~ x
  )
}

limpiar_ambito <- function(x) {
  x <- str_trim(x)
  case_when(
    str_detect(x, regex("infantil",                           ignore_case = TRUE)) ~ "Ed. Infantil",
    str_detect(x, regex("primàr|primari|primaria",            ignore_case = TRUE)) ~ "Ed. Primaria",
    str_detect(x, regex("secundàr|secundari|secundaria",      ignore_case = TRUE)) ~ "Ed. Secundaria",
    str_detect(x, regex("batxiller|bachiller",                ignore_case = TRUE)) ~ "Bachillerato",
    str_detect(x, regex("formació professional|formación profesional", ignore_case = TRUE)) ~ "FP",
    str_detect(x, regex("adults|adultos",                     ignore_case = TRUE)) ~ "Ed. Adultos",
    str_detect(x, regex("especial",                           ignore_case = TRUE)) ~ "Ed. Especial",
    TRUE ~ x
  )
}

# ── CATALUÑA ──────────────────────────────────────────────────────
cat_df <- raw_cat %>%
  select(
    id = 1, edad = 8, genero = 9, formacion = 10, experiencia = 14,
    ambito = 15, regimen = 17, tipologia = 18,
    con_propio = 19, con_centro = 20, importancia = 21,
    sup_ecologismo = 23, sup_pacifismo = 24, sup_feminismo = 25,
    sup_der_hum = 26, sup_lgtbiq = 27, sup_antirac = 28, sup_anticap = 29,
    imp_genero = 30, imp_paz = 31, imp_derechos = 32, imp_just_eco = 33,
    imp_just_amb = 34, imp_intercult = 35, imp_bienestar = 36,
    imp_rel_educ = 37, imp_digital = 38, imp_tecnologia = 39,
    trab_genero = 40, trab_paz = 41, trab_derechos = 42, trab_just_eco = 43,
    trab_just_amb = 44, trab_intercult = 45, trab_bienestar = 46,
    trab_rel_educ = 47, trab_digital = 48, trab_tecnologia = 49,
    formato_pref = 73
  ) %>%
  mutate(
    contexto  = "Cataluña",
    genero    = case_when(
      genero == "Femení"  ~ "Femenino",
      genero == "Masculí" ~ "Masculino",
      TRUE                ~ "No informa"
    ),
    formacion = case_when(
      str_detect(formacion, "Doctorat")                       ~ "Doctorado",
      str_detect(formacion, "Màster|Postgrau")                ~ "Máster/Postgrado",
      str_detect(formacion, "Grau|Llicenciatura|Diplomatura") ~ "Grado/Licenciatura",
      TRUE                                                    ~ "No informa"
    ),
    regimen   = str_trim(regimen),
    regimen   = case_when(
      str_detect(regimen, "úblic")  ~ "Público",
      str_detect(regimen, "oncert") ~ "Concertado",
      TRUE                         ~ regimen
    ),
    tipologia   = limpiar_tipologia(tipologia),
    ambito      = limpiar_ambito(ambito),
    edad        = as.numeric(edad),
    edad        = ifelse(edad > 100, NA_real_, edad),
    experiencia = str_replace_all(str_trim(as.character(experiencia)),
                                  c("anys" = "años", "Més de" = "Más de")),
    across(c(con_propio, con_centro, importancia,
             sup_ecologismo:sup_anticap,
             imp_genero:imp_tecnologia), as.numeric)
  )

# ── ESPAÑA (RESTO) ────────────────────────────────────────────────
esp_df <- raw_esp %>%
  select(
    id = 1, edad = 8, genero = 9, formacion = 10, experiencia = 14,
    ambito = 15, ccaa = 17, regimen = 18, tipologia = 19,
    con_propio = 20, con_centro = 21, importancia = 22,
    sup_ecologismo = 24, sup_pacifismo = 25, sup_feminismo = 26,
    sup_der_hum = 27, sup_lgtbiq = 28, sup_antirac = 29, sup_anticap = 30,
    imp_genero = 31, imp_paz = 32, imp_derechos = 33, imp_just_eco = 34,
    imp_just_amb = 35, imp_intercult = 36, imp_bienestar = 37,
    imp_rel_educ = 38, imp_digital = 39, imp_tecnologia = 40,
    trab_genero = 41, trab_paz = 42, trab_derechos = 43, trab_just_eco = 44,
    trab_just_amb = 45, trab_intercult = 46, trab_bienestar = 47,
    trab_rel_educ = 48, trab_digital = 49, trab_tecnologia = 50,
    formato_pref = 74
  ) %>%
  mutate(
    contexto  = "España (resto)",
    genero    = case_when(
      genero == "Femenino"  ~ "Femenino",
      genero == "Masculino" ~ "Masculino",
      TRUE                  ~ "No informa"
    ),
    formacion = case_when(
      str_detect(formacion, "Doctorado")                      ~ "Doctorado",
      str_detect(formacion, "Máster|Postgrado")               ~ "Máster/Postgrado",
      str_detect(formacion, "Grado|Licenciatura|Diplomatura") ~ "Grado/Licenciatura",
      TRUE                                                    ~ "No informa"
    ),
    regimen   = str_trim(regimen),
    regimen   = case_when(
      str_detect(regimen, "úblico")    ~ "Público",
      str_detect(regimen, "oncertado") ~ "Concertado",
      str_detect(regimen, "rivado")    ~ "Privado",
      TRUE                            ~ regimen
    ),
    tipologia = limpiar_tipologia(tipologia),
    ambito    = limpiar_ambito(ambito),
    edad      = as.numeric(edad),
    across(c(con_propio, con_centro, importancia,
             sup_ecologismo:sup_anticap,
             imp_genero:imp_tecnologia), as.numeric)
  )

# ── Dataset combinado ─────────────────────────────────────────────
cols_comunes <- intersect(names(cat_df), names(esp_df))
df <- bind_rows(
  cat_df %>% select(all_of(cols_comunes)),
  esp_df %>% select(all_of(cols_comunes))
) %>%
  mutate(
    contexto    = factor(contexto, levels = c("Cataluña", "España (resto)")),
    experiencia = factor(
      str_replace_all(str_trim(experiencia),
                      c("anys" = "años", "Més de" = "Más de")),
      levels = c("0 a 5 años", "6 a 10 años", "11 a 15 años",
                 "16 a 20 años", "21 a 25 años", "26 a 30 años",
                 "31 a 35 años", "Más de 35 años")
    )
  )

# ── Dataset con filas "Total" para gráficos ───────────────────────
# Se duplican todas las filas con contexto = "Total" para que aparezca
# automáticamente como tercera categoría en todos los gráficos y tablas.
df_plot <- bind_rows(
  df,
  df %>% mutate(contexto = "Total")
) %>%
  mutate(contexto = factor(contexto,
                           levels = c("Cataluña", "España (resto)", "Total")))

1 Descripción de la muestra

tabla_n <- df_plot %>%
  count(contexto, name = "n") %>%
  mutate(Porcentaje = case_when(
    contexto == "Total" ~ "100%",
    TRUE ~ percent(n / sum(n[contexto != "Total"]), accuracy = .1)
  ))

kable(tabla_n, col.names = c("Contexto", "n", "%"),
      caption = "Tamaño de la muestra por contexto") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  row_spec(which(tabla_n$contexto == "Total"), bold = TRUE, background = azul7)
Tamaño de la muestra por contexto
Contexto n %
Cataluña 538 52.7%
España (resto) 482 47.3%
Total 1020 100%

2 Perfil sociodemográfico

2.1 Edad

edad_stats <- df_plot %>%
  filter(!is.na(edad)) %>%
  group_by(contexto) %>%
  summarise(n       = n(),
            Media   = round(mean(edad), 1),
            Mediana = round(median(edad), 1),
            DT      = round(sd(edad), 1),
            Mínimo  = min(edad),
            Máximo  = max(edad))

kable(edad_stats, caption = "Estadísticos descriptivos de la edad") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  column_spec(1, bold = TRUE, color = azul1) %>%
  row_spec(which(edad_stats$contexto == "Total"), bold = TRUE, background = azul7)
Estadísticos descriptivos de la edad
contexto n Media Mediana DT Mínimo Máximo
Cataluña 514 45.0 45 9.6 21 63
España (resto) 466 45.8 47 10.1 23 69
Total 980 45.4 46 9.9 21 69
ggplot(df_plot %>% filter(!is.na(edad)), aes(x = edad, fill = contexto)) +
  geom_histogram(binwidth = 3, colour = "white", alpha = 0.85) +
  facet_wrap(~contexto, ncol = 3) +
  scale_fill_manual(values = col_ctx, guide = "none") +
  scale_x_continuous(breaks = seq(20, 70, 10)) +
  geom_vline(data = edad_stats,
             aes(xintercept = Media, colour = contexto),
             linetype = "dashed", linewidth = 0.8) +
  scale_colour_manual(values = col_ctx, name = "Media") +
  labs(title = "Distribución de la edad del profesorado",
       x = "Edad (años)", y = "Frecuencia") +
  tema_epjg

2.2 Género

tab_gen <- df_plot %>%
  filter(!is.na(genero), genero != "No informa") %>%
  count(contexto, genero) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n))

ggplot(tab_gen, aes(x = fct_reorder(genero, n, .desc = TRUE),
                    y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.7) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), vjust = -0.4, size = 3.2,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 1)) +
  labs(title = "Distribución por género", x = NULL, y = "Proporción") +
  tema_epjg

2.3 Formación

tab_form <- df_plot %>%
  filter(!is.na(formacion), formacion != "No informa") %>%
  count(contexto, formacion) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n),
         formacion = factor(formacion,
                            levels = c("Grado/Licenciatura", "Máster/Postgrado", "Doctorado")))

ggplot(tab_form, aes(x = formacion, y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.7) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), vjust = -0.4, size = 3.2,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 0.85)) +
  labs(title = "Nivel de formación más elevado", x = NULL, y = "Proporción") +
  tema_epjg

2.4 Experiencia docente

tab_exp <- df_plot %>%
  filter(!is.na(experiencia)) %>%
  count(contexto, experiencia) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n))

ggplot(tab_exp, aes(x = experiencia, y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.75) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), vjust = -0.4, size = 2.5,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 0.40)) +
  labs(title = "Años de experiencia docente", x = NULL, y = "Proporción") +
  tema_epjg +
  theme(axis.text.x = element_text(angle = 35, hjust = 1))

2.5 Ámbito profesional

ambitos_principales <- c("Ed. Infantil", "Ed. Primaria", "Ed. Secundaria",
                          "Bachillerato", "FP", "Ed. Adultos", "Ed. Especial")

tab_ambito <- df_plot %>%
  filter(ambito %in% ambitos_principales) %>%
  count(contexto, ambito) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n),
         ambito = factor(ambito, levels = ambitos_principales))

ggplot(tab_ambito, aes(x = ambito, y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.75) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), vjust = -0.4, size = 2.8,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 0.60)) +
  labs(title = "Ámbito profesional actual", x = NULL, y = "Proporción") +
  tema_epjg +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

2.6 Régimen y tipología del centro

tab_regimen <- df_plot %>%
  filter(!is.na(regimen)) %>%
  count(contexto, regimen) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n),
         regimen = factor(regimen, levels = c("Público", "Concertado", "Privado")))

p_regimen <- ggplot(tab_regimen, aes(x = regimen, y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.7) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), vjust = -0.4, size = 3,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 1.05)) +
  labs(title = "Régimen del centro educativo", x = NULL, y = "Proporción") +
  tema_epjg

tipologias_clean <- c("Urbana", "Rural", "Instituto/IES", "Alta complejidad")
tab_tip <- df_plot %>%
  filter(tipologia %in% tipologias_clean) %>%
  count(contexto, tipologia) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n),
         tipologia = factor(tipologia, levels = tipologias_clean))

p_tip <- ggplot(tab_tip, aes(x = tipologia, y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.7) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), vjust = -0.4, size = 3,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 1.05)) +
  labs(title = "Tipología del centro (criterio geográfico)", x = NULL, y = "Proporción") +
  tema_epjg

p_regimen / p_tip + plot_layout(guides = "collect") &
  theme(legend.position = "bottom")

2.7 Comunidades autónomas (España)

tab_ccaa <- tibble(ccaa = raw_esp[[17]]) %>%
  filter(!is.na(ccaa)) %>%
  count(ccaa, sort = TRUE) %>%
  mutate(prop = n / sum(n), ccaa = fct_reorder(ccaa, n))

ggplot(tab_ccaa, aes(x = ccaa, y = prop, fill = prop)) +
  geom_col() +
  geom_text(aes(label = str_c(n, " (", percent(prop, accuracy = 1), ")")),
            hjust = -0.05, size = 3, colour = azul1) +
  scale_fill_gradient(low = azul6, high = azul1, guide = "none") +
  scale_y_continuous(labels = percent, limits = c(0, 0.23)) +
  coord_flip() +
  labs(title = "Distribución por comunidad autónoma (España, resto)",
       x = NULL, y = "Proporción") +
  tema_epjg


3 Conocimiento y percepción de la EpJG

lik5 <- c("1 - Nada", "2", "3", "4", "5 - Mucho")

3.1 Conocimiento propio

tab_cp <- df_plot %>%
  filter(!is.na(con_propio)) %>%
  mutate(con_propio = factor(con_propio, levels = 1:5, labels = lik5)) %>%
  count(contexto, con_propio) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n))

ggplot(tab_cp, aes(x = con_propio, y = prop, fill = con_propio)) +
  geom_col(show.legend = FALSE) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            vjust = -0.4, size = 3, colour = azul1) +
  scale_fill_manual(values = escala_blues[c(1,2,3,4,5)]) +
  scale_y_continuous(labels = percent, limits = c(0, 0.55)) +
  facet_wrap(~contexto, ncol = 3) +
  labs(title = "¿Cuál es tu grado de conocimiento de la EpJG?",
       x = NULL, y = "Proporción") +
  tema_epjg +
  theme(axis.text.x = element_text(size = 8))

df_plot %>%
  filter(!is.na(con_propio)) %>%
  group_by(contexto) %>%
  summarise(n = n(),
            Media   = round(mean(con_propio, na.rm = TRUE), 2),
            Mediana = median(con_propio, na.rm = TRUE),
            DT      = round(sd(con_propio, na.rm = TRUE), 2)) %>%
  kable(caption = "Estadísticos: grado de conocimiento propio de la EpJG") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  row_spec(3, bold = TRUE, background = azul7)
Estadísticos: grado de conocimiento propio de la EpJG
contexto n Media Mediana DT
Cataluña 515 2.35 2 1.12
España (resto) 466 2.32 2 1.15
Total 981 2.33 2 1.13

3.2 Conocimiento percibido del centro

tab_cc <- df_plot %>%
  filter(!is.na(con_centro)) %>%
  mutate(con_centro = factor(con_centro, levels = 1:5, labels = lik5)) %>%
  count(contexto, con_centro) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n))

ggplot(tab_cc, aes(x = con_centro, y = prop, fill = con_centro)) +
  geom_col(show.legend = FALSE) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            vjust = -0.4, size = 3, colour = azul1) +
  scale_fill_manual(values = escala_blues[c(1,2,3,4,5)]) +
  scale_y_continuous(labels = percent, limits = c(0, 0.65)) +
  facet_wrap(~contexto, ncol = 3) +
  labs(title = "¿Qué grado de conocimiento crees que tiene el profesorado de tu centro?",
       x = NULL, y = "Proporción") +
  tema_epjg +
  theme(axis.text.x = element_text(size = 8))

3.3 Importancia de la EpJG

tab_imp <- df_plot %>%
  filter(!is.na(importancia)) %>%
  mutate(importancia = factor(importancia, levels = 1:5, labels = lik5)) %>%
  count(contexto, importancia) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n))

ggplot(tab_imp, aes(x = importancia, y = prop, fill = importancia)) +
  geom_col(show.legend = FALSE) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            vjust = -0.4, size = 3, colour = azul1) +
  scale_fill_manual(values = escala_blues[c(1,2,3,4,5)]) +
  scale_y_continuous(labels = percent, limits = c(0, 0.70)) +
  facet_wrap(~contexto, ncol = 3) +
  labs(title = "¿Qué importancia tiene introducir la EpJG en tu práctica?",
       x = NULL, y = "Proporción") +
  tema_epjg +
  theme(axis.text.x = element_text(size = 8))

3.4 Comparación de las tres dimensiones

dim_stats <- df_plot %>%
  select(contexto, con_propio, con_centro, importancia) %>%
  pivot_longer(-contexto, names_to = "dimension", values_to = "valor") %>%
  filter(!is.na(valor)) %>%
  group_by(contexto, dimension) %>%
  summarise(Media = mean(valor, na.rm = TRUE),
            DT    = sd(valor, na.rm = TRUE), .groups = "drop") %>%
  mutate(dimension = factor(dimension,
    levels = c("con_propio", "con_centro", "importancia"),
    labels = c("Conocimiento propio", "Conoc. del centro", "Importancia")))

ggplot(dim_stats, aes(x = dimension, y = Media, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.7) +
  geom_errorbar(aes(ymin = Media - DT, ymax = Media + DT),
                position = position_dodge(0.8), width = 0.25,
                colour = "#444444", linewidth = 0.5) +
  geom_text(aes(label = round(Media, 2)),
            position = position_dodge(0.8), vjust = -0.7, size = 3.2,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(limits = c(0, 6.5), breaks = 1:5) +
  labs(title = "Comparación: conocimiento e importancia de la EpJG",
       subtitle = "Media ± desviación típica (escala 1–5)",
       x = NULL, y = "Puntuación media (1–5)") +
  tema_epjg

# Tabla resumen de las tres dimensiones
dim_stats %>%
  mutate(Media_DT = str_c(round(Media, 2), " (", round(DT, 2), ")")) %>%
  select(contexto, dimension, Media_DT) %>%
  pivot_wider(names_from = contexto, values_from = Media_DT) %>%
  rename(Dimensión = dimension) %>%
  kable(caption = "Conocimiento e importancia de la EpJG — Media (DT), escala 1–5") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  column_spec(1, bold = TRUE, color = azul1) %>%
  column_spec(4, bold = TRUE, background = azul7)
Conocimiento e importancia de la EpJG — Media (DT), escala 1–5
Dimensión Cataluña España (resto) Total
Conoc. del centro 2.23 (0.93) 2.16 (1.02) 2.2 (0.97)
Conocimiento propio 2.35 (1.12) 2.32 (1.15) 2.33 (1.13)
Importancia 3.71 (1.08) 3.88 (1.12) 3.79 (1.1)

4 Apoyo a los movimientos sociales

movimientos   <- c("sup_ecologismo", "sup_pacifismo", "sup_feminismo",
                    "sup_der_hum", "sup_lgtbiq", "sup_antirac", "sup_anticap")
etiquetas_mov <- c("Ecologismo", "Pacifismo", "Feminismo",
                   "Derechos humanos", "LGTBIQ+", "Antirracismo", "Anticapitalismo")

tab_mov <- df_plot %>%
  select(contexto, all_of(movimientos)) %>%
  pivot_longer(-contexto, names_to = "movimiento", values_to = "valor") %>%
  filter(!is.na(valor)) %>%
  mutate(movimiento = factor(movimiento, levels = movimientos, labels = etiquetas_mov))

4.1 Perfil global

mov_stats <- tab_mov %>%
  group_by(contexto, movimiento) %>%
  summarise(Media = mean(valor, na.rm = TRUE),
            DT    = sd(valor, na.rm = TRUE), .groups = "drop")

ggplot(mov_stats, aes(x = fct_reorder(movimiento, Media, .fun = function(x) x[3]),
                       y = Media, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.75) +
  geom_errorbar(aes(ymin = Media - DT, ymax = Media + DT),
                position = position_dodge(0.8), width = 0.25,
                colour = "#555555", linewidth = 0.5) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(limits = c(0, 6), breaks = 1:5) +
  coord_flip() +
  labs(title = "Grado de apoyo a los principios de los movimientos sociales",
       subtitle = "Media ± DT (escala 1–5)",
       x = NULL, y = "Puntuación media") +
  tema_epjg

4.2 Distribución por movimiento

tab_mov_prop <- tab_mov %>%
  mutate(valor = factor(valor, levels = 1:5, labels = lik5)) %>%
  count(contexto, movimiento, valor) %>%
  group_by(contexto, movimiento) %>%
  mutate(prop = n / sum(n))

ggplot(tab_mov_prop, aes(x = valor, y = prop, fill = valor)) +
  geom_col(show.legend = FALSE) +
  scale_fill_manual(values = escala_blues[c(1,2,3,4,5)]) +
  scale_y_continuous(labels = percent, breaks = c(0, 0.5)) +
  facet_grid(movimiento ~ contexto) +
  labs(title = "Distribución del apoyo por movimiento social",
       x = NULL, y = "Proporción") +
  tema_epjg +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 7),
        strip.text.y = element_text(angle = 0, size = 7))

4.3 Tabla resumen

mov_stats %>%
  mutate(Media_DT = str_c(round(Media, 2), " (", round(DT, 2), ")")) %>%
  select(contexto, movimiento, Media_DT) %>%
  pivot_wider(names_from = contexto, values_from = Media_DT) %>%
  rename(Movimiento = movimiento) %>%
  kable(caption = "Apoyo a los movimientos sociales — Media (DT), escala 1–5") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  column_spec(1, bold = TRUE, color = azul1) %>%
  column_spec(4, bold = TRUE, background = azul7)
Apoyo a los movimientos sociales — Media (DT), escala 1–5
Movimiento Cataluña España (resto) Total
Ecologismo 4.32 (0.93) 4.4 (0.89) 4.36 (0.91)
Pacifismo 4.57 (0.76) 4.67 (0.75) 4.62 (0.76)
Feminismo 4.34 (0.94) 4.39 (1.05) 4.36 (0.99)
Derechos humanos 4.62 (0.73) 4.75 (0.67) 4.68 (0.71)
LGTBIQ+ 4.38 (0.92) 4.35 (1.03) 4.37 (0.97)
Antirracismo 4.65 (0.72) 4.73 (0.71) 4.69 (0.72)
Anticapitalismo 3.82 (1.2) 3.82 (1.26) 3.82 (1.23)

5 Importancia de las temáticas de formación

tematicas      <- c("imp_genero", "imp_paz", "imp_derechos", "imp_just_eco",
                     "imp_just_amb", "imp_intercult", "imp_bienestar",
                     "imp_rel_educ", "imp_digital", "imp_tecnologia")
etiquetas_tema <- c("Género y feminismos", "Cultura de paz", "Derechos humanos",
                     "Justicia econ. y social", "Justicia ambiental",
                     "Interculturalidad", "Bienestar emocional",
                     "Relación educativa", "Equidad digital", "Crít. tecnología")

tab_tema <- df_plot %>%
  select(contexto, all_of(tematicas)) %>%
  pivot_longer(-contexto, names_to = "tematica", values_to = "valor") %>%
  filter(!is.na(valor)) %>%
  mutate(tematica = factor(tematica, levels = tematicas, labels = etiquetas_tema))

5.1 Puntuación media por temática

tema_stats <- tab_tema %>%
  group_by(contexto, tematica) %>%
  summarise(Media = mean(valor, na.rm = TRUE),
            DT    = sd(valor, na.rm = TRUE), .groups = "drop")

ggplot(tema_stats, aes(x = fct_reorder(tematica, Media, .fun = function(x) x[3]),
                        y = Media, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.75) +
  geom_errorbar(aes(ymin = Media - DT, ymax = Media + DT),
                position = position_dodge(0.8), width = 0.25,
                colour = "#555555", linewidth = 0.5) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(limits = c(0, 6), breaks = 1:5) +
  coord_flip() +
  labs(title = "Importancia de las temáticas para la formación docente",
       subtitle = "Media ± DT (escala 1–5)",
       x = NULL, y = "Puntuación media") +
  tema_epjg

5.2 Distribución por temática

tab_tema_prop <- tab_tema %>%
  mutate(valor = factor(valor, levels = 1:5, labels = lik5)) %>%
  count(contexto, tematica, valor) %>%
  group_by(contexto, tematica) %>%
  mutate(prop = n / sum(n))

ggplot(tab_tema_prop, aes(x = valor, y = prop, fill = valor)) +
  geom_col(show.legend = FALSE) +
  scale_fill_manual(values = escala_blues[c(1,2,3,4,5)]) +
  scale_y_continuous(labels = percent, breaks = c(0, 0.5)) +
  facet_grid(tematica ~ contexto) +
  labs(title = "Distribución de la importancia por temática",
       x = NULL, y = "Proporción") +
  tema_epjg +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 7),
        strip.text.y = element_text(angle = 0, size = 7))

5.3 Tabla resumen

tema_stats %>%
  mutate(Media_DT = str_c(round(Media, 2), " (", round(DT, 2), ")")) %>%
  select(contexto, tematica, Media_DT) %>%
  pivot_wider(names_from = contexto, values_from = Media_DT) %>%
  rename(Temática = tematica) %>%
  kable(caption = "Importancia para la formación — Media (DT), escala 1–5") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  column_spec(1, bold = TRUE, color = azul1) %>%
  column_spec(4, bold = TRUE, background = azul7)
Importancia para la formación — Media (DT), escala 1–5
Temática Cataluña España (resto) Total
Género y feminismos 3.73 (0.83) 3.79 (0.86) 3.76 (0.85)
Cultura de paz 3.86 (0.76) 3.84 (0.86) 3.85 (0.81)
Derechos humanos 3.66 (0.86) 3.69 (0.91) 3.67 (0.89)
Justicia econ. y social 3.38 (0.94) 3.44 (0.99) 3.41 (0.96)
Justicia ambiental 3.4 (0.98) 3.5 (1.01) 3.45 (1)
Interculturalidad 3.68 (0.87) 3.75 (0.91) 3.71 (0.89)
Bienestar emocional 4.01 (0.85) 3.92 (0.97) 3.97 (0.91)
Relación educativa 3.54 (1.02) 3.63 (0.99) 3.58 (1.01)
Equidad digital 3.2 (0.97) 3.24 (1.07) 3.22 (1.02)
Crít. tecnología 3.21 (1) 3.35 (1.08) 3.28 (1.04)

6 Temáticas trabajadas en el aula

trabajadas <- c("trab_genero", "trab_paz", "trab_derechos", "trab_just_eco",
                 "trab_just_amb", "trab_intercult", "trab_bienestar",
                 "trab_rel_educ", "trab_digital", "trab_tecnologia")

tab_trab <- df_plot %>%
  select(contexto, all_of(trabajadas)) %>%
  pivot_longer(-contexto, names_to = "tematica", values_to = "valor") %>%
  filter(!is.na(valor)) %>%
  mutate(
    tematica = factor(str_remove(tematica, "trab_"),
                      levels = str_remove(trabajadas, "trab_"),
                      labels = etiquetas_tema),
    valor = str_to_upper(str_trim(valor))
  ) %>%
  count(contexto, tematica, valor) %>%
  group_by(contexto, tematica) %>%
  mutate(prop = n / sum(n)) %>%
  filter(valor == "SÍ")

6.1 % que trabaja cada temática

ggplot(tab_trab, aes(x = fct_reorder(tematica, prop, .fun = function(x) x[3]),
                      y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.75) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), hjust = -0.1, size = 2.8,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 1.1)) +
  coord_flip() +
  labs(title = "Temáticas de la EpJG trabajadas en el aula (% SÍ)",
       x = NULL, y = "% que responde SÍ") +
  tema_epjg

6.2 Tabla resumen

tab_trab %>%
  mutate(pct = percent(prop, accuracy = 1)) %>%
  select(contexto, tematica, pct) %>%
  pivot_wider(names_from = contexto, values_from = pct) %>%
  rename(Temática = tematica) %>%
  kable(caption = "Porcentaje de docentes que trabaja cada temática (SÍ)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
  column_spec(1, bold = TRUE, color = azul1) %>%
  column_spec(4, bold = TRUE, background = azul7)
Porcentaje de docentes que trabaja cada temática (SÍ)
Temática Cataluña España (resto) Total
Género y feminismos 77% 76% 77%
Cultura de paz 83% 82% 83%
Derechos humanos 70% 71% 70%
Justicia econ. y social 46% 54% 50%
Justicia ambiental 63% 65% 64%
Interculturalidad 81% 81% 81%
Bienestar emocional 86% 85% 86%
Relación educativa 62% 70% 66%
Equidad digital 41% 44% 42%
Crít. tecnología 55% 67% 61%

7 Preferencias de formación

7.1 Formato preferido

tab_fmt <- df_plot %>%
  filter(!is.na(formato_pref)) %>%
  mutate(formato_pref = str_trim(formato_pref),
         formato_pref = case_when(
           str_detect(formato_pref, "irtual")                   ~ "Virtual",
           str_detect(formato_pref, "resencial")                ~ "Presencial",
           str_detect(formato_pref, "emisencial|emipresencial") ~ "Semipresencial",
           TRUE ~ formato_pref
         )) %>%
  count(contexto, formato_pref) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n),
         formato_pref = factor(formato_pref,
                               levels = c("Presencial", "Virtual", "Semipresencial")))

ggplot(tab_fmt, aes(x = formato_pref, y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.7) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), vjust = -0.4, size = 3.2,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 0.60)) +
  labs(title = "Formato de formación preferido", x = NULL, y = "Proporción") +
  tema_epjg

7.2 Modalidad formativa

armonizar_modalidad <- function(x) {
  case_when(
    str_detect(x, regex("curs|curso",                          ignore_case = TRUE)) ~ "Curso",
    str_detect(x, regex("taller|seminari|seminar",             ignore_case = TRUE)) ~ "Talleres/Seminarios",
    str_detect(x, regex("intercanvi|intercambio",              ignore_case = TRUE)) ~ "Intercambio de experiencias",
    str_detect(x, regex("conferèn|conferenci",                 ignore_case = TRUE)) ~ "Ciclos de conferencias",
    str_detect(x, regex("assessorament|asesoramiento",         ignore_case = TRUE)) ~ "Asesoramiento en centros",
    str_detect(x, regex("comunitat|comunidad",                 ignore_case = TRUE)) ~ "Comunidad de aprendizaje",
    TRUE ~ x
  )
}

mod_base <- bind_rows(
  tibble(modalidad = raw_cat[[72]], contexto = "Cataluña"),
  tibble(modalidad = raw_esp[[73]], contexto = "España (resto)")
) %>%
  filter(!is.na(modalidad)) %>%
  mutate(modalidad = str_split(modalidad, ";")) %>%
  unnest(modalidad) %>%
  mutate(modalidad = str_trim(modalidad)) %>%
  filter(modalidad != "")

# Añadir filas Total
tab_mod <- bind_rows(
  mod_base,
  mod_base %>% mutate(contexto = "Total")
) %>%
  mutate(contexto  = factor(contexto, levels = c("Cataluña", "España (resto)", "Total")),
         modalidad = armonizar_modalidad(modalidad)) %>%
  count(contexto, modalidad) %>%
  group_by(contexto) %>%
  mutate(prop = n / sum(n)) %>%
  filter(n > 2)

ggplot(tab_mod, aes(x = fct_reorder(modalidad, prop, .fun = function(x) x[3]),
                     y = prop, fill = contexto)) +
  geom_col(position = position_dodge(0.8), width = 0.75) +
  geom_text(aes(label = percent(prop, accuracy = 1)),
            position = position_dodge(0.8), hjust = -0.1, size = 2.8,
            colour = azul1) +
  scale_fill_manual(values = col_ctx, name = "Contexto") +
  scale_y_continuous(labels = percent, limits = c(0, 0.55)) +
  coord_flip() +
  labs(title = "Modalidad formativa preferida (respuesta múltiple)",
       subtitle = "Porcentaje calculado sobre el total de respuestas por contexto",
       x = NULL, y = "Proporción de menciones") +
  tema_epjg


8 Resumen ejecutivo

Resumen ejecutivo por contexto
Indicador Cataluña España (resto) Total
n (muestra válida edad) 514 466 980
Edad media (años) 45 45.8 45.4
% Femenino 71.6% 67.8% 69.8%
Régimen mayoritario Público Público Público
Tipología mayoritaria Urbana Urbana Urbana
Conocimiento propio EpJG (1–5) 2.35 2.32 2.33
Conoc. percibido del centro (1–5) 2.23 2.16 2.2
Importancia EpJG (1–5) 3.71 3.88 3.79