Carregamento de Pacotes e Dados
library(haven)
library(dplyr)
library(ggplot2)
library(broom)
library(knitr)
library(purrr)
library(tidyr)
library(gridExtra)
library(corrplot)
library(car)
# Carregamento da base (assumindo que já está filtrada para Q1 do ESCS)
dados <- read_sav("../2-base-de-analise/PISA2022_LATAM_resiliencia.sav")
# Seleção de variáveis necessárias
variaveis <- c("CNT", "resil_math", "resil_read", "resil_scie", "ICTREG", "ICTEFFIC", "ST004D01T", "ESCS")
variaveis_existentes <- variaveis[variaveis %in% names(dados)]
dados_trabalho <- dados %>% select(all_of(variaveis_existentes))
# Checagem opcional: garantir Q1 de ESCS, caso a base não esteja filtrada
if("ESCS" %in% names(dados_trabalho)){
# Mantém apenas o primeiro quartil dentro da própria amostra (se já estiver filtrada, nada muda)
q1 <- quantile(dados_trabalho$ESCS, probs = 0.25, na.rm = TRUE)
n_before <- nrow(dados_trabalho)
dados_trabalho <- dados_trabalho %>% filter(!is.na(ESCS) & ESCS <= q1)
cat("Observações mantidas após garantir Q1 do ESCS:", nrow(dados_trabalho), "(de", n_before, ")
")
}
## Observações mantidas após garantir Q1 do ESCS: 4788 (de 19143 )
# Limpeza essencial
dados_limpos <- dados_trabalho %>%
filter(!is.na(CNT), !is.na(ICTREG), !is.na(ICTEFFIC),
!is.na(resil_math), !is.na(resil_read), !is.na(resil_scie)) %>%
mutate(
genero = if("ST004D01T" %in% names(.)) ifelse(ST004D01T == 1, "Feminino", "Masculino") else NA_character_,
ICTREG_std = as.numeric(scale(ICTREG)),
ICTEFFIC_std = as.numeric(scale(ICTEFFIC))
) %>%
mutate(genero = if("ST004D01T" %in% names(.)) factor(genero) else NULL)
str(dados_limpos)
## tibble [742 × 11] (S3: tbl_df/tbl/data.frame)
## $ CNT : chr+lbl [1:742] ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG,...
## ..@ label : chr "Country code 3-character"
## ..@ format.spss : chr "A3"
## ..@ display_width: int 3
## ..@ labels : Named chr [1:81] "MDA" "THA" "BRA" "FRA" ...
## .. ..- attr(*, "names")= chr [1:81] "Republic of Moldova" "Thailand" "Brazil" "France" ...
## $ resil_math : num [1:742] 0 0 0 0 0 0 0 0 0 0 ...
## ..- attr(*, "format.spss")= chr "F8.0"
## $ resil_read : num [1:742] 0 0 0 0 0 0 0 0 0 0 ...
## ..- attr(*, "format.spss")= chr "F8.0"
## $ resil_scie : num [1:742] 0 0 0 1 0 0 0 0 0 0 ...
## ..- attr(*, "format.spss")= chr "F8.0"
## $ ICTREG : dbl+lbl [1:742] 0.1612, 0.6260, 3.2020, 0.3759, 1.1799, 0.1169, ...
## ..@ label : chr "Views of regulated ICT use in school (WLE)"
## ..@ format.spss: chr "F7.4"
## ..@ labels : Named num [1:4] 95 97 98 99
## .. ..- attr(*, "names")= chr [1:4] "Valid Skip" "Not Applicable" "Invalid" "No Response"
## $ ICTEFFIC : dbl+lbl [1:742] 0.0490, -1.1925, -0.5172, -1.2300, 0.2302, 0.6282, ...
## ..@ label : chr "Self-efficacy in digital competencies (WLE)"
## ..@ format.spss: chr "F7.4"
## ..@ labels : Named num [1:4] 95 97 98 99
## .. ..- attr(*, "names")= chr [1:4] "Valid Skip" "Not Applicable" "Invalid" "No Response"
## $ ST004D01T : dbl+lbl [1:742] 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, ...
## ..@ label : chr "Student (Standardized) Gender"
## ..@ format.spss: chr "F1.0"
## ..@ labels : Named num [1:6] 1 2 5 7 8 9
## .. ..- attr(*, "names")= chr [1:6] "Female" "Male" "Valid Skip" "Not Applicable" ...
## $ ESCS : dbl+lbl [1:742] -2.90, -2.98, -2.89, -3.09, -3.12, -3.22, -3.16, -3.20...
## ..@ label : chr "Index of economic, social and cultural status"
## ..@ format.spss: chr "F7.4"
## ..@ labels : Named num [1:4] 95 97 98 99
## .. ..- attr(*, "names")= chr [1:4] "Valid Skip" "Not Applicable" "Invalid" "No Response"
## $ genero : Factor w/ 2 levels "Feminino","Masculino": 2 2 2 1 2 2 2 1 1 1 ...
## $ ICTREG_std : num [1:742] -0.0266 0.3504 2.4396 0.1475 0.7996 ...
## $ ICTEFFIC_std: num [1:742] 0.707 -0.446 0.181 -0.481 0.875 ...
cat("Amostra final:", nrow(dados_limpos), "observações; Países:", length(unique(dados_limpos$CNT)), "
")
## Amostra final: 742 observações; Países: 6
Estratégia de Modelagem
Serão estimados, para cada disciplina, três modelos: - Modelo 1:
ICTREG_std + ICTEFFIC_std - Modelo 2: Modelo 1 + gênero - Modelo 3:
Modelo 2 + efeitos fixos de país (CNT)
fit_series <- function(df, y){
# Constrói fórmulas
f1 <- as.formula(paste(y, "~ ICTREG_std + ICTEFFIC_std"))
f2 <- as.formula(paste(y, "~ ICTREG_std + ICTEFFIC_std + genero"))
f3 <- as.formula(paste(y, "~ ICTREG_std + ICTEFFIC_std + genero + CNT"))
# Ajuste com tryCatch para robustez
safe_glm <- function(form){
tryCatch(glm(form, data = df, family = binomial(link = "logit")), error = function(e) NULL)
}
m1 <- safe_glm(f1)
m2 <- if("genero" %in% names(df)) safe_glm(f2) else NULL
m3 <- if(!is.null(m2)) safe_glm(f3) else if("genero" %in% names(df)) NULL else safe_glm(as.formula(paste(y, "~ ICTREG_std + ICTEFFIC_std + CNT")))
list(m1 = m1, m2 = m2, m3 = m3)
}
extract_table <- function(model, nome){
if(is.null(model)) return(NULL)
out <- tidy(model)
# filtra apenas termos de interesse
out <- out %>% filter(grepl("ICTREG_std|ICTEFFIC_std|genero", term)) %>%
mutate(
modelo = nome,
OR = exp(estimate),
OR_lower = exp(estimate - 1.96*std.error),
OR_upper = exp(estimate + 1.96*std.error),
sig = ifelse(p.value < 0.05, "Sim", "Não")
) %>%
select(modelo, term, estimate, std.error, OR, OR_lower, OR_upper, statistic, p.value, sig)
out
}
Matemática
mods_math <- fit_series(dados_limpos, "resil_math")
res_math <- bind_rows(
extract_table(mods_math$m1, "Modelo 1: ICT"),
extract_table(mods_math$m2, "Modelo 2: ICT + Gênero"),
extract_table(mods_math$m3, "Modelo 3: ICT + Gênero + País")
)
kable(res_math, digits = 4, caption = "Regressão Logística Múltipla - Matemática (Q1 ESCS)")
Regressão Logística Múltipla - Matemática (Q1 ESCS)
| Modelo 1: ICT |
ICTREG_std |
0.2132 |
0.1575 |
1.2377 |
0.9090 |
1.6851 |
1.3542 |
0.1757 |
Não |
| Modelo 1: ICT |
ICTEFFIC_std |
0.3645 |
0.1311 |
1.4398 |
1.1135 |
1.8616 |
2.7798 |
0.0054 |
Sim |
| Modelo 2: ICT + Gênero |
ICTREG_std |
0.2067 |
0.1578 |
1.2296 |
0.9024 |
1.6753 |
1.3094 |
0.1904 |
Não |
| Modelo 2: ICT + Gênero |
ICTEFFIC_std |
0.3645 |
0.1311 |
1.4399 |
1.1135 |
1.8618 |
2.7801 |
0.0054 |
Sim |
| Modelo 2: ICT + Gênero |
generoMasculino |
0.1220 |
0.2871 |
1.1298 |
0.6435 |
1.9834 |
0.4249 |
0.6709 |
Não |
| Modelo 3: ICT + Gênero + País |
ICTREG_std |
0.2406 |
0.1648 |
1.2720 |
0.9209 |
1.7569 |
1.4600 |
0.1443 |
Não |
| Modelo 3: ICT + Gênero + País |
ICTEFFIC_std |
0.3231 |
0.1331 |
1.3815 |
1.0643 |
1.7931 |
2.4283 |
0.0152 |
Sim |
| Modelo 3: ICT + Gênero + País |
generoMasculino |
0.1288 |
0.2903 |
1.1375 |
0.6439 |
2.0092 |
0.4437 |
0.6572 |
Não |
comp_math <- data.frame(
Modelo = c("M1", "M2", "M3"),
AIC = c(if(!is.null(mods_math$m1)) AIC(mods_math$m1) else NA,
if(!is.null(mods_math$m2)) AIC(mods_math$m2) else NA,
if(!is.null(mods_math$m3)) AIC(mods_math$m3) else NA),
BIC = c(if(!is.null(mods_math$m1)) BIC(mods_math$m1) else NA,
if(!is.null(mods_math$m2)) BIC(mods_math$m2) else NA,
if(!is.null(mods_math$m3)) BIC(mods_math$m3) else NA)
)
kable(comp_math, digits = 2, caption = "Comparação de Modelos - Matemática")
Comparação de Modelos - Matemática
| M1 |
382.90 |
396.73 |
| M2 |
384.72 |
403.16 |
| M3 |
383.63 |
425.11 |
Leitura
mods_read <- fit_series(dados_limpos, "resil_read")
res_read <- bind_rows(
extract_table(mods_read$m1, "Modelo 1: ICT"),
extract_table(mods_read$m2, "Modelo 2: ICT + Gênero"),
extract_table(mods_read$m3, "Modelo 3: ICT + Gênero + País")
)
kable(res_read, digits = 4, caption = "Regressão Logística Múltipla - Leitura (Q1 ESCS)")
Regressão Logística Múltipla - Leitura (Q1 ESCS)
| Modelo 1: ICT |
ICTREG_std |
0.0361 |
0.1396 |
1.0368 |
0.7886 |
1.3631 |
0.2589 |
0.7957 |
Não |
| Modelo 1: ICT |
ICTEFFIC_std |
0.4104 |
0.1219 |
1.5074 |
1.1870 |
1.9142 |
3.3658 |
0.0008 |
Sim |
| Modelo 2: ICT + Gênero |
ICTREG_std |
0.0417 |
0.1405 |
1.0425 |
0.7916 |
1.3730 |
0.2965 |
0.7669 |
Não |
| Modelo 2: ICT + Gênero |
ICTEFFIC_std |
0.4107 |
0.1220 |
1.5078 |
1.1872 |
1.9149 |
3.3673 |
0.0008 |
Sim |
| Modelo 2: ICT + Gênero |
generoMasculino |
-0.1175 |
0.2738 |
0.8891 |
0.5199 |
1.5205 |
-0.4292 |
0.6677 |
Não |
| Modelo 3: ICT + Gênero + País |
ICTREG_std |
0.0695 |
0.1467 |
1.0719 |
0.8040 |
1.4291 |
0.4735 |
0.6358 |
Não |
| Modelo 3: ICT + Gênero + País |
ICTEFFIC_std |
0.3936 |
0.1238 |
1.4824 |
1.1629 |
1.8896 |
3.1790 |
0.0015 |
Sim |
| Modelo 3: ICT + Gênero + País |
generoMasculino |
-0.1185 |
0.2764 |
0.8882 |
0.5167 |
1.5268 |
-0.4289 |
0.6680 |
Não |
comp_read <- data.frame(
Modelo = c("M1", "M2", "M3"),
AIC = c(if(!is.null(mods_read$m1)) AIC(mods_read$m1) else NA,
if(!is.null(mods_read$m2)) AIC(mods_read$m2) else NA,
if(!is.null(mods_read$m3)) AIC(mods_read$m3) else NA),
BIC = c(if(!is.null(mods_read$m1)) BIC(mods_read$m1) else NA,
if(!is.null(mods_read$m2)) BIC(mods_read$m2) else NA,
if(!is.null(mods_read$m3)) BIC(mods_read$m3) else NA)
)
kable(comp_read, digits = 2, caption = "Comparação de Modelos - Leitura")
Comparação de Modelos - Leitura
| M1 |
421.37 |
435.20 |
| M2 |
423.19 |
441.63 |
| M3 |
424.99 |
466.47 |
Ciências
mods_scie <- fit_series(dados_limpos, "resil_scie")
res_scie <- bind_rows(
extract_table(mods_scie$m1, "Modelo 1: ICT"),
extract_table(mods_scie$m2, "Modelo 2: ICT + Gênero"),
extract_table(mods_scie$m3, "Modelo 3: ICT + Gênero + País")
)
kable(res_scie, digits = 4, caption = "Regressão Logística Múltipla - Ciências (Q1 ESCS)")
Regressão Logística Múltipla - Ciências (Q1 ESCS)
| Modelo 1: ICT |
ICTREG_std |
0.0728 |
0.1510 |
1.0755 |
0.8000 |
1.4458 |
0.4819 |
0.6299 |
Não |
| Modelo 1: ICT |
ICTEFFIC_std |
0.4523 |
0.1282 |
1.5720 |
1.2227 |
2.0210 |
3.5282 |
0.0004 |
Sim |
| Modelo 2: ICT + Gênero |
ICTREG_std |
0.0657 |
0.1512 |
1.0679 |
0.7939 |
1.4364 |
0.4344 |
0.6640 |
Não |
| Modelo 2: ICT + Gênero |
ICTEFFIC_std |
0.4523 |
0.1282 |
1.5720 |
1.2226 |
2.0212 |
3.5275 |
0.0004 |
Sim |
| Modelo 2: ICT + Gênero |
generoMasculino |
0.1462 |
0.2877 |
1.1575 |
0.6586 |
2.0342 |
0.5083 |
0.6112 |
Não |
| Modelo 3: ICT + Gênero + País |
ICTREG_std |
0.1038 |
0.1586 |
1.1093 |
0.8129 |
1.5139 |
0.6540 |
0.5131 |
Não |
| Modelo 3: ICT + Gênero + País |
ICTEFFIC_std |
0.4249 |
0.1298 |
1.5294 |
1.1858 |
1.9727 |
3.2724 |
0.0011 |
Sim |
| Modelo 3: ICT + Gênero + País |
generoMasculino |
0.1456 |
0.2898 |
1.1567 |
0.6555 |
2.0412 |
0.5023 |
0.6154 |
Não |
comp_scie <- data.frame(
Modelo = c("M1", "M2", "M3"),
AIC = c(if(!is.null(mods_scie$m1)) AIC(mods_scie$m1) else NA,
if(!is.null(mods_scie$m2)) AIC(mods_scie$m2) else NA,
if(!is.null(mods_scie$m3)) AIC(mods_scie$m3) else NA),
BIC = c(if(!is.null(mods_scie$m1)) BIC(mods_scie$m1) else NA,
if(!is.null(mods_scie$m2)) BIC(mods_scie$m2) else NA,
if(!is.null(mods_scie$m3)) BIC(mods_scie$m3) else NA)
)
kable(comp_scie, digits = 2, caption = "Comparação de Modelos - Ciências")
Comparação de Modelos - Ciências
| M1 |
380.60 |
394.42 |
| M2 |
382.34 |
400.78 |
| M3 |
387.23 |
428.71 |
Visualização Comparativa
all_res <- bind_rows(
res_math %>% mutate(disciplina = "Matemática"),
res_read %>% mutate(disciplina = "Leitura"),
res_scie %>% mutate(disciplina = "Ciências")
)
p <- ggplot(all_res, aes(x = modelo, y = OR, color = term)) +
geom_point(position = position_dodge(width = 0.3), size = 3) +
geom_errorbar(aes(ymin = OR_lower, ymax = OR_upper), position = position_dodge(width = 0.3), width = 0.2) +
geom_hline(yintercept = 1, linetype = "dashed", color = "red") +
facet_wrap(~disciplina, scales = "free_y") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(title = "Efeitos de ICTREG e ICTEFFIC (Q1 ESCS)", x = "Modelo", y = "OR (IC 95%)", color = "Variável") +
scale_color_manual(values = c("ICTREG_std" = "blue", "ICTEFFIC_std" = "green"), labels = c("ICTREG", "ICTEFFIC"))
print(p)

# Tabela resumo do modelo final (M3)
resumo_final <- all_res %>% filter(modelo == "Modelo 3: ICT + Gênero + País") %>%
arrange(disciplina, term)
kable(resumo_final, digits = 4, caption = "Resumo dos Efeitos (Modelo Final, M3)")
Resumo dos Efeitos (Modelo Final, M3)
| Modelo 3: ICT + Gênero + País |
ICTEFFIC_std |
0.4249 |
0.1298 |
1.5294 |
1.1858 |
1.9727 |
3.2724 |
0.0011 |
Sim |
Ciências |
| Modelo 3: ICT + Gênero + País |
ICTREG_std |
0.1038 |
0.1586 |
1.1093 |
0.8129 |
1.5139 |
0.6540 |
0.5131 |
Não |
Ciências |
| Modelo 3: ICT + Gênero + País |
generoMasculino |
0.1456 |
0.2898 |
1.1567 |
0.6555 |
2.0412 |
0.5023 |
0.6154 |
Não |
Ciências |
| Modelo 3: ICT + Gênero + País |
ICTEFFIC_std |
0.3936 |
0.1238 |
1.4824 |
1.1629 |
1.8896 |
3.1790 |
0.0015 |
Sim |
Leitura |
| Modelo 3: ICT + Gênero + País |
ICTREG_std |
0.0695 |
0.1467 |
1.0719 |
0.8040 |
1.4291 |
0.4735 |
0.6358 |
Não |
Leitura |
| Modelo 3: ICT + Gênero + País |
generoMasculino |
-0.1185 |
0.2764 |
0.8882 |
0.5167 |
1.5268 |
-0.4289 |
0.6680 |
Não |
Leitura |
| Modelo 3: ICT + Gênero + País |
ICTEFFIC_std |
0.3231 |
0.1331 |
1.3815 |
1.0643 |
1.7931 |
2.4283 |
0.0152 |
Sim |
Matemática |
| Modelo 3: ICT + Gênero + País |
ICTREG_std |
0.2406 |
0.1648 |
1.2720 |
0.9209 |
1.7569 |
1.4600 |
0.1443 |
Não |
Matemática |
| Modelo 3: ICT + Gênero + País |
generoMasculino |
0.1288 |
0.2903 |
1.1375 |
0.6439 |
2.0092 |
0.4437 |
0.6572 |
Não |
Matemática |