library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(forcats)
library(stringr)
library(scales)
library(knitr)
library(kableExtra)
library(patchwork)azul1 <- "#084594"; azul2 <- "#2171B5"; azul3 <- "#4292C6"
azul4 <- "#6BAED6"; azul5 <- "#9ECAE1"; azul6 <- "#C6DBEF"; azul7 <- "#DEEBF7"
escala_blues <- c(azul1, azul2, azul3, azul4, azul5, azul6, azul7)
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)
)# ── Lectura ───────────────────────────────────────────────────────
# Cataluña: las etiquetas de preguntas están EN los nombres de columna.
# España: la primera fila de datos contiene etiquetas de preguntas → slice(-1)
raw_cat <- read_excel("Cataluña Professió Docent i Justícia Global (1-538).xlsx")
raw_esp <- read_excel("ESPAÑA Profesión Docente y Justicia Global (2)(1-483).xlsx") %>%
slice(-1) # elimina la fila de etiquetas de preguntas# ── Limpieza tipología ────────────────────────────────────────────
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
)
}
# ── Armonización dificultades (CAT → ES) ─────────────────────────
arm_dificultad <- function(x) {
x <- str_trim(str_replace_all(x, "\u00a0", "")) # elimina non-breaking spaces
case_when(
str_detect(x, regex("recursos econòmics|recursos económicos", ignore_case = TRUE)) ~ "Falta de recursos económicos",
str_detect(x, regex("recursos pedagògics|recursos pedagógicos", ignore_case = TRUE)) ~ "Falta de recursos pedagógicos",
str_detect(x, regex("recolzament|apoyo.*famílies|apoyo.*familias", ignore_case = TRUE)) ~ "Falta de apoyo de las familias",
str_detect(x, regex("temps|tiempo", ignore_case = TRUE)) ~ "Falta de tiempo",
str_detect(x, regex("interès|interés", ignore_case = TRUE)) ~ "Falta de interés personal",
str_detect(x, regex("regulació|regulación", ignore_case = TRUE)) ~ "Falta de regulación institucional",
str_detect(x, regex("formació|formación", ignore_case = TRUE)) ~ "Falta de formación",
TRUE ~ x
)
}# ── Etiquetas de las temáticas ────────────────────────────────────
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"
)
# ═══════════════════════════════════════════════════════════════════
# CATALUÑA (R 1-indexed; etiquetas ya en los nombres de columna)
# ═══════════════════════════════════════════════════════════════════
# Bloque Cols (R)
# Perfil 1,8-10,14-15,17-18
# EpJG global 19-21
# Movimientos 23-29
# Conoc. temát. 30-39
# Trab. aula 40-49
# Dificultades 50-59
# Interés form. 60-69
# Modalidad/Fmt 72-73
cat_df <- raw_cat %>%
select(
id = 1, edad = 8, genero = 9, formacion = 10,
experiencia = 14, ambito = 15, regimen = 17, tipologia = 18,
# EpJG percepción global
con_propio = 19, con_centro = 20, importancia = 21,
# Apoyo movimientos sociales
sup_ecologismo = 23, sup_pacifismo = 24, sup_feminismo = 25,
sup_der_hum = 26, sup_lgtbiq = 27, sup_antirac = 28, sup_anticap = 29,
# Conocimiento sobre las temáticas (escala 1-5)
conoc_genero = 30, conoc_paz = 31, conoc_derechos = 32,
conoc_just_eco = 33, conoc_just_amb = 34, conoc_intercult = 35,
conoc_bienestar = 36, conoc_rel_educ = 37, conoc_digital = 38,
conoc_tecnologia = 39,
# Trabaja en el aula (SÍ/NO)
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,
# Principal dificultad (categórico)
dif_genero = 50, dif_paz = 51, dif_derechos = 52,
dif_just_eco = 53, dif_just_amb = 54, dif_intercult = 55,
dif_bienestar = 56, dif_rel_educ = 57, dif_digital = 58,
dif_tecnologia = 59,
# Interés en formarse (escala 1-5)
int_genero = 60, int_paz = 61, int_derechos = 62,
int_just_eco = 63, int_just_amb = 64, int_intercult = 65,
int_bienestar = 66, int_rel_educ = 67, int_digital = 68,
int_tecnologia = 69,
# Preferencias formación
modalidad = 72, formato_pref = 73
) %>%
mutate(
contexto = "Cataluña",
id = as.character(id),
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,
conoc_genero:conoc_tecnologia,
int_genero:int_tecnologia), as.numeric),
across(dif_genero:dif_tecnologia, arm_dificultad)
)
# ═══════════════════════════════════════════════════════════════════
# ESPAÑA (REST) (R 1-indexed; tras slice(-1) la fila de etiquetas ya no existe)
# ═══════════════════════════════════════════════════════════════════
# Bloque Cols (R)
# Perfil 1,8-10,14-15,17-19
# EpJG global 20-22
# Movimientos 24-30
# Conoc. temát. 31-40
# Trab. aula 41-50
# Dificultades 51-60
# Interés form. 61-70
# Modalidad/Fmt 73-74
esp_df <- raw_esp %>%
select(
id = 1, edad = 8, genero = 9, formacion = 10,
experiencia = 14, ambito = 15, ccaa = 17, regimen = 18, tipologia = 19,
# EpJG percepción global
con_propio = 20, con_centro = 21, importancia = 22,
# Apoyo movimientos sociales
sup_ecologismo = 24, sup_pacifismo = 25, sup_feminismo = 26,
sup_der_hum = 27, sup_lgtbiq = 28, sup_antirac = 29, sup_anticap = 30,
# Conocimiento sobre las temáticas
conoc_genero = 31, conoc_paz = 32, conoc_derechos = 33,
conoc_just_eco = 34, conoc_just_amb = 35, conoc_intercult = 36,
conoc_bienestar = 37, conoc_rel_educ = 38, conoc_digital = 39,
conoc_tecnologia = 40,
# Trabaja en el aula
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,
# Principal dificultad
dif_genero = 51, dif_paz = 52, dif_derechos = 53,
dif_just_eco = 54, dif_just_amb = 55, dif_intercult = 56,
dif_bienestar = 57, dif_rel_educ = 58, dif_digital = 59,
dif_tecnologia = 60,
# Interés en formarse
int_genero = 61, int_paz = 62, int_derechos = 63,
int_just_eco = 64, int_just_amb = 65, int_intercult = 66,
int_bienestar = 67, int_rel_educ = 68, int_digital = 69,
int_tecnologia = 70,
# Preferencias formación
modalidad = 73, formato_pref = 74
) %>%
mutate(
contexto = "España (resto)",
id = as.character(id),
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,
conoc_genero:conoc_tecnologia,
int_genero:int_tecnologia), as.numeric),
across(dif_genero:dif_tecnologia, arm_dificultad)
)
# ── 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 Total ─────────────────────────────────────────────
df_plot <- bind_rows(df, df %>% mutate(contexto = "Total")) %>%
mutate(contexto = factor(contexto,
levels = c("Cataluña", "España (resto)", "Total")))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)| Contexto | n | % |
|---|---|---|
| Cataluña | 538 | 52.7% |
| España (resto) | 482 | 47.3% |
| Total | 1020 | 100% |
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)| contexto | n | Media | Mediana | DT | Mínimo | Máximo |
|---|---|---|---|---|---|---|
| Cataluña | 514 | 45.0 | 45 | 9.6 | 21 | 63 |
| España (resto) | 465 | 45.8 | 47 | 10.1 | 23 | 69 |
| Total | 979 | 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_epjgtab_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_epjgtab_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_epjgtab_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))ambitos_ok <- c("Ed. Infantil","Ed. Primaria","Ed. Secundaria",
"Bachillerato","FP","Ed. Adultos","Ed. Especial")
tab_ambito <- df_plot %>%
filter(ambito %in% ambitos_ok) %>%
count(contexto, ambito) %>%
group_by(contexto) %>%
mutate(prop = n / sum(n), ambito = factor(ambito, levels = ambitos_ok))
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))tab_reg <- df_plot %>% filter(!is.na(regimen)) %>%
count(contexto, regimen) %>% group_by(contexto) %>%
mutate(prop = n/sum(n), regimen = factor(regimen, c("Público","Concertado","Privado")))
p1 <- ggplot(tab_reg, aes(x = regimen, y = prop, fill = contexto)) +
geom_col(position = position_dodge(0.8), width = 0.7) +
geom_text(aes(label = percent(prop,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", x = NULL, y = "Proporción") + tema_epjg
tip_ok <- c("Urbana","Rural","Instituto/IES","Alta complejidad")
tab_tip <- df_plot %>% filter(tipologia %in% tip_ok) %>%
count(contexto, tipologia) %>% group_by(contexto) %>%
mutate(prop = n/sum(n), tipologia = factor(tipologia, tip_ok))
p2 <- 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,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", x = NULL, y = "Proporción") + tema_epjg
p1 / p2 + plot_layout(guides = "collect") & theme(legend.position = "bottom")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,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,.23)) +
coord_flip() +
labs(title="Distribución por comunidad autónoma (España, resto)",
x=NULL, y="Proporción") + tema_epjgtab_cp <- df_plot %>% filter(!is.na(con_propio)) %>%
mutate(con_propio = factor(con_propio, 1:5, 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,1)), vjust=-0.4, size=3, colour=azul1) +
scale_fill_manual(values=escala_blues[1:5]) +
scale_y_continuous(labels=percent, limits=c(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: conocimiento propio de la EpJG") %>%
kable_styling(bootstrap_options=c("striped","hover"), full_width=FALSE) %>%
row_spec(3, bold=TRUE, background=azul7)| 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.34 | 2 | 1.13 |
tab_cc <- df_plot %>% filter(!is.na(con_centro)) %>%
mutate(con_centro=factor(con_centro,1:5,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,1)), vjust=-0.4, size=3, colour=azul1) +
scale_fill_manual(values=escala_blues[1:5]) +
scale_y_continuous(labels=percent, limits=c(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))tab_imp <- df_plot %>% filter(!is.na(importancia)) %>%
mutate(importancia=factor(importancia,1:5,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,1)), vjust=-0.4, size=3, colour=azul1) +
scale_fill_manual(values=escala_blues[1:5]) +
scale_y_continuous(labels=percent, limits=c(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))dim_stats <- df_plot %>%
select(contexto, con_propio, con_centro, importancia) %>%
pivot_longer(-contexto, names_to="dim", values_to="valor") %>%
filter(!is.na(valor)) %>%
group_by(contexto, dim) %>%
summarise(Media=mean(valor,na.rm=TRUE), DT=sd(valor,na.rm=TRUE), .groups="drop") %>%
mutate(dim=factor(dim, c("con_propio","con_centro","importancia"),
c("Conocimiento propio","Conoc. del centro","Importancia")))
ggplot(dim_stats, aes(x=dim, 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="#444", 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 ± DT (escala 1–5)", x=NULL, y="Puntuación media (1–5)") + tema_epjgdim_stats %>%
mutate(val=str_c(round(Media,2)," (",round(DT,2),")")) %>%
select(contexto,dim,val) %>%
pivot_wider(names_from=contexto, values_from=val) %>%
rename(Dimensión=dim) %>%
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)| 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.34 (1.13) |
| Importancia | 3.71 (1.08) | 3.88 (1.11) | 3.79 (1.1) |
conocs <- c("conoc_genero","conoc_paz","conoc_derechos","conoc_just_eco",
"conoc_just_amb","conoc_intercult","conoc_bienestar",
"conoc_rel_educ","conoc_digital","conoc_tecnologia")
tab_conoc <- df_plot %>%
select(contexto, all_of(conocs)) %>%
pivot_longer(-contexto, names_to="tematica", values_to="valor") %>%
filter(!is.na(valor)) %>%
mutate(tematica=factor(tematica, conocs, etiquetas_tema))conoc_stats <- tab_conoc %>% group_by(contexto,tematica) %>%
summarise(Media=mean(valor,na.rm=TRUE), DT=sd(valor,na.rm=TRUE), .groups="drop")
ggplot(conoc_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="#555", 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 conocimiento sobre las temáticas de la EpJG",
subtitle="Media ± DT (escala 1–5)", x=NULL, y="Puntuación media") + tema_epjgtab_conoc %>%
mutate(valor=factor(valor,1:5,lik5)) %>%
count(contexto,tematica,valor) %>%
group_by(contexto,tematica) %>% mutate(prop=n/sum(n)) %>%
ggplot(aes(x=valor, y=prop, fill=valor)) +
geom_col(show.legend=FALSE) +
scale_fill_manual(values=escala_blues[1:5]) +
scale_y_continuous(labels=percent, breaks=c(0,.5)) +
facet_grid(tematica~contexto) +
labs(title="Distribución del conocimiento 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))conoc_stats %>%
mutate(val=str_c(round(Media,2)," (",round(DT,2),")")) %>%
select(contexto,tematica,val) %>%
pivot_wider(names_from=contexto, values_from=val) %>%
rename(Temática=tematica) %>%
kable(caption="Conocimiento sobre las temáticas — 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)| 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.74 (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.98) | 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) |
trabs <- 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(trabs)) %>%
pivot_longer(-contexto, names_to="tematica", values_to="valor") %>%
filter(!is.na(valor)) %>%
mutate(tematica=factor(str_remove(tematica,"trab_"),
str_remove(trabs,"trab_"), 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Í")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,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_epjgtab_trab %>%
mutate(pct=percent(prop,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)| 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% |
difs <- c("dif_genero","dif_paz","dif_derechos","dif_just_eco",
"dif_just_amb","dif_intercult","dif_bienestar",
"dif_rel_educ","dif_digital","dif_tecnologia")
tab_dif <- df_plot %>%
select(contexto, all_of(difs)) %>%
pivot_longer(-contexto, names_to="tematica", values_to="dificultad") %>%
filter(!is.na(dificultad)) %>%
mutate(tematica=factor(str_remove(tematica,"dif_"),
str_remove(difs,"dif_"), etiquetas_tema))tab_dif_glob <- tab_dif %>%
count(contexto, dificultad) %>%
group_by(contexto) %>% mutate(prop=n/sum(n)) %>%
filter(!is.na(dificultad))
ggplot(tab_dif_glob, aes(x=fct_reorder(dificultad,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,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,.45)) + coord_flip() +
labs(title="Principal dificultad para incorporar la EpJG en el aula",
subtitle="Agregado sobre todas las temáticas",
x=NULL, y="Proporción de menciones") + tema_epjgtab_dif_tema <- tab_dif %>%
count(contexto, tematica, dificultad) %>%
group_by(contexto, tematica) %>% mutate(prop=n/sum(n))
# Mostrar solo las 3 dificultades más frecuentes por legibilidad
top3_dif <- tab_dif %>% count(dificultad, sort=TRUE) %>%
head(6) %>% pull(dificultad)
tab_dif_tema %>%
filter(dificultad %in% top3_dif) %>%
ggplot(aes(x=dificultad, y=prop, fill=contexto)) +
geom_col(position=position_dodge(0.8), width=0.75) +
scale_fill_manual(values=col_ctx, name="Contexto") +
scale_y_continuous(labels=percent, limits=c(0,.65)) +
facet_wrap(~tematica, ncol=2) +
labs(title="Dificultades más frecuentes por temática",
x=NULL, y="Proporción") + tema_epjg +
theme(axis.text.x=element_text(angle=40, hjust=1, size=7))tab_dif_glob %>%
mutate(pct=percent(prop,1)) %>%
select(contexto,dificultad,pct) %>%
pivot_wider(names_from=contexto, values_from=pct) %>%
arrange(desc(Total)) %>%
rename(Dificultad=dificultad) %>%
kable(caption="Distribución de la principal dificultad (agregada sobre todas las temáticas)") %>%
kable_styling(bootstrap_options=c("striped","hover"), full_width=FALSE) %>%
column_spec(1, bold=TRUE, color=azul1) %>% column_spec(4, bold=TRUE, background=azul7)| Dificultad | Cataluña | España (resto) | Total |
|---|---|---|---|
| Falta de interés personal | 5% | 6% | 5% |
| Falta de recursos económicos | 6% | 5% | 5% |
| Falta de apoyo de las familias | 3% | 6% | 4% |
| Falta de tiempo | 38% | 39% | 39% |
| Falta de formación | 20% | 20% | 20% |
| Falta de recursos pedagógicos | 18% | 13% | 15% |
| Falta de regulación institucional | 11% | 12% | 11% |
ints <- c("int_genero","int_paz","int_derechos","int_just_eco",
"int_just_amb","int_intercult","int_bienestar",
"int_rel_educ","int_digital","int_tecnologia")
tab_int <- df_plot %>%
select(contexto, all_of(ints)) %>%
pivot_longer(-contexto, names_to="tematica", values_to="valor") %>%
filter(!is.na(valor)) %>%
mutate(tematica=factor(str_remove(tematica,"int_"),
str_remove(ints,"int_"), etiquetas_tema))int_stats <- tab_int %>% group_by(contexto,tematica) %>%
summarise(Media=mean(valor,na.rm=TRUE), DT=sd(valor,na.rm=TRUE), .groups="drop")
ggplot(int_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="#555", 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="Interés en formarse en las temáticas de la EpJG",
subtitle="Media ± DT (escala 1–5)", x=NULL, y="Puntuación media") + tema_epjgtab_int %>%
mutate(valor=factor(valor,1:5,lik5)) %>%
count(contexto,tematica,valor) %>%
group_by(contexto,tematica) %>% mutate(prop=n/sum(n)) %>%
ggplot(aes(x=valor, y=prop, fill=valor)) +
geom_col(show.legend=FALSE) +
scale_fill_manual(values=escala_blues[1:5]) +
scale_y_continuous(labels=percent, breaks=c(0,.5)) +
facet_grid(tematica~contexto) +
labs(title="Distribución del interés en formarse 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))comp <- bind_rows(
conoc_stats %>% mutate(tipo="Conocimiento actual"),
int_stats %>% mutate(tipo="Interés en formarse")
) %>% filter(contexto == "Total")
ggplot(comp, aes(x=fct_reorder(tematica,Media), y=Media, fill=tipo)) +
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="#444", linewidth=0.5) +
scale_fill_manual(values=c("Conocimiento actual"=azul3, "Interés en formarse"=azul1),
name=NULL) +
scale_y_continuous(limits=c(0,6), breaks=1:5) + coord_flip() +
labs(title="Conocimiento actual vs. Interés en formarse (Total muestra)",
subtitle="Media ± DT (escala 1–5)", x=NULL, y="Puntuación media") + tema_epjgint_stats %>%
mutate(val=str_c(round(Media,2)," (",round(DT,2),")")) %>%
select(contexto,tematica,val) %>%
pivot_wider(names_from=contexto, values_from=val) %>%
rename(Temática=tematica) %>%
kable(caption="Interés en formarse — 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)| Temática | Cataluña | España (resto) | Total |
|---|---|---|---|
| Género y feminismos | 3.31 (1.38) | 3.51 (1.41) | 3.41 (1.4) |
| Cultura de paz | 3.51 (1.28) | 3.73 (1.28) | 3.61 (1.29) |
| Derechos humanos | 3.43 (1.25) | 3.78 (1.23) | 3.6 (1.25) |
| Justicia econ. y social | 3.43 (1.26) | 3.75 (1.24) | 3.58 (1.26) |
| Justicia ambiental | 3.53 (1.24) | 3.8 (1.22) | 3.66 (1.24) |
| Interculturalidad | 3.63 (1.23) | 3.91 (1.18) | 3.76 (1.21) |
| Bienestar emocional | 3.92 (1.26) | 4.13 (1.19) | 4.02 (1.23) |
| Relación educativa | 3.71 (1.24) | 3.97 (1.22) | 3.83 (1.24) |
| Equidad digital | 3.17 (1.29) | 3.46 (1.3) | 3.31 (1.3) |
| Crít. tecnología | 3.33 (1.34) | 3.71 (1.27) | 3.51 (1.32) |
tab_fmt <- df_plot %>% filter(!is.na(formato_pref)) %>%
mutate(fmt=str_trim(formato_pref),
fmt=case_when(
str_detect(fmt,"irtual") ~ "Virtual",
str_detect(fmt,"resencial") ~ "Presencial",
str_detect(fmt,"emisencial|emipresencial") ~ "Semipresencial",
TRUE ~ fmt
)) %>%
count(contexto, fmt) %>% group_by(contexto) %>%
mutate(prop=n/sum(n), fmt=factor(fmt,c("Presencial","Virtual","Semipresencial")))
ggplot(tab_fmt, aes(x=fmt, y=prop, fill=contexto)) +
geom_col(position=position_dodge(0.8), width=0.7) +
geom_text(aes(label=percent(prop,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,.60)) +
labs(title="Formato de formación preferido", x=NULL, y="Proporción") + tema_epjgarm_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 != "")
tab_mod <- bind_rows(mod_base, mod_base %>% mutate(contexto="Total")) %>%
mutate(contexto=factor(contexto,c("Cataluña","España (resto)","Total")),
modalidad=arm_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,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,.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| Indicador | Cataluña | España (resto) | Total |
|---|---|---|---|
| n (válidos edad) | 514 | 465 | 979 |
| Edad media (años) | 45 años | 45.8 años | 45.4 años |
| % Femenino | 71.6% | 67.7% | 69.7% |
| Régimen mayoritario | Público | Público | Público |
| Tipología mayoritaria | Urbana | Urbana | Urbana |
| Conoc. propio EpJG (1–5) | 2.35 | 2.32 | 2.34 |
| Conoc. percibido centro (1–5) | 2.23 | 2.16 | 2.2 |
| Importancia EpJG (1–5) | 3.71 | 3.88 | 3.79 |
| Conoc. medio temáticas (1–5) | 3.57 | 3.62 | 3.59 |
| Interés medio formación (1–5) | 3.5 | 3.78 | 3.63 |
Las siguientes secciones amplían los descriptivos con inferencia estadística orientada a la publicación científica.
Criterio de normalidad: dado el tamaño muestral (n > 50 por grupo), se usa el test de Kolmogorov-Smirnov con corrección de Lilliefors (nortest). Para muestras Likert con asimetría evidente se aplican tests no paramétricos.
# Instala si es necesario:
# install.packages(c("nortest","coin","rstatix","ggcorrplot","cluster","factoextra","MASS","broom","purrr"))
# Orden de carga importante: coin y MASS antes de rstatix y dplyr
# para que sus funciones no enmascaren las que usamos
library(nortest) # KS-Lilliefors
library(coin) # wilcoxon_test exacto (carga antes que rstatix)
library(MASS) # polr — carga antes que dplyr
library(rstatix) # wilcox_test, adjust_pvalue
library(ggcorrplot) # heatmap correlaciones
library(cluster) # PAM (k-medoides)
library(factoextra) # fviz_cluster, fviz_nbclust
library(broom) # tidy() para tablas de modelos
library(purrr) # map_dfr
# Restaurar dplyr al final para que su select() tenga prioridad
library(dplyr)# Variables Likert principales sobre las que se comparan los dos grupos
vars_likert <- c("con_propio", "con_centro", "importancia",
"sup_ecologismo","sup_pacifismo","sup_feminismo",
"sup_der_hum","sup_lgtbiq","sup_antirac","sup_anticap",
paste0("conoc_", c("genero","paz","derechos","just_eco",
"just_amb","intercult","bienestar",
"rel_educ","digital","tecnologia")),
paste0("int_", c("genero","paz","derechos","just_eco",
"just_amb","intercult","bienestar",
"rel_educ","digital","tecnologia")))
# KS-Lilliefors por contexto
norm_test <- df %>%
dplyr::select(contexto, all_of(vars_likert)) %>%
pivot_longer(-contexto, names_to = "variable", values_to = "valor") %>%
dplyr::filter(!is.na(valor)) %>%
dplyr::group_by(contexto, variable) %>%
dplyr::summarise(
n = n(),
KS_D = tryCatch(lillie.test(valor)$statistic, error = function(e) NA_real_),
KS_p = tryCatch(lillie.test(valor)$p.value, error = function(e) NA_real_),
Normal = ifelse(!is.na(KS_p) & KS_p > .05, "Sí", "No"),
.groups = "drop"
)
# Resumen: ¿cuántas variables superan la normalidad?
norm_test %>%
dplyr::count(contexto, Normal) %>%
kable(caption = "Normalidad por contexto (KS-Lilliefors): número de variables") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)| contexto | Normal | n |
|---|---|---|
| Cataluña | No | 30 |
| España (resto) | No | 30 |
# Tabla completa
norm_test %>%
dplyr::mutate(KS_D = round(KS_D, 3), KS_p = round(KS_p, 3)) %>%
kable(caption = "Test de normalidad KS-Lilliefors por variable y contexto") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE) %>%
scroll_box(height = "400px")| contexto | variable | n | KS_D | KS_p | Normal |
|---|---|---|---|---|---|
| Cataluña | con_centro | 515 | 0.234 | 0 | No |
| Cataluña | con_propio | 515 | 0.209 | 0 | No |
| Cataluña | conoc_bienestar | 515 | 0.253 | 0 | No |
| Cataluña | conoc_derechos | 515 | 0.232 | 0 | No |
| Cataluña | conoc_digital | 515 | 0.195 | 0 | No |
| Cataluña | conoc_genero | 515 | 0.274 | 0 | No |
| Cataluña | conoc_intercult | 515 | 0.247 | 0 | No |
| Cataluña | conoc_just_amb | 515 | 0.201 | 0 | No |
| Cataluña | conoc_just_eco | 515 | 0.209 | 0 | No |
| Cataluña | conoc_paz | 515 | 0.284 | 0 | No |
| Cataluña | conoc_rel_educ | 515 | 0.227 | 0 | No |
| Cataluña | conoc_tecnologia | 515 | 0.189 | 0 | No |
| Cataluña | importancia | 515 | 0.213 | 0 | No |
| Cataluña | int_bienestar | 515 | 0.263 | 0 | No |
| Cataluña | int_derechos | 515 | 0.183 | 0 | No |
| Cataluña | int_digital | 515 | 0.154 | 0 | No |
| Cataluña | int_genero | 515 | 0.168 | 0 | No |
| Cataluña | int_intercult | 515 | 0.195 | 0 | No |
| Cataluña | int_just_amb | 515 | 0.190 | 0 | No |
| Cataluña | int_just_eco | 515 | 0.166 | 0 | No |
| Cataluña | int_paz | 515 | 0.174 | 0 | No |
| Cataluña | int_rel_educ | 515 | 0.199 | 0 | No |
| Cataluña | int_tecnologia | 515 | 0.162 | 0 | No |
| Cataluña | sup_anticap | 515 | 0.222 | 0 | No |
| Cataluña | sup_antirac | 515 | 0.444 | 0 | No |
| Cataluña | sup_der_hum | 515 | 0.429 | 0 | No |
| Cataluña | sup_ecologismo | 515 | 0.323 | 0 | No |
| Cataluña | sup_feminismo | 515 | 0.340 | 0 | No |
| Cataluña | sup_lgtbiq | 515 | 0.350 | 0 | No |
| Cataluña | sup_pacifismo | 515 | 0.406 | 0 | No |
| España (resto) | con_centro | 466 | 0.218 | 0 | No |
| España (resto) | con_propio | 466 | 0.200 | 0 | No |
| España (resto) | conoc_bienestar | 466 | 0.253 | 0 | No |
| España (resto) | conoc_derechos | 466 | 0.233 | 0 | No |
| España (resto) | conoc_digital | 466 | 0.179 | 0 | No |
| España (resto) | conoc_genero | 466 | 0.251 | 0 | No |
| España (resto) | conoc_intercult | 466 | 0.248 | 0 | No |
| España (resto) | conoc_just_amb | 466 | 0.204 | 0 | No |
| España (resto) | conoc_just_eco | 466 | 0.209 | 0 | No |
| España (resto) | conoc_paz | 466 | 0.260 | 0 | No |
| España (resto) | conoc_rel_educ | 466 | 0.242 | 0 | No |
| España (resto) | conoc_tecnologia | 466 | 0.189 | 0 | No |
| España (resto) | importancia | 466 | 0.227 | 0 | No |
| España (resto) | int_bienestar | 466 | 0.318 | 0 | No |
| España (resto) | int_derechos | 466 | 0.208 | 0 | No |
| España (resto) | int_digital | 466 | 0.184 | 0 | No |
| España (resto) | int_genero | 466 | 0.196 | 0 | No |
| España (resto) | int_intercult | 466 | 0.230 | 0 | No |
| España (resto) | int_just_amb | 466 | 0.220 | 0 | No |
| España (resto) | int_just_eco | 466 | 0.214 | 0 | No |
| España (resto) | int_paz | 466 | 0.211 | 0 | No |
| España (resto) | int_rel_educ | 466 | 0.272 | 0 | No |
| España (resto) | int_tecnologia | 466 | 0.207 | 0 | No |
| España (resto) | sup_anticap | 466 | 0.230 | 0 | No |
| España (resto) | sup_antirac | 466 | 0.472 | 0 | No |
| España (resto) | sup_der_hum | 466 | 0.481 | 0 | No |
| España (resto) | sup_ecologismo | 466 | 0.351 | 0 | No |
| España (resto) | sup_feminismo | 466 | 0.386 | 0 | No |
| España (resto) | sup_lgtbiq | 466 | 0.359 | 0 | No |
| España (resto) | sup_pacifismo | 466 | 0.455 | 0 | No |
Decisión: si alguna variable no sigue distribución normal (p < .05, habitual en escalas Likert), se aplica el test de Mann-Whitney U en lugar de la t de Student para todas las comparaciones de esta línea, para mantener coherencia metodológica.
library(rstatix)
mwu_res <- df %>%
dplyr::select(contexto, all_of(vars_likert)) %>%
dplyr::filter(contexto %in% c("Cataluña","España (resto)")) %>%
pivot_longer(-contexto, names_to = "variable", values_to = "valor") %>%
dplyr::filter(!is.na(valor)) %>%
dplyr::group_by(variable) %>%
rstatix::wilcox_test(valor ~ contexto, paired = FALSE) %>%
rstatix::adjust_pvalue(method = "BH") %>%
rstatix::add_significance("p.adj") %>%
dplyr::mutate(r = abs(statistic) / sqrt(n1 + n2))
# Tabla de resultados significativos
mwu_res %>%
dplyr::filter(p.adj < .05) %>%
dplyr::select(variable, n1, n2, statistic, p, p.adj, p.adj.signif, r) %>%
dplyr::mutate(across(c(p, p.adj, r), ~ round(.x, 3))) %>%
arrange(p.adj) %>%
kable(caption = "Diferencias significativas entre contextos (Mann-Whitney U, corrección BH)
— Solo resultados con p.adj < .05") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE) %>%
column_spec(7, bold = TRUE, color = azul1)| variable | n1 | n2 | statistic | p | p.adj | p.adj.signif | r |
|---|---|---|---|---|---|---|---|
| int_derechos | 515 | 466 | 100010.5 | 0.000 | 0.000 | **** | 3193.090 |
| int_just_eco | 515 | 466 | 101819.5 | 0.000 | 0.000 | *** | 3250.846 |
| int_tecnologia | 515 | 466 | 100308.0 | 0.000 | 0.000 | **** | 3202.588 |
| sup_der_hum | 515 | 466 | 107063.0 | 0.000 | 0.000 | *** | 3418.259 |
| int_digital | 515 | 466 | 104634.0 | 0.000 | 0.001 | ** | 3340.707 |
| int_intercult | 515 | 466 | 103251.5 | 0.000 | 0.001 | *** | 3296.567 |
| int_just_amb | 515 | 466 | 104412.5 | 0.000 | 0.001 | ** | 3333.635 |
| int_rel_educ | 515 | 466 | 103917.0 | 0.000 | 0.001 | *** | 3317.814 |
| sup_pacifismo | 515 | 466 | 109548.0 | 0.002 | 0.007 | ** | 3497.598 |
| importancia | 515 | 466 | 107355.5 | 0.003 | 0.009 | ** | 3427.597 |
| int_bienestar | 515 | 466 | 108131.5 | 0.004 | 0.011 |
|
3452.373 |
| int_paz | 515 | 466 | 107823.0 | 0.004 | 0.011 |
|
3442.523 |
| sup_antirac | 515 | 466 | 111850.5 | 0.010 | 0.023 |
|
3571.112 |
| int_genero | 515 | 466 | 109344.5 | 0.014 | 0.029 |
|
3491.101 |
| conoc_tecnologia | 515 | 466 | 110055.0 | 0.019 | 0.039 |
|
3513.786 |
# Gráfico de tamaños del efecto (r) para variables significativas
mwu_res %>%
filter(p.adj < .05) %>%
mutate(
variable = factor(variable, levels = variable[order(r)]),
magnitud = case_when(r >= .5 ~ "Grande (≥ .50)",
r >= .3 ~ "Mediano (.30–.49)",
TRUE ~ "Pequeño (< .30)")
) %>%
ggplot(aes(x = variable, y = r, fill = magnitud)) +
geom_col() +
scale_fill_manual(values = c("Grande (≥ .50)" = azul1,
"Mediano (.30–.49)" = azul3,
"Pequeño (< .30)" = azul6),
name = "Magnitud efecto") +
coord_flip() +
labs(title = "Tamaño del efecto (r) de las diferencias entre contextos",
subtitle = "Solo variables con p.adj < .05 (corrección Benjamini-Hochberg)",
x = NULL, y = "r de Cohen") +
tema_epjgHipótesis: el interés en formarse es significativamente superior al conocimiento actual para cada temática. Test de Wilcoxon de rangos con signo (muestras relacionadas, mismo sujeto responde ambas escalas).
# Normalidad de las diferencias (conoc - interés) por temática
temas_cod <- c("genero","paz","derechos","just_eco","just_amb",
"intercult","bienestar","rel_educ","digital","tecnologia")
diff_norm <- df %>%
dplyr::select(all_of(paste0("conoc_", temas_cod)),
all_of(paste0("int_", temas_cod))) %>%
dplyr::mutate(across(everything(), as.numeric))
norm_diff <- map_dfr(temas_cod, function(t) {
d <- diff_norm[[paste0("conoc_",t)]] - diff_norm[[paste0("int_",t)]]
d <- d[!is.na(d)]
tibble(
Temática = etiquetas_tema[match(t, temas_cod)],
n = length(d),
KS_D = round(lillie.test(d)$statistic, 3),
KS_p = round(lillie.test(d)$p.value, 3),
Normal = ifelse(lillie.test(d)$p.value > .05, "Sí", "No")
)
})
norm_diff %>%
kable(caption = "Normalidad de las diferencias (conocimiento − interés) por temática") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)| Temática | n | KS_D | KS_p | Normal |
|---|---|---|---|---|
| Género y feminismos | 981 | 0.211 | 0 | No |
| Cultura de paz | 981 | 0.191 | 0 | No |
| Derechos humanos | 981 | 0.198 | 0 | No |
| Justicia econ. y social | 981 | 0.172 | 0 | No |
| Justicia ambiental | 981 | 0.198 | 0 | No |
| Interculturalidad | 981 | 0.209 | 0 | No |
| Bienestar emocional | 981 | 0.235 | 0 | No |
| Relación educativa | 981 | 0.190 | 0 | No |
| Equidad digital | 981 | 0.161 | 0 | No |
| Crít. tecnología | 981 | 0.178 | 0 | No |
library(purrr)
brecha_res <- map_dfr(temas_cod, function(t) {
x <- as.numeric(df[[paste0("conoc_", t)]])
y <- as.numeric(df[[paste0("int_", t)]])
ok <- !is.na(x) & !is.na(y)
wt <- wilcox.test(x[ok], y[ok], paired = TRUE, exact = FALSE)
n <- sum(ok)
tibble(
Temática = etiquetas_tema[match(t, temas_cod)],
Media_conoc = round(mean(x[ok]), 2),
Media_int = round(mean(y[ok]), 2),
Brecha = round(mean(x[ok]) - mean(y[ok]), 2),
W = wt$statistic,
p = round(wt$p.value, 4),
r = round(abs(qnorm(wt$p.value / 2)) / sqrt(n), 3)
)
}) %>%
mutate(p.adj = round(p.adjust(p, method = "BH"), 4),
Sig = case_when(p.adj < .001 ~ "***",
p.adj < .01 ~ "**",
p.adj < .05 ~ "*",
TRUE ~ "ns"))
brecha_res %>%
kable(caption = "Wilcoxon rangos con signo: conocimiento actual vs. interés en formarse") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE) %>%
column_spec(4, bold = TRUE,
color = ifelse(brecha_res$Brecha < 0, azul1, "#c0392b"))| Temática | Media_conoc | Media_int | Brecha | W | p | r | p.adj | Sig |
|---|---|---|---|---|---|---|---|---|
| Género y feminismos | 3.76 | 3.41 | 0.35 | 144177.5 | 0.0000 | 0.231 | 0.0000 | *** |
| Cultura de paz | 3.85 | 3.61 | 0.24 | 137214.0 | 0.0000 | 0.153 | 0.0000 | *** |
| Derechos humanos | 3.67 | 3.60 | 0.07 | 108782.0 | 0.2496 | 0.037 | 0.2496 | ns |
| Justicia econ. y social | 3.41 | 3.58 | -0.17 | 98999.5 | 0.0000 | 0.134 | 0.0000 | *** |
| Justicia ambiental | 3.45 | 3.66 | -0.21 | 77057.5 | 0.0000 | 0.168 | 0.0000 | *** |
| Interculturalidad | 3.71 | 3.76 | -0.05 | 95068.0 | 0.0725 | 0.057 | 0.0864 | ns |
| Bienestar emocional | 3.97 | 4.02 | -0.05 | 84049.5 | 0.0778 | 0.056 | 0.0864 | ns |
| Relación educativa | 3.58 | 3.83 | -0.25 | 80533.0 | 0.0000 | 0.190 | 0.0000 | *** |
| Equidad digital | 3.22 | 3.31 | -0.09 | 102515.0 | 0.0261 | 0.071 | 0.0373 |
|
| Crít. tecnología | 3.28 | 3.51 | -0.23 | 88804.0 | 0.0000 | 0.168 | 0.0000 | *** |
# Visualización de la brecha
brecha_res %>%
mutate(Temática = fct_reorder(Temática, Brecha)) %>%
ggplot(aes(x = Temática, y = Brecha, fill = Brecha < 0)) +
geom_col() +
geom_text(aes(label = str_c(Sig, " r=", r)),
hjust = ifelse(brecha_res %>% arrange(Brecha) %>% pull(Brecha) < 0, -0.1, 1.1),
size = 3, colour = "white") +
scale_fill_manual(values = c("TRUE" = azul1, "FALSE" = "#c0392b"),
labels = c("TRUE" = "Interés > Conocimiento",
"FALSE" = "Conocimiento > Interés"),
name = NULL) +
coord_flip() +
labs(title = "Brecha: conocimiento actual − interés en formarse",
subtitle = "Negativo = el interés supera al conocimiento | * p<.05 ** p<.01 *** p<.001",
x = NULL, y = "Diferencia de medias (conocimiento − interés)") +
tema_epjgHipótesis: la formación académica, los años de experiencia y el régimen del centro predicen el autoconocimiento de la EpJG. Regresión ordinal (MASS::polr) dado que la variable dependiente es Likert 1–5.
# Comprobación de normalidad de los residuos se evalúa post-modelo (ver abajo)
# Verificar distribución de la VD
df %>% filter(!is.na(con_propio)) %>%
count(con_propio) %>%
mutate(prop = percent(n / sum(n), 1)) %>%
kable(caption = "Distribución de 'conocimiento propio EpJG' (VD del modelo)") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)| con_propio | n | prop |
|---|---|---|
| 1 | 283 | 29% |
| 2 | 294 | 30% |
| 3 | 221 | 23% |
| 4 | 158 | 16% |
| 5 | 25 | 3% |
df_mod <- df %>%
dplyr::filter(!is.na(con_propio), !is.na(formacion), !is.na(experiencia),
!is.na(regimen), !is.na(ambito), !is.na(contexto)) %>%
dplyr::mutate(
con_propio_ord = factor(con_propio, levels = 1:5, ordered = TRUE),
formacion = factor(formacion,
levels = c("Grado/Licenciatura","Máster/Postgrado","Doctorado")),
# Colapsar "Privado" en "Concertado" si tiene < 10 casos (evita separación perfecta)
regimen = dplyr::case_when(
regimen %in% c("Concertado","Privado") ~ "Concertado/Privado",
TRUE ~ regimen
) %>% factor(levels = c("Público","Concertado/Privado")),
# Reagrupar experiencia en 4 tramos para evitar niveles con n muy bajo
exp_tramo = dplyr::case_when(
experiencia %in% c("0 a 5 años","6 a 10 años") ~ "0–10 años",
experiencia %in% c("11 a 15 años","16 a 20 años") ~ "11–20 años",
experiencia %in% c("21 a 25 años","26 a 30 años") ~ "21–30 años",
experiencia %in% c("31 a 35 años","Más de 35 años") ~ "> 30 años",
TRUE ~ NA_character_
) %>% factor(levels = c("0–10 años","11–20 años","21–30 años","> 30 años"),
ordered = TRUE),
ambito = dplyr::case_when(
ambito %in% c("Ed. Adultos","Ed. Especial","FP","Bachillerato") ~ "Otros",
TRUE ~ ambito
) %>% factor(),
contexto = factor(contexto, levels = c("Cataluña","España (resto)"))
) %>%
dplyr::filter(!is.na(exp_tramo)) %>%
droplevels() # elimina niveles de factor sin observaciones
# Verificar distribución de predictores (para detectar niveles con n muy bajo)
cat("— Distribución de regimen:\n"); print(table(df_mod$regimen))## — Distribución de regimen:
##
## Público Concertado/Privado
## 918 62
## — Distribución de exp_tramo:
##
## 0–10 años 11–20 años 21–30 años > 30 años
## 420 241 236 83
## — Distribución de ambito:
##
## Artes plásticas y diseño
## 1
## Cap d'estudis
## 1
## CFA
## 1
## Cicle for.grau mitja de decoració ceràmica
## 1
## Cooperación
## 1
## Dirección pedagógica
## 1
## Ed. Infantil
## 70
## Ed. Primaria
## 203
## Ed. Secundaria
## 536
## Educació especfial
## 1
## EEMM
## 1
## Enseñanzas artísticas
## 1
## Enseñanzas Artísticas Superiores
## 2
## enseñanzas artísticas. artes plásticas y diseño
## 1
## equipo directivo
## 1
## ESO, FP, ESA
## 1
## ESO, FPB
## 1
## IFE
## 1
## Logopeda
## 1
## maestra PT
## 1
## Otros
## 149
## Pedagogia terapeutica
## 1
## Pedagogía Terapéutica
## 1
## Todas
## 1
## Universidad
## 1
# Modelo de regresión ordinal (proportional odds)
mod_ord <- polr(con_propio_ord ~ formacion + exp_tramo + regimen + ambito + contexto,
data = df_mod, Hess = TRUE)
# summary() devuelve una tabla con betas Y umbrales (zetas) juntos.
# Los betas son los primeros n = length(mod_ord$coefficients) filas.
sum_ord <- summary(mod_ord)$coefficients # matriz: betas + zetas
n_beta <- length(mod_ord$coefficients) # número de coeficientes de regresión
beta_tab <- sum_ord[seq_len(n_beta), , drop = FALSE] # solo filas de betas
coefs <- beta_tab[, "Value"]
coef_se <- beta_tab[, "Std. Error"]
z_val <- qnorm(0.975)
ci_lower <- coefs - z_val * coef_se
ci_upper <- coefs + z_val * coef_se
z_scores <- coefs / coef_se
p_vals <- 2 * pnorm(abs(z_scores), lower.tail = FALSE)
# Tabla en escala OR
tabla_ord <- tibble(
Predictor = names(coefs),
OR = round(exp(coefs), 3),
IC_inf = round(exp(ci_lower), 3),
IC_sup = round(exp(ci_upper), 3),
z = round(z_scores, 2),
p.value = round(p_vals, 4),
Sig = dplyr::case_when(
p_vals < .001 ~ "***",
p_vals < .01 ~ "**",
p_vals < .05 ~ "*",
TRUE ~ ""
)
)
tabla_ord %>%
kable(caption = "Regresión ordinal — OR (IC 95% Wald) | OR > 1 = mayor probabilidad de mayor conocimiento EpJG") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE) %>%
column_spec(7, bold = TRUE, color = azul1)| Predictor | OR | IC_inf | IC_sup | z | p.value | Sig |
|---|---|---|---|---|---|---|
| formacionMáster/Postgrado | 8.460000e-01 | 0.651 | 1.098000e+00 | -1.26 | 0.2083 | |
| formacionDoctorado | 7.320000e-01 | 0.389 | 1.377000e+00 | -0.97 | 0.3335 | |
| exp_tramo.L | 1.203000e+00 | 0.883 | 1.639000e+00 | 1.17 | 0.2406 | |
| exp_tramo.Q | 9.590000e-01 | 0.729 | 1.261000e+00 | -0.30 | 0.7621 | |
| exp_tramo.C | 9.290000e-01 | 0.730 | 1.183000e+00 | -0.60 | 0.5505 | |
| regimenConcertado/Privado | 2.031000e+00 | 1.261 | 3.270000e+00 | 2.92 | 0.0035 | ** |
| ambitoCap d’estudis | 2.178232e+14 | 0.000 | 3.363079e+188 | 0.16 | 0.8718 | |
| ambitoCFA | 3.967282e+08 | 0.000 | 4.076963e+21 | 1.30 | 0.1953 | |
| ambitoCicle for.grau mitja de decoració ceràmica | 9.887839e+07 | 0.000 | 1.018857e+21 | 1.20 | 0.2285 | |
| ambitoCooperación | 1.968072e+09 | 0.000 | 2.088416e+22 | 1.40 | 0.1620 | |
| ambitoDirección pedagógica | 4.845300e+07 | 0.000 | 5.007219e+20 | 1.16 | 0.2471 | |
| ambitoEd. Infantil | 1.017205e+08 | 0.000 | 9.237866e+20 | 1.21 | 0.2258 | |
| ambitoEd. Primaria | 1.327437e+08 | 0.000 | 1.203355e+21 | 1.23 | 0.2192 | |
| ambitoEd. Secundaria | 1.310258e+08 | 0.000 | 1.187064e+21 | 1.23 | 0.2195 | |
| ambitoEducació especfial | 4.770000e-01 | 0.464 | 4.910000e-01 | -50.19 | 0.0000 | *** |
| ambitoEEMM | 1.239000e+00 | 1.210 | 1.269000e+00 | 17.64 | 0.0000 | *** |
| ambitoEnseñanzas artísticas | 1.318000e+00 | 1.289 | 1.347000e+00 | 24.64 | 0.0000 | *** |
| ambitoEnseñanzas Artísticas Superiores | 3.938812e+07 | 0.000 | 3.915472e+20 | 1.15 | 0.2521 | |
| ambitoenseñanzas artísticas. artes plásticas y diseño | 1.148000e+00 | 1.116 | 1.181000e+00 | 9.63 | 0.0000 | *** |
| ambitoequipo directivo | 2.784981e+08 | 0.000 | 2.862256e+21 | 1.27 | 0.2034 | |
| ambitoESO, FP, ESA | 4.189151e+08 | 0.000 | 4.304571e+21 | 1.30 | 0.1940 | |
| ambitoESO, FPB | 1.044050e+08 | 0.000 | 1.075619e+21 | 1.21 | 0.2271 | |
| ambitoIFE | 9.887839e+07 | 0.000 | 1.018857e+21 | 1.20 | 0.2285 | |
| ambitoLogopeda | 9.750000e-01 | 0.951 | 9.990000e-01 | -2.00 | 0.0451 |
|
| ambitomaestra PT | 1.546509e+09 | 0.000 | 1.641435e+22 | 1.38 | 0.1668 | |
| ambitoOtros | 1.208944e+08 | 0.000 | 1.096240e+21 | 1.22 | 0.2215 | |
| ambitoPedagogia terapeutica | 1.759259e+09 | 0.000 | 1.867517e+22 | 1.39 | 0.1642 | |
| ambitoPedagogía Terapéutica | 3.293303e+08 | 0.000 | 3.387827e+21 | 1.28 | 0.1995 | |
| ambitoTodas | 4.189151e+08 | 0.000 | 4.304571e+21 | 1.30 | 0.1940 | |
| ambitoUniversidad | 1.810249e+14 | 0.000 | 3.617602e+188 | 0.16 | 0.8726 | |
| contextoEspaña (resto) | 9.470000e-01 | 0.749 | 1.197000e+00 | -0.45 | 0.6494 |
# Nota metodológica: en regresión ordinal estimada por máxima verosimilitud (ML)
# no se asume normalidad de residuos. La bondad de ajuste se evalúa con el
# pseudo-R² de McFadden y la comparación con el modelo nulo.
null_ord <- polr(con_propio_ord ~ 1, data = df_mod, Hess = TRUE)
r2_mcfad <- round(1 - as.numeric(logLik(mod_ord)) / as.numeric(logLik(null_ord)), 3)
chi2_lrt <- round(2 * (as.numeric(logLik(mod_ord)) - as.numeric(logLik(null_ord))), 2)
df_lrt <- length(coef(mod_ord)) - length(coef(null_ord))
p_lrt <- round(pchisq(chi2_lrt, df = df_lrt, lower.tail = FALSE), 4)
cat(sprintf(
"\nBondad de ajuste (LRT vs. modelo nulo):\n χ²(%d) = %.2f, p = %.4f\n Pseudo-R² McFadden = %.3f\n",
df_lrt, chi2_lrt, p_lrt, r2_mcfad
))##
## Bondad de ajuste (LRT vs. modelo nulo):
## χ²(31) = 57.36, p = 0.0027
## Pseudo-R² McFadden = 0.020
Hipótesis: existen perfiles diferenciados de docentes según su conocimiento, interés y práctica con la EpJG. Se usa k-medoides (PAM) robusto a outliers; el número óptimo de clústeres se determina con el método de la silueta.
# Variables para el clúster: conocimiento EpJG global, interés global, práctica, apoyo movimientos
df_cl <- df %>%
mutate(
conoc_medio = rowMeans(across(all_of(paste0("conoc_", temas_cod)), as.numeric), na.rm=TRUE),
int_medio = rowMeans(across(all_of(paste0("int_", temas_cod)), as.numeric), na.rm=TRUE),
movs_medio = rowMeans(across(all_of(movs), as.numeric), na.rm=TRUE),
n_trab = rowSums(across(starts_with("trab_"),
~ case_when(.x=="SÍ"~1,.x=="NO"~0,TRUE~NA_real_)),na.rm=TRUE)
) %>%
dplyr::select(contexto, con_propio, con_centro, importancia,
conoc_medio, int_medio, movs_medio, n_trab) %>%
drop_na()
mat_cl <- df_cl %>%
dplyr::select(-contexto) %>%
dplyr::mutate(across(everything(), as.numeric)) %>%
scale()# Número óptimo de clústeres (silueta, k = 2–6)
fviz_nbclust(mat_cl, pam, method = "silhouette", k.max = 6) +
labs(title = "Número óptimo de clústeres (método de la silueta)",
subtitle = "k-medoides (PAM)") +
tema_epjgset.seed(42)
k_opt <- 3 # ajusta según el gráfico anterior
pam_res <- pam(mat_cl, k = k_opt, metric = "euclidean")
df_cl$cluster <- factor(paste0("Perfil ", pam_res$clustering))
# Caracterización de los clústeres
perfil_stats <- df_cl %>%
group_by(cluster) %>%
summarise(
n = n(),
Conoc_EpJG = round(mean(con_propio, na.rm=TRUE), 2),
Imp_EpJG = round(mean(importancia, na.rm=TRUE), 2),
Conoc_temas = round(mean(conoc_medio, na.rm=TRUE), 2),
Int_form = round(mean(int_medio, na.rm=TRUE), 2),
Apoyo_movs = round(mean(movs_medio, na.rm=TRUE), 2),
N_trab = round(mean(n_trab, na.rm=TRUE), 2)
)
perfil_stats %>%
kable(caption = "Caracterización de los perfiles docentes latentes (k-medoides)") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE) %>%
column_spec(1, bold = TRUE, color = azul1)| cluster | n | Conoc_EpJG | Imp_EpJG | Conoc_temas | Int_form | Apoyo_movs | N_trab |
|---|---|---|---|---|---|---|---|
| Perfil 1 | 280 | 3.68 | 4.42 | 4.04 | 3.99 | 4.63 | 8.18 |
| Perfil 2 | 262 | 1.70 | 2.74 | 3.10 | 2.69 | 3.74 | 5.03 |
| Perfil 3 | 439 | 1.86 | 4.02 | 3.59 | 3.96 | 4.68 | 6.96 |
# Visualización 2D
fviz_cluster(pam_res, data = mat_cl,
palette = c(azul1, azul3, azul5),
ellipse.type = "convex",
ggtheme = tema_epjg,
main = "Perfiles docentes latentes (PAM, proyección PCA)")# ¿La pertenencia al clúster varía según el contexto?
tab_cl_ctx <- df_cl %>%
count(cluster, contexto) %>%
group_by(cluster) %>% mutate(prop = percent(n / sum(n), 1))
tab_cl_ctx %>%
pivot_wider(names_from = contexto, values_from = c(n, prop)) %>%
kable(caption = "Distribución de perfiles por contexto") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)| cluster | n_Cataluña | n_España (resto) | prop_Cataluña | prop_España (resto) |
|---|---|---|---|---|
| Perfil 1 | 147 | 133 | 52% | 48% |
| Perfil 2 | 156 | 106 | 60% | 40% |
| Perfil 3 | 212 | 227 | 48% | 52% |
# Chi-cuadrado: ¿hay asociación entre perfil y contexto?
chisq_res <- chisq.test(table(df_cl$cluster, df_cl$contexto))
cat(sprintf("Chi² = %.2f, gl = %d, p = %.4f\n",
chisq_res$statistic, chisq_res$parameter, chisq_res$p.value))## Chi² = 8.33, gl = 2, p = 0.0155