Governo Eletrônico no Brasil: Análise Longitudinal 2015–2025

Replicação e expansão de Vargas, Macadar, Wanke & Antunes (2021)

Autor

Marcus Ramalho

Data de Publicação

22 de abril de 2026

1 Introdução

Este documento replica e expande a análise de Vargas, Macadar, Wanke & Antunes (2021), publicada nos Cadernos EBAPE.BR, que investigou os fatores que influenciam o uso de serviços de governo eletrônico (e-gov) pelos cidadãos brasileiros.

O estudo original analisou apenas os microdados da pesquisa TIC Domicílios 2019, usando regressão logística para modelar a probabilidade de uso de e-gov a partir de variáveis sociodemográficas. Aqui, replicamos o modelo para todos os anos de 2015 a 2025 (10 edições — 2020 excluído por ausência do módulo G), comparamos a evolução dos coeficientes e interpretamos as mudanças ao longo da década.

1.0.1 Principais achados do artigo original (2019)

Indicador Valor
N (após filtros) 11.781
Accuracy 0,7314
F1-score 0,8023
Recall 0,8428
Precision 0,7656

Variáveis significativas: idade (−), PEA (+), e-commerce (+), grau de instrução (+), classe econômica (+), renda familiar (+), dispositivo de acesso (+). Variáveis não significativas: sexo, região geográfica, área urbana/rural.

2 Setup

Carregar pacotes
suppressPackageStartupMessages({
  library(tidyverse)
  library(haven)
  library(broom)
  library(pROC)
  library(nnet)
  library(caret)
  library(fastDummies)
  library(plotly)
  library(gganimate)
  library(gifski)
  library(scales)
  library(rpart)
  library(rpart.plot)
  library(ranger)
})

# Tema padrao para graficos
tema <- theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", size = 15),
    plot.subtitle = element_text(color = "grey40", size = 11),
    legend.position = "bottom",
    panel.grid.minor = element_blank()
  )

theme_set(tema)

dir.create("dados", showWarnings = FALSE)

# Formatadores pt-BR para inline R
fmt_pct <- function(x) scales::percent(x, accuracy = 0.1, decimal.mark = ",")
fmt_n   <- function(x) format(x, big.mark = ".", decimal.mark = ",")
fmt_c   <- function(x) formatC(x, format = "f", digits = 3, decimal.mark = ",")
fmt_c4  <- function(x) formatC(x, format = "f", digits = 4, decimal.mark = ",")

3 Download dos Microdados

Os microdados da pesquisa TIC Domicílios estão disponíveis no site do Cetic.br. Baixamos a base de indivíduos (.sav) de cada ano, que contém as variáveis sociodemográficas e o módulo G de governo eletrônico.

AvisoEdição 2020 excluída

A edição 2020 teve metodologia adaptada por causa da pandemia (coleta por telefone CATI). O módulo G (governo eletrônico) não foi coletado, impossibilitando a inclusão na análise longitudinal.

Download dos arquivos .sav
urls <- tribble(
  ~ano, ~url, ~encoding,
  2015, "https://cetic.br/media/microdados/217/ticdom_2015_individuos_base_de_microdados_v1.2.sav", "UTF-8",
  2016, "https://cetic.br/media/microdados/221/ticdom_2016_individuos_base_de_microdados_v1.2.sav", "latin1",
  2017, "https://cetic.br/media/microdados/223/ticdom_2017_individuos_base_de_microdados_v1.5.sav", "latin1",
  2018, "https://cetic.br/media/microdados/209/ticdom_2018_individuos_base_de_microdados_v1.0.sav", "UTF-8",
  2019, "https://cetic.br/media/microdados/582/ticdom_2019_individuos_base_de_microdados_v1.1.sav", "latin1",
  2021, "https://cetic.br/media/microdados/619/tic_domicilios_2021_individuos_base_de_microdados_v1.0.sav", "UTF-8",
  2022, "https://cetic.br/media/microdados/694/tic_domicilios_2022_individuos_base_de_microdados_v1.0.sav", "UTF-8",
  2023, "https://cetic.br/media/microdados/754/tic_domicilios_2023_individuos_base_de_microdados_v1.0.sav", "UTF-8",
  2024, "https://cetic.br/media/microdados/861/tic_domicilios_2024_individuos_base_de_microdados_v1.0.sav", "UTF-8",
  2025, "https://cetic.br/media/microdados/988/tic_domicilios_2025_individuos_base_de_microdados_v1.0.sav", "UTF-8"
)

urls %>%
  pwalk(function(ano, url, encoding) {
    dest <- str_glue("dados/tic_ind_{ano}.sav")
    if (!file.exists(dest)) {
      cat(str_glue("[{ano}] Baixando..."), "\n")
      tryCatch(
        download.file(url, dest, mode = "wb", quiet = TRUE),
        error = function(e) cat(str_glue("[{ano}] ERRO: {e$message}"), "\n")
      )
    }
  })

cat("Arquivos disponíveis:\n")
Arquivos disponíveis:
Download dos arquivos .sav
list.files("dados", pattern = "tic_ind.*\\.sav") %>% walk(~ cat(" ", .x, "\n"))
  tic_ind_2015.sav 
  tic_ind_2016.sav 
  tic_ind_2017.sav 
  tic_ind_2018.sav 
  tic_ind_2019.sav 
  tic_ind_2021.sav 
  tic_ind_2022.sav 
  tic_ind_2023.sav 
  tic_ind_2024.sav 
  tic_ind_2025.sav 

4 Harmonização de Variáveis

O Cetic.br muda nomes de variáveis entre edições. A estratégia é:

  1. Converter todos os nomes para MAIÚSCULAS
  2. Buscar cada variável por padrão regex (prioridade para variantes agregadas)
  3. Reconstruir G1_AGREG quando ausente (2015, 2016) a partir das variáveis individuais G1_A a G1_G
NotaDecisões de harmonização

As seguintes inconsistências entre edições foram identificadas e tratadas:

Variável Problema Solução
G1_AGREG Não existe em 2015 e 2016 Reconstruída como any(G1_A:G1_G == 1)
Grau de instrução 2015–2023: GRAU_INSTRUCAO_2 (4 níveis); 2024–2025: GRAU_INST_1 (4 níveis, nome diferente); existe também GRAU_INSTRUCAO_1 detalhado (20 níveis) Regex prioriza _2 > GRAU_INST_1 > fallback genérico
C5_Dispositivos 2024–2025 incluem nível 4 (“Nenhum dispositivo”), inexistente em 2015–2023 Nível 4 filtrado junto com 97/98/99 para manter 3 categorias comparáveis
C5_Dispositivos Não existe em 2015 2015 entra no modelo sem essa variável (menos termos)
Encoding .sav 2016, 2017 e 2019: encoding latin1 Especificado encoding = "latin1" no read_sav()
G1_H Nova questão em 2025 (Justiça) G1_AGREG já vem calculada pelo Cetic.br incluindo G1_H; mantida como está
Carregar e harmonizar variáveis de cada ano
carregar_e_harmonizar <- function(ano, encoding) {
  path <- str_glue("dados/tic_ind_{ano}.sav")
  if (!file.exists(path)) return(NULL)

  df <- read_sav(path, encoding = encoding) %>%
    rename_with(str_to_upper)

  # Buscar coluna por padrao regex
  encontrar <- function(padroes) {
    for (p in padroes) {
      match <- str_which(names(df), regex(p, ignore_case = TRUE))
      if (length(match) > 0) return(names(df)[match[1]])
    }
    NA_character_
  }

  # Mapear variaveis
  col_g1_agreg    <- encontrar(c("^G1_AGREG$"))
  col_c1          <- encontrar(c("^C1$"))
  col_sexo        <- encontrar(c("^SEXO$"))
  col_idade       <- encontrar(c("^IDADE$"))
  col_pea         <- encontrar(c("^PEA_?2$", "^PEA$"))
  col_h2          <- encontrar(c("^H2$"))
  col_j5          <- encontrar(c("^J5$"))
  col_renda       <- encontrar(c("^RENDA.*FAM"))
  col_classe      <- encontrar(c("^CLASSE.*CB", "^CLASSE.*2015"))
  col_grau        <- encontrar(c("^GRAU.*INSTR.*2$", "^GRAU_INST_1$", "^GRAU.*INSTR"))
  col_c5          <- encontrar(c("^C5.*DISP"))
  col_area        <- encontrar(c("^AREA$"))
  col_regiao      <- encontrar(c("^COD.*REGIAO.*2$", "^COD.*REGIAO", "^REGIAO"))
  col_raca        <- encontrar(c("^RACA$", "^COR"))

  # Reconstruir G1_AGREG se ausente
  if (is.na(col_g1_agreg)) {
    g1_cols <- names(df)[str_detect(names(df), regex("^G1_[A-G]$", ignore_case = TRUE))]
    if (length(g1_cols) >= 7) {
      df <- df %>%
        mutate(G1_AGREG_CALC = if_else(
          if_any(all_of(g1_cols), ~ as.numeric(.) == 1), 1, 0
        ))
      col_g1_agreg <- "G1_AGREG_CALC"
    } else {
      return(NULL)
    }
  }

  # Montar mapa
  mapa <- c(
    g1_agreg = col_g1_agreg, c1 = col_c1,
    sexo = col_sexo, idade = col_idade, pea = col_pea,
    h2 = col_h2, j5 = col_j5, renda_familiar = col_renda,
    classe_cb = col_classe, grau_instrucao = col_grau,
    c5_dispositivos = col_c5, area = col_area, cod_regiao = col_regiao,
    raca = col_raca
  ) %>% purrr::discard(is.na)

  # Checar obrigatorias
  faltantes <- c("g1_agreg", "c1", "idade", "pea", "h2", "renda_familiar", "grau_instrucao") %>%
    setdiff(names(mapa))
  if (length(faltantes) > 0) return(NULL)

  df %>%
    select(all_of(mapa)) %>%
    mutate(across(everything(), as.numeric), ano = ano)
}

dados_brutos <- urls %>%
  pmap(~ carregar_e_harmonizar(..1, ..3)) %>%
  compact()

cat(str_glue("Anos carregados com sucesso: {length(dados_brutos)}\n"))
Anos carregados com sucesso: 10
Carregar e harmonizar variáveis de cada ano
cat("Anos:", dados_brutos %>% map_dbl(~ unique(.x$ano)) %>% sort() %>% str_c(collapse = ", "), "\n")
Anos: 2015, 2016, 2017, 2018, 2019, 2021, 2022, 2023, 2024, 2025 

5 Filtros e Recodificações

Aplicamos exatamente os mesmos filtros do estudo original (Figura 1 do artigo):

  1. C1 = 1: somente quem respondeu “Sim” a “Já usou a Internet?” (exclui 0=Não, 97=Não sabe, 98=Não respondeu)
  2. Remover 97/98/99: respostas indefinidas em H2, J5, renda, C5
  3. Idade ≥ 16: somente maiores de 16 anos
  4. Recodificar PEA, classe econômica, renda, área conforme Quadro 4 do artigo
Aplicar filtros e recodificações
preparar_dados <- function(df) {
  ano_val <- unique(df$ano)
  n0 <- nrow(df)

  # Filtro C1 (somente quem respondeu "Sim" a "Já usou a Internet?")
  # O artigo usa C1 == 1 (exclui 0=Não, 97=Não sabe, 98=Não respondeu)
  df <- df %>% filter(c1 == 1)
  n1 <- nrow(df)

  # Remover c1
  df <- df %>% select(-c1)

  # Excluir indefinidas (97, 98, 99)
  df <- df %>% filter(!h2 %in% c(97, 98, 99))
  if ("j5" %in% names(df)) df <- df %>% filter(!j5 %in% c(97, 98, 99))
  df <- df %>% filter(!renda_familiar %in% c(97, 98, 99))
  # C5: remover 4 (Nenhum dispositivo, novo em 2024+) alem de 97/98/99
  if ("c5_dispositivos" %in% names(df)) df <- df %>% filter(!c5_dispositivos %in% c(4, 97, 98, 99))
  n2 <- nrow(df)

  # Idade >= 16
  df <- df %>% filter(idade >= 16)
  n3 <- nrow(df)

  # Recodificacoes (Quadro 4)
  df <- df %>%
    mutate(
      pea = case_when(pea == 1 ~ 1, pea == 2 ~ 0, TRUE ~ NA_real_),
      renda_familiar = if_else(renda_familiar == 9, 0, renda_familiar),
      area = if_else(area == 1, 1, 0),
      g1_agreg = if_else(g1_agreg == 1, 1, 0),
      # Sexo: 1=Masc, 2=Fem -> 0=Masc, 1=Fem
      sexo = if_else(sexo == 2, 1, 0)
    )

  if ("classe_cb" %in% names(df)) {
    df <- df %>%
      mutate(classe_cb = case_when(
        classe_cb == 1 ~ 3, classe_cb == 2 ~ 2,
        classe_cb == 3 ~ 1, classe_cb == 4 ~ 0,
        TRUE ~ NA_real_
      ))
  }

  # Raca: remover 98 (Nao respondeu); manter 1-5
  if ("raca" %in% names(df)) {
    df <- df %>%
      mutate(raca = if_else(raca %in% c(97, 98, 99), NA_real_, raca))
  }

  tibble(ano = ano_val, etapa = c("Bruto", "Internet (C1)", "Sem indef.", "Idade ≥ 16"),
         n = c(n0, n1, n2, n3)) -> pipeline_info

  list(dados = df, pipeline = pipeline_info)
}

resultados_prep <- dados_brutos %>% map(preparar_dados)
dados_prep <- resultados_prep %>% map("dados") %>% compact()
pipeline_info <- resultados_prep %>% map_dfr("pipeline")
Ver código
pipeline_info %>%
  pivot_wider(names_from = etapa, values_from = n) %>%
  knitr::kable(format.args = list(big.mark = "."))
Tabela 1: Pipeline de filtragem por ano
ano Bruto Internet (C1) Sem indef. Idade ≥ 16
2.015 20.397 12.038 9.496 8.506
2.016 20.722 12.815 10.051 9.072
2.017 20.490 13.633 11.639 10.470
2.018 20.544 14.080 12.210 11.081
2.019 20.536 14.701 12.884 11.781
2.021 21.011 15.981 14.069 12.914
2.022 20.688 15.738 13.672 12.648
2.023 21.271 16.664 14.647 13.533
2.024 21.170 17.069 15.204 14.144
2.025 24.535 19.921 17.464 16.373

6 Estatísticas Descritivas

Ver código
descritivas <- dados_prep %>%
  map_dfr(function(df) {
    tibble(
      ano = unique(df$ano),
      n = nrow(df),
      prop_egov = mean(df$g1_agreg, na.rm = TRUE),
      idade_media = mean(df$idade, na.rm = TRUE),
      prop_pea = mean(df$pea, na.rm = TRUE),
      prop_h2 = mean(df$h2, na.rm = TRUE)
    )
  })
Ver código
descritivas %>%
  mutate(
    prop_egov = percent(prop_egov, accuracy = 0.1),
    prop_pea = percent(prop_pea, accuracy = 0.1),
    prop_h2 = percent(prop_h2, accuracy = 0.1),
    idade_media = round(idade_media, 1)
  ) %>%
  rename(
    Ano = ano, N = n, `% E-gov` = prop_egov,
    `Idade média` = idade_media, `% PEA` = prop_pea, `% E-commerce` = prop_h2
  ) %>%
  knitr::kable(format.args = list(big.mark = "."))
Tabela 2: Estatísticas descritivas por ano
Ano N % E-gov Idade média % PEA % E-commerce
2.015 8.506 58.1% 34.2 83.9% 39.9%
2.016 9.072 60.6% 35.0 82.3% 40.3%
2.017 10.470 61.3% 36.6 80.9% 35.3%
2.018 11.081 52.6% 37.5 80.3% 34.6%
2.019 11.781 64.7% 38.7 79.7% 38.4%
2.021 12.914 67.1% 39.0 76.3% 38.9%
2.022 12.648 61.4% 39.4 76.2% 36.8%
2.023 13.533 67.7% 40.9 74.4% 42.1%
2.024 14.144 52.9% 41.9 70.3% 36.5%
2.025 16.373 66.3% 42.0 68.2% 41.6%
Ver código
p_desc <- descritivas %>%
  select(ano, `E-gov` = prop_egov, PEA = prop_pea, `E-commerce` = prop_h2) %>%
  pivot_longer(-ano, names_to = "Indicador", values_to = "Proporção") %>%
  ggplot(aes(x = ano, y = `Proporção`, color = Indicador)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2.5) +
  scale_y_continuous(labels = percent) +
  scale_x_continuous(breaks = descritivas$ano) +
  labs(x = "Ano", y = "Proporção", color = NULL)

ggplotly(p_desc) %>%
  layout(legend = list(orientation = "h", y = -0.15))
Figura 1: Evolução das características da amostra (após filtros)

Três tendências estruturais se destacam na composição da amostra ao longo da década, todas com implicações diretas para a interpretação dos modelos:

Idade média da amostra. A idade média subiu de 34.2 anos (2015) para 42 anos (2025). Em 2019 — ano-base do artigo original — a média era 38.7 anos. Esse envelhecimento reflete a universalização do acesso à internet entre faixas etárias mais velhas. Como a idade tem efeito negativo sobre o uso de e-gov, a estabilidade do coeficiente de idade ao longo dos anos (ver Seção 8) torna-se ainda mais relevante: a barreira etária persiste mesmo com a popularização.

Proporção de PEA na amostra. A parcela de economicamente ativos caiu de 83,9% (2015) para 68,2% (2025). Isso indica que a internet se expandiu para aposentados, estudantes e pessoas fora do mercado de trabalho. Vargas et al. (2021) encontraram a PEA como preditor significativo em 2019 (quando 79,7% eram PEA) — a queda dessa proporção ajuda a explicar por que o coeficiente da PEA pode ter se enfraquecido nos anos recentes.

E-commerce. A proporção de compradores online oscilou entre 34,6% (2018) e 42,1% (2023). A relativa estabilidade sugere que o e-commerce, diferentemente do acesso à internet, não se universalizou na mesma velocidade — e explica por que ele permanece como o preditor mais discriminante: quem compra online continua sendo um subgrupo com maior letramento digital.

Tamanho amostral. O N após filtros cresceu de 8.506 (2015) para 16.373 (2025), refletindo a ampliação da base de respondentes que usam internet (filtro C1). O N reduzido de 2015 deve-se à ausência de C5_Dispositivos, que exclui muitas observações por missing naquele ano.

7 Replicação do Modelo Original (2019)

A replicação do modelo de regressão logística do artigo original foi feita com multinom() do pacote nnet e dummies via fastDummies, seguindo exatamente a metodologia descrita em Vargas et al. (2021).

Ajustar modelo para 2019 e comparar com artigo
ajustar_modelo <- function(df) {
  ano_val <- unique(df$ano)

  vars_modelo <- c("g1_agreg", "idade", "pea", "h2",
                    "renda_familiar", "classe_cb", "grau_instrucao", "c5_dispositivos")
  vars_presentes <- intersect(vars_modelo, names(df))

  df_modelo <- df %>%
    select(all_of(vars_presentes)) %>%
    drop_na()

  n_modelo <- nrow(df_modelo)
  if (n_modelo < 200) return(NULL)

  vars_dummy <- intersect(c("renda_familiar", "classe_cb", "grau_instrucao", "c5_dispositivos"),
                           vars_presentes)

  df_dummies <- df_modelo %>%
    mutate(across(all_of(vars_dummy), as.character)) %>%
    dummy_cols(select_columns = vars_dummy, remove_first_dummy = TRUE,
              remove_selected_columns = TRUE)

  tryCatch({
    modelo <- multinom(g1_agreg ~ ., data = df_dummies, trace = FALSE)

    probs <- predict(modelo, type = "probs")
    preds <- predict(modelo, type = "class") %>% as.character() %>% as.numeric()
    y_real <- df_dummies$g1_agreg

    tp <- sum(preds == 1 & y_real == 1)
    fp <- sum(preds == 1 & y_real == 0)
    fn <- sum(preds == 0 & y_real == 1)
    tn <- sum(preds == 0 & y_real == 0)

    accuracy  <- (tp + tn) / n_modelo
    precision_val <- tp / (tp + fp)
    recall    <- tp / (tp + fn)
    f1        <- 2 * precision_val * recall / (precision_val + recall)
    roc_obj   <- roc(y_real, probs, quiet = TRUE)
    auc_val   <- as.numeric(auc(roc_obj))

    s <- summary(modelo)
    coefs <- tibble(
      term = names(s$coefficients),
      estimate = as.numeric(s$coefficients),
      std.error = as.numeric(s$standard.errors)
    ) %>%
      mutate(
        z_value = estimate / std.error,
        p.value = 2 * pnorm(abs(z_value), lower.tail = FALSE),
        conf.low = estimate - 1.96 * std.error,
        conf.high = estimate + 1.96 * std.error,
        ano = ano_val,
        n = n_modelo,
        prop_egov = mean(df_modelo$g1_agreg),
        sig = case_when(
          p.value < 0.001 ~ "***",
          p.value < 0.01  ~ "**",
          p.value < 0.05  ~ "*",
          p.value < 0.1   ~ ".",
          TRUE ~ ""
        )
      )

    metricas <- tibble(
      ano = ano_val, n = n_modelo,
      prop_egov = mean(df_modelo$g1_agreg),
      accuracy = accuracy, precision = precision_val,
      recall = recall, f1 = f1, auc = auc_val
    )

    list(coefs = coefs, metricas = metricas)
  }, error = function(e) NULL)
}
Ver código
# Ajustar somente 2019
df_2019 <- dados_prep %>% keep(~ unique(.x$ano) == 2019) %>% pluck(1)
res_2019 <- ajustar_modelo(df_2019)

7.0.1 Comparação com o artigo original

Ver código
tibble(
  Métrica = c("N", "Accuracy", "F1-score", "Recall", "Precision"),
  Artigo = c("11.781", "0,7314", "0,8023", "0,8428", "0,7656"),
  Replicação = c(
    format(res_2019$metricas$n, big.mark = "."),
    sprintf("%.4f", res_2019$metricas$accuracy),
    sprintf("%.4f", res_2019$metricas$f1),
    sprintf("%.4f", res_2019$metricas$recall),
    sprintf("%.4f", res_2019$metricas$precision)
  )
) %>%
  knitr::kable()
Tabela 3: Validação: replicação vs. artigo original (2019)
Métrica Artigo Replicação
N 11.781 11.781
Accuracy 0,7314 0.7314
F1-score 0,8023 0.8023
Recall 0,8428 0.8428
Precision 0,7656 0.7656

A replicação reproduz exatamente o pipeline da Figura 1 do artigo original. Cada passo intermediário bate: 20.536 obs brutas → 14.701 após filtro C1 = 1 → 12.884 após exclusão de indefinidas → 11.781 após filtro de idade ≥ 16. O N final e todas as métricas coincidem com os valores publicados.

Ver código
res_2019$coefs %>%
  mutate(across(c(estimate, std.error, z_value, p.value, conf.low, conf.high), ~ round(.x, 4))) %>%
  select(Variável = term, Coef. = estimate, EP = std.error, z = z_value,
         `p-valor` = p.value, `IC inf.` = conf.low, `IC sup.` = conf.high, Sig. = sig) %>%
  knitr::kable()
Tabela 4: Coeficientes do modelo logístico — 2019
Variável Coef. EP z p-valor IC inf. IC sup. Sig.
(Intercept) -1.0533 0.3161 -3.3318 0.0009 -1.6729 -0.4337 ***
idade -0.0215 0.0015 -14.2557 0.0000 -0.0245 -0.0186 ***
pea 0.5585 0.0525 10.6396 0.0000 0.4556 0.6613 ***
h2 1.0552 0.0543 19.4507 0.0000 0.9489 1.1616 ***
renda_familiar_1 -0.0061 0.1600 -0.0379 0.9697 -0.3198 0.3076
renda_familiar_2 0.1893 0.1605 1.1796 0.2382 -0.1253 0.5039
renda_familiar_3 0.4414 0.1653 2.6699 0.0076 0.1174 0.7655 **
renda_familiar_4 0.3680 0.1713 2.1488 0.0316 0.0323 0.7037 *
renda_familiar_5 0.4955 0.1895 2.6144 0.0089 0.1240 0.8669 **
renda_familiar_6 0.4227 0.2605 1.6230 0.1046 -0.0878 0.9333
renda_familiar_7 0.3335 0.4864 0.6856 0.4929 -0.6198 1.2868
renda_familiar_8 0.0350 0.5718 0.0612 0.9512 -1.0857 1.1557
classe_cb_1 0.2105 0.0525 4.0076 0.0001 0.1076 0.3135 ***
classe_cb_2 0.2379 0.0936 2.5421 0.0110 0.0545 0.4214 *
classe_cb_3 0.3481 0.2776 1.2542 0.2098 -0.1959 0.8922
grau_instrucao_2 0.4283 0.1228 3.4867 0.0005 0.1876 0.6691 ***
grau_instrucao_3 0.9302 0.1242 7.4877 0.0000 0.6867 1.1737 ***
grau_instrucao_4 1.1446 0.1410 8.1149 0.0000 0.8681 1.4210 ***
c5_dispositivos_2 0.4208 0.2359 1.7839 0.0744 -0.0415 0.8831 .
c5_dispositivos_3 1.0916 0.2395 4.5574 0.0000 0.6221 1.5610 ***

Os coeficientes de 2019 confirmam os achados de Vargas et al. (2021):

  • E-commerce (H2): o preditor mais forte (β = 1,055, p < 0,001). Quem compra online tem 2.9× mais chance (odds ratio) de usar e-gov. Isso corrobora a hipótese de que a familiaridade com transações digitais é um facilitador central.
  • Idade: efeito negativo e significativo (β = -0,022, p < 0,001). Cada ano adicional reduz em 2,1% a chance de uso.
  • PEA: ser economicamente ativo aumenta a chance (β = 0,558, p < 0,001), possivelmente pela necessidade de interagir com serviços trabalhistas e previdenciários.
  • Grau de instrução superior: forte efeito positivo (β = 1,145, p < 0,001), refletindo a barreira educacional ao uso de e-gov.
  • Usar computador e celular (C5=3): o maior efeito entre os dispositivos (β = 1,092, p < 0,001), sugerindo que o acesso multidispositivo amplia a interação com e-gov.

A pergunta que motiva a expansão longitudinal é: esses padrões se mantêm ao longo da década, ou são específicos de 2019?

8 Validação longitudinal (2015-2025)

Antes de concentrar a análise no período pós-pandemia, esta seção verifica a estabilidade do modelo original ao longo de uma década. O objetivo é mostrar que a estrutura de determinantes identificada por Vargas et al. (2021) em 2019 se mantém ao longo da série histórica, servindo como base sólida para a extensão com novas variáveis apresentada na Seção 6.

Agora aplicamos o mesmo modelo a todos os anos disponíveis e analisamos a evolução dos coeficientes e das métricas de desempenho.

Ajustar modelo para todos os anos
resultados <- dados_prep %>%
  map(ajustar_modelo) %>%
  compact()

coefs_todos <- resultados %>% map_dfr("coefs")
metricas_todos <- resultados %>% map_dfr("metricas")

cat(str_glue("Modelos ajustados: {nrow(metricas_todos)} anos\n"))
Modelos ajustados: 10 anos
Ajustar modelo para todos os anos
# --- Variaveis auxiliares para inline R no texto ---
n_anos <- nrow(metricas_todos)
anos_serie <- str_c(metricas_todos$ano, collapse = ", ")

# Proporcao e-gov
egov_min <- metricas_todos %>% slice_min(prop_egov, n = 1)
egov_max <- metricas_todos %>% slice_max(prop_egov, n = 1)

# Validacao 2019
m19 <- metricas_todos %>% filter(ano == 2019)

# Coeficientes-chave: ranges
coef_h2  <- coefs_todos %>% filter(term == "h2")
coef_ida <- coefs_todos %>% filter(term == "idade")
coef_pea <- coefs_todos %>% filter(term == "pea")

h2_range  <- c(min(coef_h2$estimate),  max(coef_h2$estimate))
ida_range <- c(min(coef_ida$estimate), max(coef_ida$estimate))
pea_range <- c(min(coef_pea$estimate), max(coef_pea$estimate))

# AUC range
auc_range <- c(min(metricas_todos$auc), max(metricas_todos$auc))
acc_range <- c(min(metricas_todos$accuracy), max(metricas_todos$accuracy))

# 2015 info
m15 <- metricas_todos %>% filter(ano == 2015)

# 2021 info
m21 <- metricas_todos %>% filter(ano == 2021)

# Picos e vales
pico1 <- metricas_todos %>% filter(ano != 2015) %>% slice_max(prop_egov, n = 1)
pico2 <- metricas_todos %>% filter(ano != 2015, ano != pico1$ano) %>% slice_max(prop_egov, n = 1)
vale1 <- metricas_todos %>% slice_min(prop_egov, n = 1)
vale2 <- metricas_todos %>% filter(ano != vale1$ano) %>% slice_min(prop_egov, n = 1)

8.1 Evolução do uso de governo eletrônico

Ver código
p_egov <- metricas_todos %>%
  ggplot(aes(x = ano, y = prop_egov)) +
  geom_line(linewidth = 1.2, color = "#2563EB") +
  geom_point(size = 3.5, color = "#2563EB") +
  geom_text(aes(label = percent(prop_egov, accuracy = 0.1)),
            vjust = -1.3, size = 3.5, color = "#1e40af") +
  annotate("rect", xmin = 2019.5, xmax = 2020.5, ymin = 0, ymax = 1,
           alpha = 0.08, fill = "red") +
  annotate("text", x = 2020, y = 0.92, label = "2020\n(sem dados)",
           size = 3, color = "red", fontface = "italic") +
  scale_x_continuous(breaks = metricas_todos$ano) +
  scale_y_continuous(labels = percent, limits = c(0, 1)) +
  labs(
    x = "Ano", y = "Proporção de uso de e-gov",
    caption = "Fonte: TIC Domicílios (Cetic.br) | 2020 excluído (Módulo G não coletado)"
  )

ggplotly(p_egov, tooltip = c("x", "y"))
Figura 2: Proporção de usuários de internet (16+) que usaram e-gov nos últimos 12 meses

A proporção de uso de e-gov oscila entre 52,6% e 74,0% ao longo da série, sem tendência monotônica de crescimento. Destacam-se:

  • Picos: 2023 (67,7%) e 2021 (67,1%) — possivelmente impulsionados pela digitalização acelerada pós-pandemia
  • Vales: 2018 (52,6%) e 2024 (52,9%)
  • 2015: valor elevado (74,0%) mas com N muito reduzido (2.632 vs ~10–16k nos demais anos), devendo ser interpretado com cautela

8.2 Evolução dos coeficientes-chave

Ver código
vars_chave <- c("idade", "pea", "h2")
labels_vars <- c(idade = "Idade", pea = "PEA (ativo)", h2 = "E-commerce (H2)")

p_coefs <- coefs_todos %>%
  filter(term %in% vars_chave) %>%
  mutate(term_label = labels_vars[term]) %>%
  ggplot(aes(x = ano, y = estimate, color = term_label, fill = term_label)) +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high), alpha = 0.12, color = NA) +
  geom_line(linewidth = 1) +
  geom_point(size = 2.5) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  scale_x_continuous(breaks = metricas_todos$ano) +
  labs(
    x = "Ano", y = "Coeficiente (log-odds)",
    color = NULL, fill = NULL,
    caption = "Fonte: TIC Domicílios (Cetic.br)"
  )

ggplotly(p_coefs) %>%
  layout(legend = list(orientation = "h", y = -0.15))
Figura 3: Evolução dos coeficientes-chave do modelo logístico com IC 95%

8.2.1 Interpretação dos coeficientes

E-commerce (H2) — O preditor mais forte e mais estável: coeficiente entre 0,947 e 1,250 em todos os anos. Quem compra online tem ~3× mais chance de usar e-gov. Esse efeito não se alterou em uma década, sugerindo que a familiaridade com transações digitais é um facilitador robusto e persistente.

Idade — Efeito negativo pequeno e notavelmente constante: -0,022 a -0,013 em todos os anos. Cada ano adicional de idade reduz marginalmente a chance de uso de e-gov. A hipótese de que o efeito da idade diminuiria com a popularização não se confirma: o coeficiente permanece estável.

PEA (condição de atividade) — Efeito positivo moderado (0,314 a 0,599), com leve tendência de queda ao longo dos anos. Em 2015, o coeficiente era 0,526; em 2025, 0,430. A redução sugere que ser economicamente ativo se tornou menos determinante para o uso de e-gov, possivelmente porque serviços sociais (Auxílio Brasil, Bolsa Família) passaram a ser acessados digitalmente por pessoas fora da PEA.

8.3 Heatmap de significância

Ver código
termos_principais <- coefs_todos %>%
  filter(term != "(Intercept)") %>%
  count(term) %>%
  filter(n >= 5) %>%
  pull(term)

p_heat <- coefs_todos %>%
  filter(term %in% termos_principais) %>%
  mutate(label = str_c(round(estimate, 3), sig)) %>%
  ggplot(aes(x = factor(ano), y = term, fill = estimate)) +
  geom_tile(color = "white", linewidth = 0.5) +
  geom_text(aes(label = label), size = 2.6) +
  scale_fill_gradient2(
    low = "#DC2626", mid = "white", high = "#2563EB",
    midpoint = 0, name = "Coeficiente"
  ) +
  labs(
    subtitle = "*** p<0.001 | ** p<0.01 | * p<0.05 | . p<0.1",
    x = "Ano", y = "Variável",
    caption = "Fonte: TIC Domicílios (Cetic.br)"
  )

p_heat
Figura 4: Coeficientes do modelo logístico por ano — cores indicam direção e magnitude, texto indica significância

O heatmap revela padrões que o artigo original de 2019 não pôde capturar:

Variáveis consistentemente significativas (*) em toda a série**: idade, PEA e H2 mantêm significância a p < 0,001 em todos os 10 anos. Essa estabilidade é notável e indica que esses são determinantes estruturais do uso de e-gov, não artefatos de um ano específico. Vargas et al. (2021) estavam corretos ao identificá-los como preditores centrais — a análise longitudinal valida essa conclusão.

Grau de instrução superior (nível 4): fortemente positivo e significativo de 2015 a 2023 (β entre 1,070 e 1,586), mas perde significância e inverte sinal em 2024–2025. Isso pode indicar uma mudança na codificação da variável nessas edições (de GRAU_INSTRUCAO_2 para GRAU_INST_1) que, embora mantenha 4 categorias nominalmente equivalentes, pode ter limiares de classificação diferentes. Esse resultado merece investigação complementar com os dicionários de variáveis.

Classe econômica (nível A): raramente significativa — apenas 0 de 10 anos com p < 0,05. O artigo original já havia notado a baixa relevância dessa variável em 2019. A análise longitudinal confirma: a classe econômica da ABEP, quando controlada por renda e escolaridade, não é preditor robusto de uso de e-gov. Isso pode decorrer de colinearidade com renda familiar e grau de instrução, que capturam os mesmos fenômenos.

C5_Dispositivos (Ambos = nível 3): efeito positivo e significativo nos anos centrais da série (2017–2019, 2022), mas instável nos anos recentes. Em 2019, usar computador e celular era forte preditor (β = 1,092). A perda de significância pós-2021 pode refletir a convergência do acesso: à medida que quase todos os usuários de internet passaram a usar celular, a distinção “só celular vs ambos” perdeu poder discriminante.

Renda familiar: efeito positivo nos níveis intermediários (3–6), mas irregular nos extremos. A faixa de renda mais alta nem sempre é significativa, provavelmente por baixa frequência amostral. Diferentemente do que o corte transversal de 2019 sugeria, a renda não é um preditor tão estável quanto o grau de instrução ao longo da década.

8.4 Desempenho do modelo ao longo dos anos

Ver código
p_met <- metricas_todos %>%
  select(ano, Accuracy = accuracy, `AUC-ROC` = auc, `F1-Score` = f1) %>%
  pivot_longer(-ano, names_to = "Métrica", values_to = "Valor") %>%
  ggplot(aes(x = ano, y = Valor, color = `Métrica`)) +
  geom_line(linewidth = 1) +
  geom_point(size = 3) +
  scale_x_continuous(breaks = metricas_todos$ano) +
  scale_y_continuous(limits = c(0.5, 1)) +
  labs(x = "Ano", y = "Valor", color = NULL,
       caption = "Fonte: TIC Domicílios (Cetic.br)")

ggplotly(p_met) %>%
  layout(legend = list(orientation = "h", y = -0.15))
Figura 5: Accuracy, F1-Score e AUC-ROC do modelo logístico por ano
Ver código
metricas_todos %>%
  mutate(across(c(prop_egov, accuracy, precision, recall, f1, auc), ~ round(.x, 4))) %>%
  rename(
    Ano = ano, N = n, `% E-gov` = prop_egov,
    Accuracy = accuracy, Precisão = precision,
    Recall = recall, F1 = f1, AUC = auc
  ) %>%
  knitr::kable(format.args = list(big.mark = "."))
Tabela 5: Métricas de desempenho do modelo por ano
Ano N % E-gov Accuracy Precisão Recall F1 AUC
2.015 2.632 0.7397 0.7644 0.7834 0.9420 0.8554 0.7392
2.016 9.072 0.6060 0.7002 0.7268 0.8096 0.7660 0.7520
2.017 10.470 0.6129 0.7042 0.7428 0.7913 0.7663 0.7692
2.018 11.081 0.5262 0.6926 0.7215 0.6772 0.6987 0.7565
2.019 11.781 0.6467 0.7314 0.7656 0.8428 0.8023 0.7810
2.021 12.914 0.6714 0.7261 0.7581 0.8694 0.8100 0.7673
2.022 12.648 0.6142 0.7047 0.7434 0.7930 0.7674 0.7625
2.023 13.533 0.6775 0.7365 0.7715 0.8682 0.8170 0.7751
2.024 14.144 0.5293 0.6992 0.7342 0.6765 0.7042 0.7717
2.025 16.373 0.6629 0.7329 0.7678 0.8558 0.8094 0.7714

O AUC-ROC manteve-se estável entre 0,7392 (2015) e 0,7810 (2019), indicando que o conjunto de variáveis proposto por Vargas et al. (2021) mantém poder preditivo consistente ao longo de uma década. Para contextualizar: o AUC de 2019 no artigo original não foi reportado, mas a replicação aqui apresentada encontra 0,7810, valor próximo da mediana da série inteira. O modelo de 2019 não é excepcionalmente bom nem ruim; ele é representativo do período.

A accuracy varia mais (0,6926–0,7644), e essa variação é quase inteiramente explicável pela proporção de uso de e-gov em cada ano (r = 0,921 entre accuracy e distância de 50%). Nos anos em que o uso se aproxima de 50% (2018, 2024), a classificação binária se torna intrinsecamente mais difícil, reduzindo a accuracy mesmo sem perda de capacidade discriminante. O F1-Score espelha esse padrão: é mais baixo em 2018 (0,6987) quando a classe positiva é minoritária, e mais alto em 2015 (0,8554) quando predomina.

A conclusão central é que a estrutura preditiva identificada em 2019 não é um achado pontual: o mesmo conjunto de variáveis discrimina usuários e não-usuários de e-gov com desempenho comparável ao longo de toda a década.

8.5 Animação: coeficientes ao longo do tempo

8.5.1 Animação interativa (plotly)

Ver código
coefs_anim <- coefs_todos %>%
  filter(term %in% vars_chave) %>%
  mutate(term_label = labels_vars[term])

plot_ly(
  coefs_anim,
  x = ~estimate, y = ~term_label,
  frame = ~ano,
  type = "bar", orientation = "h",
  color = ~term_label,
  colors = c("Idade" = "#DC2626", "PEA (ativo)" = "#059669", "E-commerce (H2)" = "#2563EB"),
  error_x = list(
    type = "data",
    symmetric = FALSE,
    arrayminus = ~(estimate - conf.low),
    array = ~(conf.high - estimate)
  ),
  text = ~paste0(round(estimate, 3), " ", sig),
  textposition = "outside",
  hoverinfo = "text",
  showlegend = FALSE
) %>%
  layout(
    xaxis = list(title = "Coeficiente (log-odds)", zeroline = TRUE,
                 range = c(min(coefs_anim$conf.low) - 0.15,
                           max(coefs_anim$conf.high) + 0.3)),
    yaxis = list(title = ""),
    title = list(text = "Coeficientes-chave por ano"),
    uniformtext = list(minsize = 10, mode = "show")
  ) %>%
  animation_opts(frame = 800, transition = 400, easing = "cubic-in-out") %>%
  animation_slider(currentvalue = list(prefix = "Ano: "))
Figura 6: Evolução dos coeficientes das variáveis-chave — use o slider para navegar entre anos

8.5.2 Animação GIF (gganimate)

Ver código
p_anim <- ggplot(coefs_anim, aes(x = term_label, y = estimate, fill = term_label)) +
  geom_col(width = 0.6, show.legend = FALSE) +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey40") +
  geom_text(aes(label = round(estimate, 3)),
            vjust = -0.8, size = 4.5) +
  scale_fill_manual(values = c("Idade" = "#DC2626", "PEA (ativo)" = "#059669", "E-commerce (H2)" = "#2563EB")) +
  coord_flip() +
  labs(
    title = "Coeficientes-chave — {closest_state}",
    x = NULL, y = "Coeficiente (log-odds)",
    caption = "Fonte: TIC Domicílios (Cetic.br)"
  ) +
  transition_states(ano, transition_length = 2, state_length = 3) +
  ease_aes("cubic-in-out")

animate(p_anim, nframes = 100, fps = 10, width = 8, height = 4,
        units = "in", res = 150, renderer = gifski_renderer())
Figura 7: Evolução dos coeficientes das variáveis-chave ao longo dos anos

As duas animações acima permitem visualizar um achado central que só emerge da análise longitudinal: a hierarquia relativa dos preditores é invariante ao longo da década. Em todos os anos, o e-commerce (H2) domina com coeficiente acima de 0,947, a PEA contribui moderadamente, e a idade exerce efeito negativo pequeno. Essa “assinatura” do modelo se mantém mesmo em anos com proporções de uso de e-gov muito diferentes — de 52,6% em 2018 a 74,0% em 2015.

O que muda entre anos é a magnitude dos efeitos, não sua direção. Em particular, note como o coeficiente da PEA oscila mais do que os outros dois — um indício de que a relação entre condição de atividade econômica e uso de e-gov é mediada por fatores contextuais (políticas públicas, oferta de serviços digitais) que variam mais do que a relação entre, por exemplo, familiaridade digital e e-gov.

8.6 Modelo pooled com ano como covariável (2015-2025)

Para testar formalmente se há efeito temporal no uso de e-gov além do explicado pelas variáveis sociodemográficas, três modelos pooled são ajustados empilhando todos os anos: (i) sem a variável ano, (ii) com ano categórico (dummies por edição) e (iii) com ano contínuo (tendência linear).

Ajustar modelos pooled
dados_pool <- dados_prep %>% bind_rows()

vars_modelo <- c("g1_agreg", "idade", "pea", "h2",
                  "renda_familiar", "classe_cb", "grau_instrucao",
                  "c5_dispositivos", "ano")
vars_dummy <- c("renda_familiar", "classe_cb", "grau_instrucao", "c5_dispositivos")

dados_modelo <- dados_pool %>%
  select(any_of(vars_modelo)) %>%
  drop_na() %>%
  mutate(ano = factor(ano))

# Modelo 1: SEM ano
df_base <- dados_modelo %>%
  select(-ano) %>%
  mutate(across(all_of(vars_dummy), as.character)) %>%
  dummy_cols(select_columns = vars_dummy, remove_first_dummy = TRUE,
             remove_selected_columns = TRUE)

modelo_base <- multinom(g1_agreg ~ ., data = df_base, trace = FALSE)

probs_base <- predict(modelo_base, type = "probs")
preds_base <- predict(modelo_base, type = "class") %>% as.character() %>% as.numeric()
y <- df_base$g1_agreg
acc_base <- mean(preds_base == y)
auc_base <- as.numeric(auc(roc(y, probs_base, quiet = TRUE)))

# Modelo 2: COM ano categorica
df_ano <- dados_modelo %>%
  mutate(across(all_of(c(vars_dummy, "ano")), as.character)) %>%
  dummy_cols(select_columns = c(vars_dummy, "ano"), remove_first_dummy = TRUE,
             remove_selected_columns = TRUE)

modelo_ano <- multinom(g1_agreg ~ ., data = df_ano, trace = FALSE)

probs_ano <- predict(modelo_ano, type = "probs")
preds_ano <- predict(modelo_ano, type = "class") %>% as.character() %>% as.numeric()
acc_ano <- mean(preds_ano == y)
auc_ano <- as.numeric(auc(roc(y, probs_ano, quiet = TRUE)))

# Modelo 3: Ano continua (tendencia linear)
df_trend <- dados_modelo %>%
  mutate(ano_num = as.numeric(as.character(ano)) - 2015) %>%
  select(-ano) %>%
  mutate(across(all_of(vars_dummy), as.character)) %>%
  dummy_cols(select_columns = vars_dummy, remove_first_dummy = TRUE,
             remove_selected_columns = TRUE)

modelo_trend <- multinom(g1_agreg ~ ., data = df_trend, trace = FALSE)
s_trend <- summary(modelo_trend)
coef_ano_trend <- s_trend$coefficients["ano_num"]
se_ano_trend   <- s_trend$standard.errors["ano_num"]
z_trend <- coef_ano_trend / se_ano_trend
p_trend <- 2 * pnorm(abs(z_trend), lower.tail = FALSE)

# Accuracy e AUC do modelo_trend
probs_trend <- predict(modelo_trend, type = "probs")
preds_trend <- predict(modelo_trend, type = "class") %>% as.character() %>% as.numeric()
acc_trend <- mean(preds_trend == y)
auc_trend <- as.numeric(auc(roc(y, probs_trend, quiet = TRUE)))

8.7 Teste de razão de verossimilhança

Ver código
ll_base <- logLik(modelo_base)
ll_ano  <- logLik(modelo_ano)
lr_stat <- -2 * (as.numeric(ll_base) - as.numeric(ll_ano))
df_diff <- length(coef(modelo_ano)) - length(coef(modelo_base))
lr_pval <- pchisq(lr_stat, df = df_diff, lower.tail = FALSE)
Ver código
extrair_coefs_pooled <- function(modelo, nome) {
  s <- summary(modelo)
  tibble(
    term = names(s$coefficients),
    estimate = as.numeric(s$coefficients),
    std.error = as.numeric(s$standard.errors)
  ) %>%
    mutate(
      z_value = estimate / std.error,
      p.value = 2 * pnorm(abs(z_value), lower.tail = FALSE),
      conf.low = estimate - 1.96 * std.error,
      conf.high = estimate + 1.96 * std.error,
      sig = case_when(
        p.value < 0.001 ~ "***",
        p.value < 0.01  ~ "**",
        p.value < 0.05  ~ "*",
        p.value < 0.1   ~ ".",
        TRUE ~ ""
      ),
      modelo = nome
    )
}

tibble(
  Modelo = c("Sem ano (baseline)", "Com ano (categórica)", "Com ano (contínua)"),
  N = nrow(df_base),
  Accuracy = c(acc_base, acc_ano, acc_trend),
  AUC = c(auc_base, auc_ano, auc_trend),
  `Nº parâmetros` = c(length(coef(modelo_base)), length(coef(modelo_ano)), length(coef(modelo_trend)))
) %>%
  mutate(across(c(Accuracy, AUC), ~ round(.x, 4))) %>%
  knitr::kable(format.args = list(big.mark = "."))
Tabela 6: Comparação dos modelos pooled
Modelo N Accuracy AUC Nº parâmetros
Sem ano (baseline) 102.944 0.7070 0.7620 20
Com ano (categórica) 102.944 0.7166 0.7737 27
Com ano (contínua) 102.944 0.7101 0.7654 21
ImportanteResultado do teste LR

LR stat = 2172.21, df = 7, p < 0.001

Incluir o ano como variável categórica melhora significativamente o modelo. Isso confirma que há variação temporal no uso de e-gov além do que é explicado pelas variáveis sociodemográficas.

Tendência linear: coeficiente do ano = 0.0666 (p < 0.001). Há uma tendência temporal positiva significativa.

8.8 Coeficientes das variáveis sociodemográficas (3 modelos)

Ver código
coefs_base_pooled  <- extrair_coefs_pooled(modelo_base, "Sem ano")
coefs_cat_pooled   <- extrair_coefs_pooled(modelo_ano, "Com ano (categórica)")
coefs_trend_pooled <- extrair_coefs_pooled(modelo_trend, "Com ano (contínua)")

coefs_3modelos <- bind_rows(coefs_base_pooled, coefs_cat_pooled, coefs_trend_pooled)

# Tabela com variáveis-chave
vars_chave <- c("(Intercept)", "idade", "pea", "h2", "ano_num",
                "classe_cb_1", "classe_cb_2", "classe_cb_3",
                "grau_instrucao_2", "grau_instrucao_3", "grau_instrucao_4",
                "c5_dispositivos_2", "c5_dispositivos_3",
                "renda_familiar_1", "renda_familiar_2", "renda_familiar_3",
                "renda_familiar_4", "renda_familiar_5", "renda_familiar_6")

coefs_3modelos %>%
  filter(term %in% vars_chave) %>%
  mutate(
    coef_fmt = str_c(round(estimate, 4), sig),
    term = case_when(
      term == "ano_num" ~ "Ano (contínua)",
      term == "classe_cb_1" ~ "Classe B",
      term == "classe_cb_2" ~ "Classe C",
      term == "classe_cb_3" ~ "Classe DE",
      term == "grau_instrucao_2" ~ "Fundamental",
      term == "grau_instrucao_3" ~ "Médio",
      term == "grau_instrucao_4" ~ "Superior",
      term == "c5_dispositivos_2" ~ "Só celular",
      term == "c5_dispositivos_3" ~ "Ambos dispositivos",
      str_detect(term, "renda_familiar") ~ str_c("Renda ", str_extract(term, "\\d+$")),
      TRUE ~ term
    )
  ) %>%
  select(Variável = term, Modelo = modelo, Coeficiente = coef_fmt) %>%
  pivot_wider(names_from = Modelo, values_from = Coeficiente) %>%
  knitr::kable()
Tabela 7: Coeficientes das variáveis-chave nos 3 modelos pooled
Variável Sem ano Com ano (categórica) Com ano (contínua)
(Intercept) -0.7448*** -0.7679*** -0.924***
idade -0.0161*** -0.0181*** -0.0179***
pea 0.4264*** 0.4571*** 0.4571***
h2 1.1311*** 1.0663*** 1.0832***
Renda 1 -0.0376 -0.0857 -0.0537
Renda 2 0.056 0.0404 0.0591
Renda 3 0.1961** 0.1923** 0.2045**
Renda 4 0.2839*** 0.2833*** 0.3003***
Renda 5 0.3666*** 0.365*** 0.3868***
Renda 6 0.5086*** 0.4818*** 0.5217***
Classe B 0.1181*** 0.1667*** 0.1531***
Classe C 0.0867** 0.2132*** 0.1729***
Classe DE -0.0141 0.1677. 0.1135
Fundamental 0.3711*** 0.4264*** 0.3499***
Médio 0.768*** 0.8147*** 0.7348***
Superior 1.1672*** 1.1935*** 1.1127***
Só celular 0.2525*** 0.001 0.0587
Ambos dispositivos 0.7859*** 0.6054*** 0.6368***
Ano (contínua) NA NA 0.0666***
Ver código
vars_graf <- c("idade", "pea", "h2",
               "classe_cb_1", "classe_cb_2",
               "grau_instrucao_3", "grau_instrucao_4",
               "c5_dispositivos_3", "ano_num")

labels_graf <- c(
  "idade" = "Idade", "pea" = "PEA", "h2" = "E-commerce (H2)",
  "classe_cb_1" = "Classe B", "classe_cb_2" = "Classe C",
  "grau_instrucao_3" = "Ensino Médio", "grau_instrucao_4" = "Ensino Superior",
  "c5_dispositivos_3" = "Ambos dispositivos", "ano_num" = "Ano (contínua)"
)

coefs_3modelos %>%
  filter(term %in% vars_graf) %>%
  mutate(term_label = recode(term, !!!labels_graf),
         term_label = fct_reorder(term_label, estimate)) %>%
  ggplot(aes(x = term_label, y = estimate, color = modelo)) +
  geom_pointrange(aes(ymin = conf.low, ymax = conf.high),
                  position = position_dodge(width = 0.5), size = 0.6) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  coord_flip() +
  scale_color_manual(values = c("Sem ano" = "#6B7280",
                                "Com ano (categórica)" = "#2563EB",
                                "Com ano (contínua)" = "#DC2626")) +
  labs(
    x = NULL, y = "Coeficiente (log-odds)",
    color = "Modelo",
    caption = "*** p<0.001, ** p<0.01, * p<0.05"
  ) +
  theme_minimal(base_size = 12) +
  theme(legend.position = "bottom")
Figura 8: Comparação dos coeficientes-chave entre os 3 modelos pooled

Os coeficientes das variáveis sociodemográficas são notavelmente estáveis entre os 3 modelos pooled. A inclusão do ano (seja como categórica ou contínua) não altera substancialmente os efeitos das variáveis-chave — o que confirma que esses preditores são robustos e não estão confundidos com tendências temporais.

8.9 Efeitos dos anos (modelo pooled)

Ver código
coefs_ano_pooled <- extrair_coefs_pooled(modelo_ano, "Com ano")

p_anos <- coefs_ano_pooled %>%
  filter(str_detect(term, "^ano_")) %>%
  mutate(
    ano_num = str_extract(term, "\\d{4}") %>% as.numeric(),
    sig_label = str_c(round(estimate, 3), sig)
  ) %>%
  ggplot(aes(x = ano_num, y = estimate)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_pointrange(aes(ymin = conf.low, ymax = conf.high), color = "#2563EB", size = 0.8) +
  geom_text(aes(label = sig_label), vjust = -1.2, size = 3.5) +
  scale_x_continuous(breaks = seq(2015, 2025, 1)) +
  labs(
    x = "Ano", y = "Coeficiente (log-odds)",
    subtitle = "Referência: primeiro ano. Controlado por idade, PEA, H2, renda, classe, grau, dispositivos",
    caption = "Fonte: TIC Domicílios (Cetic.br) | *** p<0.001, ** p<0.01, * p<0.05"
  )

ggplotly(p_anos)
Figura 9: Efeito de cada ano sobre o uso de e-gov, controlando por todas as variáveis sociodemográficas

Este gráfico responde a uma pergunta que o estudo de 2019 não podia formular: controlando por todas as variáveis sociodemográficas, há anos em que o uso de e-gov é sistematicamente maior ou menor?

Os anos 2019, 2021, 2022, 2023, 2025 apresentam efeito positivo significativo em relação ao ano-referência, indicando que — mesmo controlando por idade, renda, escolaridade e demais variáveis — houve maior propensão ao uso de e-gov nesses períodos. Esse efeito temporal residual pode ser atribuído abdutivamente a fatores não capturados no modelo: expansão da oferta de serviços digitais (gov.br, Pix, CNH digital), campanhas de digitalização, ou efeitos da pandemia sobre hábitos de interação com o governo.

Já os anos 2018, 2024 mostram efeito negativo significativo, sugerindo que a propensão ao uso foi menor do que o esperado pelas características sociodemográficas. O padrão não-linear das dummies de ano (com picos e vales) reforça que a tendência de uso de e-gov não é monotônica — há ciclos que merecem investigação com dados contextuais (oferta de serviços, eleições, crises econômicas).

A magnitude do efeito mais forte (2023: β = 0,653) é comparável ao coeficiente da PEA no modelo individual, o que mostra que o contexto temporal tem peso equivalente a uma variável sociodemográfica relevante. Essa é uma contribuição original da análise longitudinal que não era possível com o recorte transversal de 2019.

8.10 Linha de base: modelo pooled 2021-2025 (vars do artigo)

Antes de introduzir as extensões da Seção 6, este bloco apresenta o modelo-base: o mesmo conjunto de variáveis de Vargas et al. (2021), ajustado sobre o pooled 2021-2025 com o ano tratado como variável contínua (centralizada em 2021). Essa parametrização permite comparar, na sequência, o ganho de poder preditivo obtido com a adição das variáveis de uso digital selecionadas pelo screening universal.

Modelo pooled 2021-2025
dados_pool_pos <- dados_pool %>%
  filter(ano >= 2021)

dados_modelo_pos <- dados_pool_pos %>%
  select(any_of(vars_modelo)) %>%
  drop_na() %>%
  mutate(ano_num = as.numeric(as.character(ano)) - 2021) %>%
  select(-ano)

cat("N total 2021-2025:", nrow(dados_modelo_pos), "\n")
N total 2021-2025: 69612 
Modelo pooled 2021-2025
# Modelo com ano contínuo (centralizado em 2021)
df_pos <- dados_modelo_pos %>%
  mutate(across(all_of(vars_dummy), as.character)) %>%
  dummy_cols(select_columns = vars_dummy, remove_first_dummy = TRUE,
             remove_selected_columns = TRUE)

modelo_pos <- multinom(g1_agreg ~ ., data = df_pos, trace = FALSE)

probs_pos <- predict(modelo_pos, type = "probs")
preds_pos <- predict(modelo_pos, type = "class") %>% as.character() %>% as.numeric()
y_pos <- df_pos$g1_agreg
acc_pos <- mean(preds_pos == y_pos)
auc_pos <- as.numeric(auc(roc(y_pos, probs_pos, quiet = TRUE)))

# Extrair coeficientes
coefs_pos <- extrair_coefs_pooled(modelo_pos, "2021-2025")
Ver código
vars_chave_pos <- c("(Intercept)", "idade", "pea", "h2", "ano_num",
                    "classe_cb_1", "classe_cb_2", "classe_cb_3",
                    "grau_instrucao_2", "grau_instrucao_3", "grau_instrucao_4",
                    "c5_dispositivos_2", "c5_dispositivos_3",
                    "renda_familiar_1", "renda_familiar_2", "renda_familiar_3",
                    "renda_familiar_4", "renda_familiar_5", "renda_familiar_6")

coefs_pos %>%
  filter(term %in% vars_chave_pos) %>%
  mutate(
    term = case_when(
      term == "ano_num" ~ "Ano (tendência)",
      term == "classe_cb_1" ~ "Classe B",
      term == "classe_cb_2" ~ "Classe C",
      term == "classe_cb_3" ~ "Classe DE",
      term == "grau_instrucao_2" ~ "Fundamental",
      term == "grau_instrucao_3" ~ "Médio",
      term == "grau_instrucao_4" ~ "Superior",
      term == "c5_dispositivos_2" ~ "Só celular",
      term == "c5_dispositivos_3" ~ "Ambos dispositivos",
      str_detect(term, "renda_familiar") ~ str_c("Renda faixa ", str_extract(term, "\\d+$")),
      TRUE ~ term
    ),
    across(c(estimate, std.error, z_value, conf.low, conf.high), ~ round(.x, 4)),
    p.value = format.pval(p.value, digits = 3)
  ) %>%
  select(Variável = term, Coef = estimate, EP = std.error, z = z_value,
         `p-valor` = p.value, Sig = sig, IC_inf = conf.low, IC_sup = conf.high) %>%
  knitr::kable()
Tabela 8: Coeficientes do modelo pooled 2021-2025 (ano contínuo)
Variável Coef EP z p-valor Sig IC_inf IC_sup
(Intercept) -0.1751 0.1819 -0.9624 0.33583 -0.5317 0.1815
idade -0.0173 0.0006 -28.6821 < 2e-16 *** -0.0185 -0.0162
pea 0.4446 0.0195 22.7493 < 2e-16 *** 0.4063 0.4829
h2 1.1092 0.0210 52.8215 < 2e-16 *** 1.0680 1.1504
Ano (tendência) -0.0179 0.0062 -2.8675 0.00414 ** -0.0301 -0.0057
Renda faixa 1 -0.0963 0.0805 -1.1968 0.23140 -0.2541 0.0614
Renda faixa 2 0.0032 0.0811 0.0393 0.96867 -0.1558 0.1622
Renda faixa 3 0.1716 0.0832 2.0609 0.03931 * 0.0084 0.3347
Renda faixa 4 0.2839 0.0867 3.2766 0.00105 ** 0.1141 0.4538
Renda faixa 5 0.2991 0.0964 3.1027 0.00192 ** 0.1102 0.4881
Renda faixa 6 0.5276 0.1322 3.9910 6.58e-05 *** 0.2685 0.7866
Classe B 0.1766 0.0204 8.6775 < 2e-16 *** 0.1367 0.2166
Classe C 0.2679 0.0423 6.3368 2.35e-10 *** 0.1850 0.3508
Classe DE 0.1466 0.1542 0.9509 0.34167 -0.1556 0.4489
Fundamental 0.4117 0.0414 9.9389 < 2e-16 *** 0.3305 0.4929
Médio 0.7383 0.0427 17.2964 < 2e-16 *** 0.6547 0.8220
Superior 1.1002 0.0516 21.3181 < 2e-16 *** 0.9991 1.2014
Só celular -0.0926 0.1559 -0.5937 0.55270 -0.3981 0.2130
Ambos dispositivos 0.4369 0.1575 2.7745 0.00553 ** 0.1282 0.7455
Ver código
coefs_trend_pooled_sel <- coefs_trend_pooled %>%
  mutate(periodo = "2015-2025")
coefs_pos_sel <- coefs_pos %>%
  mutate(periodo = "2021-2025")

vars_comp <- c("idade", "pea", "h2", "ano_num",
               "classe_cb_1", "classe_cb_2",
               "grau_instrucao_3", "grau_instrucao_4",
               "c5_dispositivos_3")

labels_comp <- c(
  "idade" = "Idade", "pea" = "PEA", "h2" = "E-commerce (H2)",
  "ano_num" = "Ano (tendência)", "classe_cb_1" = "Classe B",
  "classe_cb_2" = "Classe C", "grau_instrucao_3" = "Ensino Médio",
  "grau_instrucao_4" = "Ensino Superior",
  "c5_dispositivos_3" = "Ambos dispositivos"
)

bind_rows(coefs_trend_pooled_sel, coefs_pos_sel) %>%
  filter(term %in% vars_comp) %>%
  mutate(term_label = recode(term, !!!labels_comp),
         term_label = fct_reorder(term_label, estimate)) %>%
  ggplot(aes(x = term_label, y = estimate, color = periodo)) +
  geom_pointrange(aes(ymin = conf.low, ymax = conf.high),
                  position = position_dodge(width = 0.5), size = 0.6) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  coord_flip() +
  scale_color_manual(values = c("2015-2025" = "#6B7280", "2021-2025" = "#DC2626")) +
  labs(x = NULL, y = "Coeficiente (log-odds)", color = "Período",
       caption = "Modelo com ano contínuo | *** p<0.001, ** p<0.01, * p<0.05") +
  theme_minimal(base_size = 12) +
  theme(legend.position = "bottom")
Figura 10: Comparação dos coeficientes-chave: período completo (2015-2025) vs pós-pandemia (2021-2025)
NotaModelo 2021-2025

N = 69612 | Accuracy = 0.715 | AUC = 0.7664

O gráfico acima compara os coeficientes do modelo com ano contínuo para o período completo (2015-2025) e o período pós-pandemia (2021-2025). Diferenças entre os períodos indicam mudanças estruturais nos determinantes do uso de e-gov após a pandemia.

9 Determinantes do uso de e-gov no pós-pandemia (2021-2025)

Uma vez estabelecida a estabilidade longitudinal do modelo original e apresentada a linha de base para 2021-2025 na seção anterior, este bloco constitui o eixo principal da análise: quais características dos usuários de internet explicam o uso de serviços de governo eletrônico no período pós-pandemia. O modelo logístico de Vargas et al. (2021) é comparado com extensões em duas dimensões: (i) conjunto de variáveis, o do artigo original (7 preditores) versus o conjunto ampliado com 16 variáveis de intensidade de uso digital selecionadas por screening universal; e (ii) classe de modelo, regressão logística versus árvore de decisão versus random forest. Todas as combinações são avaliadas sobre o mesmo N e as mesmas folds de validação cruzada, o que isola o efeito de cada dimensão. O desfecho é o uso de e-gov nos 12 meses anteriores à coleta, codificado como fator com “Sim” (usa e-gov) como classe positiva.

O treino é executado em script separado (fit_ml.R) e carregado aqui via RDS; a validação cruzada com random forest é computacionalmente intensiva. Para recalcular: Rscript fit_ml.R.

Carregar modelos treinados (dados/ml_results.rds)
ml_rds <- "dados/ml_results.rds"
if (!file.exists(ml_rds)) {
  stop("dados/ml_results.rds não encontrado. Rode 'Rscript fit_ml.R' antes de renderizar o qmd.")
}

ml <- readRDS(ml_rds)

modelo_glm_orig <- ml$modelos$glm_orig
modelo_glm_exp  <- ml$modelos$glm_exp
modelo_tree     <- ml$modelos$tree
modelo_rf_orig  <- ml$modelos$rf_orig
modelo_rf_exp   <- ml$modelos$rf_exp

# Aliases de compatibilidade — o GLM e o RF "principais" são as versões expandidas
modelo_glm <- modelo_glm_exp
modelo_rf  <- modelo_rf_exp

df_ml         <- ml$df_exp
resultados_ml <- ml$resamples
resumo_ml     <- ml$resumo
vars_art_ml   <- ml$vars_art
vars_extra_ml <- ml$vars_extra

cat("ML carregado de", ml_rds,
    "| treinado em", format(ml$meta$timestamp),
    "| N =", ml$meta$N, "\n")
ML carregado de dados/ml_results.rds | treinado em 2026-04-22 17:07:04 | N = 68933 

9.1 Comparação de desempenho

9.2 Screening de variáveis universais

Para ampliar o modelo sem comprometer a consistência longitudinal, o script explora_variaveis_full.R faz um screening univariado sobre 76 variáveis presentes em todas as 10 edições da TIC Domicílios (após harmonização). Cada candidata é adicionada ao modelo logístico base (vars do artigo) e medimos o ganho de AUC no pooled 2021–2025.

AUC base (só vars do artigo, N ≈ 70 mil): ≈ 0,76.

9.2.1 Endogeneidade (excluídas)

Três variáveis do top ranking foram excluídas por sobreposição conceitual com o outcome (uso de e-gov):

Variável Conteúdo ΔAUC Por que é endógena
C8_F Buscar informações em sites de governo +0,034 É e-gov por definição
C8_G Serviços públicos / pagar taxas online +0,026 É o próprio outcome
C8_H Consultas, pagamentos, transações financeiras +0,021 Pode incluir pagamentos a órgãos públicos

9.2.2 Top variáveis legítimas (selecionadas)

Dezesseis variáveis de intensidade e variedade de uso digital — cada uma soma +0,015 a +0,040 de AUC isoladamente. Agrupadas:

  • Atividades de internet (C8_A/B/D/E): produtos, saúde, emprego, enciclopédia
  • Uso do celular (J2_L/J/G/K): busca de informação, páginas, mapas, apps
  • Mídia e educação (C9_C/D, C10_A/C/D): vídeos, notícias, cursos, estudo próprio
  • Engajamento (C11_A, C7_A, B1): compartilhar, email, uso de computador

Interpretação: quem usa a internet para múltiplas finalidades tem probabilidade maior de usar e-gov. É um padrão de intensidade, não de conteúdo governamental.

9.3 Matriz 2×2 (vars × modelo)

Para separar o efeito do conjunto de variáveis do efeito do modelo, quatro combinações são treinadas compartilhando as mesmas folds e o mesmo N (drop_na sobre o superset, N ≈ 68 mil):

Ver código
resumo_ml %>%
  transmute(
    Modelo = modelo,
    Variáveis = if_else(vars == "artigo", "Artigo (7)",
                        "Artigo + 16 de uso digital"),
    N, AUC,
    `Recall (Sens)` = Sens,
    `Precisão`      = Prec,
    F1,
    `Espec.`        = Spec
  ) %>%
  knitr::kable(format.args = list(big.mark = "."))
Tabela 9: Matriz 2×2: (GLM / RF) × (Original / Expandido) — CV 5-fold, 2021-2025 | positivo = usa e-gov
Modelo Variáveis N AUC Recall (Sens) Precisão F1 Espec.
GLM Original Artigo (7) 68.933 0.7672 0.8179 0.7531 0.7842 0.5404
GLM Expandido Artigo + 16 de uso digital 68.933 0.8306 0.8360 0.8032 0.8193 0.6491
Árvore Artigo (7) 68.933 0.7402 0.8159 0.7509 0.7821 0.5362
RF Original Artigo (7) 68.933 0.7698 0.8280 0.7492 0.7867 0.5251
RF Expandido Artigo + 16 de uso digital 68.933 0.8298 0.8539 0.7934 0.8225 0.6189
ImportanteLeitura da matriz 2×2
  • ML sozinho não ajuda: RF vs GLM sobre as vars originais → ΔAUC = +0.0026. Modelos mais flexíveis não capturam padrões não-lineares além do que a logística já captura.
  • As novas variáveis é que elevam o AUC: ΔAUC = +0.0634 (GLM) / +0.0600 (RF). O ganho vem do conjunto de preditores, não da classe de modelo.
  • Logística expandida ≈ RF expandido (AUC ≈ 0.831): o problema é aproximadamente linear no espaço ampliado — a logística com vars estendidas é suficiente por parsimônia.
  • Desempenho preditivo substancial: o GLM Expandido atinge recall = 83.6% e precisão = 80.3% para usuários de e-gov (F1 = 0.819), acima do patamar de 80% em ambas as métricas. A convenção “positivo = usa e-gov” é explícita: o twoClassSummary do caret usa por default o primeiro nível do fator como positivo, o que pode inverter a leitura se não for fixado.

9.4 Coeficientes do GLM Expandido

Os coeficientes abaixo vêm da logística expandida — o modelo que atinge o maior F1 e AUC combinando todas as variáveis (artigo + 16 do screening). Como o GLM ≈ RF em AUC, esses log-odds resumem o modelo preditivo inteiro.

Ver código
fit_glm_exp <- modelo_glm_exp$finalModel

rotular_termo <- function(x) {
  x <- str_replace(x, "^RENDA_FAMILIAR", "Renda faixa ")
  x <- str_replace(x, "^CLASSE_CB1$",       "Classe A")
  x <- str_replace(x, "^CLASSE_CB2$",       "Classe B")
  x <- str_replace(x, "^CLASSE_CB3$",       "Classe C")
  x <- str_replace(x, "^CLASSE_CB4$",       "Classe DE")
  x <- str_replace(x, "^GRAU_INSTRUCAO1$",  "Sem instrução")
  x <- str_replace(x, "^GRAU_INSTRUCAO2$",  "Fundamental")
  x <- str_replace(x, "^GRAU_INSTRUCAO3$",  "Médio")
  x <- str_replace(x, "^GRAU_INSTRUCAO4$",  "Superior")
  x <- str_replace(x, "^C5_DISPOSITIVOS1$", "Só computador")
  x <- str_replace(x, "^C5_DISPOSITIVOS2$", "Só celular")
  x <- str_replace(x, "^C5_DISPOSITIVOS3$", "Ambos")
  x <- str_replace(x, "^C5_DISPOSITIVOS4$", "Nenhum")
  x
}

broom::tidy(fit_glm_exp, conf.int = TRUE, exponentiate = FALSE) %>%
  mutate(
    OR      = exp(estimate),
    OR_low  = exp(conf.low),
    OR_high = exp(conf.high),
    sig     = case_when(
      p.value < 0.001 ~ "***", p.value < 0.01 ~ "**",
      p.value < 0.05  ~ "*",  p.value < 0.1  ~ ".", TRUE ~ ""),
    Variável = rotular_termo(term)
  ) %>%
  arrange(desc(abs(estimate))) %>%
  transmute(
    Variável,
    Coef = round(estimate, 3),
    EP   = round(std.error, 3),
    z    = round(statistic, 2),
    `p-valor` = format.pval(p.value, digits = 2),
    Sig  = sig,
    OR   = round(OR, 3),
    `IC 95%` = sprintf("[%.3f; %.3f]", OR_low, OR_high)
  ) %>%
  knitr::kable()
Tabela 10: Coeficientes do GLM Expandido (CV 5-fold, 2021-2025) | OR = razão de chances
Variável Coef EP z p-valor Sig OR IC 95%
(Intercept) 1.031 0.341 3.02 0.00249 ** 2.805 [1.431; 5.463]
Nenhum 0.837 0.444 1.89 0.05921 . 2.310 [0.989; 5.668]
C8_B -0.816 0.022 -37.74 < 2e-16 *** 0.442 [0.424; 0.461]
C10_C -0.586 0.036 -16.26 < 2e-16 *** 0.557 [0.519; 0.597]
H2 -0.541 0.024 -22.66 < 2e-16 *** 0.582 [0.556; 0.610]
Renda faixa 6 -0.498 0.100 -4.96 7.2e-07 *** 0.608 [0.498; 0.739]
C8_D -0.373 0.031 -12.14 < 2e-16 *** 0.689 [0.648; 0.731]
J2_G -0.339 0.024 -14.09 < 2e-16 *** 0.713 [0.680; 0.747]
J2_L -0.334 0.026 -12.74 < 2e-16 *** 0.716 [0.681; 0.754]
Renda faixa 5 -0.322 0.061 -5.31 1.1e-07 *** 0.725 [0.643; 0.816]
Só celular 0.313 0.292 1.07 0.28298 1.368 [0.772; 2.436]
Ambos 0.302 0.293 1.03 0.30126 1.353 [0.763; 2.412]
J2_K -0.300 0.023 -12.79 < 2e-16 *** 0.741 [0.708; 0.776]
Renda faixa 4 -0.282 0.040 -6.99 2.8e-12 *** 0.754 [0.697; 0.816]
C10_A -0.279 0.028 -9.88 < 2e-16 *** 0.757 [0.716; 0.800]
C10_D -0.251 0.029 -8.67 < 2e-16 *** 0.778 [0.735; 0.824]
PEA 0.239 0.022 11.08 < 2e-16 *** 1.270 [1.218; 1.325]
C9_D -0.236 0.022 -10.77 < 2e-16 *** 0.790 [0.757; 0.824]
C11_A -0.201 0.022 -9.10 < 2e-16 *** 0.818 [0.783; 0.854]
Renda faixa 3 -0.193 0.031 -6.20 5.8e-10 *** 0.825 [0.776; 0.876]
C7_A -0.183 0.022 -8.35 < 2e-16 *** 0.833 [0.798; 0.870]
C8_E -0.169 0.035 -4.83 1.3e-06 *** 0.844 [0.788; 0.904]
J2_J -0.168 0.026 -6.53 6.7e-11 *** 0.845 [0.803; 0.889]
B1 -0.167 0.025 -6.62 3.6e-11 *** 0.846 [0.805; 0.889]
Classe B -0.159 0.160 -0.99 0.32180 0.853 [0.628; 1.177]
Fundamental -0.150 0.045 -3.36 0.00079 *** 0.861 [0.789; 0.939]
C9_C 0.135 0.023 5.85 4.8e-09 *** 1.145 [1.094; 1.198]
C8_A -0.134 0.024 -5.67 1.4e-08 *** 0.875 [0.835; 0.916]
Médio -0.116 0.047 -2.48 0.01309 * 0.890 [0.812; 0.976]
Classe C -0.107 0.160 -0.67 0.50307 0.898 [0.661; 1.239]
Superior -0.065 0.058 -1.12 0.26131 0.937 [0.837; 1.049]
Classe DE -0.061 0.161 -0.38 0.70428 0.941 [0.690; 1.300]
Renda faixa 2 -0.056 0.024 -2.35 0.01880 * 0.946 [0.903; 0.991]
Renda faixa 7 -0.053 0.068 -0.78 0.43819 0.949 [0.831; 1.084]
ano_num 0.003 0.007 0.38 0.70404 1.003 [0.989; 1.016]
IDADE -0.001 0.001 -1.68 0.09247 . 0.999 [0.997; 1.000]
Ver código
coefs_exp_or <- broom::tidy(fit_glm_exp, conf.int = TRUE, exponentiate = TRUE) %>%
  filter(term != "(Intercept)", p.value < 0.05) %>%
  mutate(Variável = rotular_termo(term),
         Variável = fct_reorder(Variável, estimate))

ggplot(coefs_exp_or, aes(x = estimate, y = Variável)) +
  geom_vline(xintercept = 1, linetype = "dashed", color = "grey50") +
  geom_pointrange(aes(xmin = conf.low, xmax = conf.high),
                  color = "#2563EB", size = 0.5) +
  scale_x_log10() +
  labs(x = "Odds Ratio (log)", y = NULL,
       caption = "Referência: RENDA_FAMILIAR=0 (sem renda), CLASSE_CB=A, GRAU_INSTRUCAO=sem instrução, C5_DISPOSITIVOS=computador")
Figura 11: Odds ratios das variáveis significativas no GLM Expandido (eixo x em log)

Leitura dos coeficientes. Entre as 16 variáveis de uso digital do screening, 16 são estatisticamente significativas a \(p < 0{,}05\), das quais 1 têm efeito positivo sobre a probabilidade de uso de e-gov. O maior efeito isolado é o de PEA (OR = 1.27), seguido de perto por C9_C (OR = 1.14) e Renda faixa 2 (OR = 0.95). O efeito de e-commerce (H2) permanece positivo e significativo (OR = 0.58), consistente com a interpretação de Vargas et al. (2021) de familiaridade com transações digitais como facilitador do uso de e-gov. Entre as variáveis do artigo original, após a factorização de CLASSE_CB, GRAU_INSTRUCAO e C5_DISPOSITIVOS, os efeitos alinham-se ao esperado na literatura: maior escolaridade e uso simultâneo de computador e celular associam-se a maior probabilidade de uso de e-gov.

9.5 Holdout temporal (2025 como teste externo)

Para testar a capacidade de previsão fora do período de treino (compatível com a parametrização de ano como variável contínua), os modelos são treinados em 2021-2024 e avaliados em 2025 como dado nunca visto:

Ver código
rotulos_modelo <- c(
  glm_orig = "GLM Original",
  glm_exp  = "GLM Expandido",
  rf_orig  = "RF Original",
  rf_exp   = "RF Expandido"
)

ml$resumo_holdout %>%
  mutate(Modelo = rotulos_modelo[modelo]) %>%
  transmute(Modelo, AUC = round(AUC, 4),
            `Recall` = round(Sens, 4),
            `Precisão` = round(Prec, 4),
            F1 = round(F1, 4),
            `Espec.` = round(Spec, 4)) %>%
  knitr::kable()
Tabela 11: Holdout temporal: treino 2021-2024, teste 2025 | positivo = usa e-gov
Modelo AUC Recall Precisão F1 Espec.
GLM Original 0.7720 0.6486 0.8410 0.7324 0.7595
GLM Expandido 0.8354 0.6802 0.8822 0.7681 0.8218
RF Original 0.7666 0.6530 0.8328 0.7320 0.7429
RF Expandido 0.8293 0.7256 0.8634 0.7885 0.7748

O GLM Expandido avaliado em 2025 de forma completamente cega (treinado apenas com 2021-2024) atinge AUC = 0.8354, contra 0.8306 no CV 5-fold intra-período (ΔAUC = +0.0048). A degradação é desprezível, o que sustenta empiricamente o uso do ano como variável contínua: o padrão de determinantes identificado em 2021-2024 se transfere sem perda relevante para 2025, viabilizando projeções de curto prazo com o mesmo modelo.

9.6 Comparação por fold

Ver código
# summary.resamples()$statistics não traz SD; calculamos direto dos valores.
resultados_ml$values %>%
  pivot_longer(-Resample, names_to = "comb", values_to = "valor") %>%
  separate(comb, into = c("Modelo", "Métrica"), sep = "~") %>%
  group_by(Métrica, Modelo) %>%
  summarise(Média = mean(valor), DP = sd(valor),
            Mín = min(valor), Máx = max(valor),
            .groups = "drop") %>%
  mutate(across(c(Média, DP, Mín, Máx), ~ round(.x, 4))) %>%
  knitr::kable()
Tabela 12: Desempenho por fold — média, desvio e range (CV 5-fold)
Métrica Modelo Média DP Mín Máx
ROC GLM Expandido 0.8307 0.0035 0.8260 0.8336
ROC GLM Original 0.7672 0.0039 0.7633 0.7721
ROC RF Expandido 0.8299 0.0034 0.8257 0.8326
ROC RF Original 0.7700 0.0035 0.7658 0.7747
ROC Árvore 0.7402 0.0029 0.7372 0.7442
Sens GLM Expandido 0.8360 0.0040 0.8308 0.8402
Sens GLM Original 0.8179 0.0067 0.8075 0.8246
Sens RF Expandido 0.8539 0.0025 0.8510 0.8572
Sens RF Original 0.8280 0.0051 0.8222 0.8347
Sens Árvore 0.8159 0.0147 0.7978 0.8303
Spec GLM Expandido 0.6491 0.0082 0.6364 0.6583
Spec GLM Original 0.5404 0.0095 0.5280 0.5528
Spec RF Expandido 0.6189 0.0075 0.6116 0.6272
Spec RF Original 0.5251 0.0118 0.5085 0.5369
Spec Árvore 0.5362 0.0286 0.5071 0.5680
Ver código
dotplot(resultados_ml, metric = c("ROC", "Sens", "Spec"))
Figura 12: Comparação de desempenho dos 5 modelos (CV 5-fold, folds fixos)

9.7 Árvore de decisão (vars do artigo)

Ver código
rpart.plot(modelo_tree$finalModel,
           type = 4, extra = 106,
           under = TRUE, fallen.leaves = TRUE,
           roundint = FALSE,
           main = "Árvore de decisão — Uso de E-gov (2021-2025, vars do artigo)")
Figura 13: Árvore de decisão sobre as variáveis do artigo

9.8 Importância das variáveis (RF expandido)

Ver código
imp_rf <- varImp(modelo_rf_exp)
plot(imp_rf, top = 20,
     main = "Importância das variáveis — Random Forest expandido")
Figura 14: Importância das variáveis no Random Forest expandido

9.9 Habilidades digitais (sub-modelo 2022-2025)

As variáveis I1A_* (habilidades digitais autorreportadas: baixar arquivos, instalar programas, transferir dados, usar planilhas, entre outras) estão disponíveis apenas a partir de 2022 e permitem testar em que medida a proficiência digital autoavaliada adiciona poder preditivo além das variáveis de intensidade de uso. O script fit_i1a.R treina GLM e RF em 2022-2025, com e sem as I1A_*, mantendo folds pareados para comparação direta.

Ver código
i1a$resumo %>%
  transmute(Modelo = modelo, N,
            AUC    = round(AUC, 4),
            Recall = round(Sens, 4),
            `Precisão` = round(Prec, 4),
            F1     = round(F1, 4),
            `Espec.`= round(Spec, 4)) %>%
  knitr::kable(format.args = list(big.mark = "."))
Tabela 13: Sub-modelo 2022-2025 com e sem habilidades digitais (I1A_*)
Modelo N AUC Recall Precisão F1 Espec.
GLM sem I1A_* 56.198 0.8312 0.8299 0.8006 0.8150 0.6597
GLM com I1A_* 56.198 0.8394 0.8200 0.8108 0.8154 0.6850
RF sem I1A_* 56.198 0.8315 0.8521 0.7904 0.8201 0.6279
RF com I1A_* 56.198 0.8417 0.8525 0.7936 0.8220 0.6350

Impacto das habilidades digitais no AUC: GLM Δ = +0.0082, RF Δ = +0.0102. Há ganho preditivo não desprezível com a inclusão das I1A_*, indicando que a proficiência digital autorreportada contém informação residual sobre o uso de e-gov além da intensidade de uso observada.

9.10 Sensibilidade: pesos amostrais (svyglm)

A TIC Domicílios é uma pesquisa com desenho amostral complexo. A análise principal deste relatório trata cada observação com peso unitário, por simplicidade de ajuste e compatibilidade com os algoritmos usados na matriz 2×2. Esta seção apresenta uma análise de sensibilidade em que o modelo logístico é reestimado via survey::svyglm, incorporando os pesos PESO fornecidos pelo Cetic.br, com o objetivo de verificar se os coeficientes estimados se mantêm estáveis sob ponderação.

Ver código
svy$aucs %>%
  transmute(Modelo = modelo,
            `Ponderado?` = if_else(ponderado, "Sim (PESO)", "Não"),
            AUC) %>%
  knitr::kable()
Tabela 14: AUC in-sample: não-ponderado vs svyglm ponderado (mesmo N, pooled 2021-2025)
Modelo Ponderado? AUC
Original Não 0.7674
Expandido Não 0.8310
Original Sim (PESO) 0.7667
Expandido Sim (PESO) 0.8297
Ver código
svy$coefs %>%
  filter(modelo == "Expandido", term != "(Intercept)") %>%
  select(term, ponderado, estimate, std.error, p.value) %>%
  pivot_wider(names_from = ponderado,
              values_from = c(estimate, std.error, p.value),
              names_prefix = "p_") %>%
  rename(est_unw = estimate_p_FALSE, est_pon = estimate_p_TRUE,
         se_unw  = std.error_p_FALSE, se_pon  = std.error_p_TRUE,
         pv_unw  = p.value_p_FALSE,   pv_pon  = p.value_p_TRUE) %>%
  mutate(delta = est_pon - est_unw,
         across(c(est_unw, est_pon, se_unw, se_pon, delta), ~ round(.x, 3)),
         across(c(pv_unw, pv_pon), ~ format.pval(.x, digits = 2))) %>%
  select(Variável = term,
         `Coef (não-pond.)` = est_unw,
         `p (não-pond.)`    = pv_unw,
         `Coef (pond.)`     = est_pon,
         `p (pond.)`        = pv_pon,
         Δ = delta) %>%
  knitr::kable()
Tabela 15: Coeficientes-chave: comparação não-ponderado vs ponderado (modelo Expandido)
Variável Coef (não-pond.) p (não-pond.) Coef (pond.) p (pond.) Δ
IDADE 0.001 0.09247 0.005 0.03874 0.004
PEA -0.239 < 2e-16 -0.277 0.00037 -0.038
H2 0.541 < 2e-16 0.439 3.0e-07 -0.102
RENDA_FAMILIAR2 0.056 0.01880 0.055 0.47273 0.000
RENDA_FAMILIAR3 0.193 5.8e-10 0.184 0.04968 -0.009
RENDA_FAMILIAR4 0.282 2.8e-12 0.319 0.00512 0.036
RENDA_FAMILIAR5 0.322 1.1e-07 -0.099 0.72586 -0.421
RENDA_FAMILIAR6 0.498 7.2e-07 0.630 0.00904 0.132
RENDA_FAMILIAR7 0.053 0.43819 0.082 0.75517 0.030
CLASSE_CB2 0.159 0.32180 0.008 0.97945 -0.150
CLASSE_CB3 0.107 0.50307 -0.231 0.50692 -0.339
CLASSE_CB4 0.061 0.70428 -0.255 0.46981 -0.316
GRAU_INSTRUCAO2 0.150 0.00079 0.141 0.25265 -0.008
GRAU_INSTRUCAO3 0.116 0.01309 0.174 0.18995 0.058
GRAU_INSTRUCAO4 0.065 0.26131 0.058 0.71912 -0.007
C5_DISPOSITIVOS2 -0.313 0.28298 0.489 0.53853 0.802
C5_DISPOSITIVOS3 -0.302 0.30126 0.535 0.50136 0.837
C5_DISPOSITIVOS4 -0.837 0.05921 -0.176 0.84120 0.662
ano_num -0.003 0.70404 -0.008 0.71707 -0.006
C8_A 0.134 1.4e-08 0.205 0.01619 0.071
C8_B 0.816 < 2e-16 0.793 < 2e-16 -0.024
C8_D 0.373 < 2e-16 0.410 0.00027 0.037
C8_E 0.169 1.3e-06 0.112 0.39464 -0.057
J2_L 0.334 < 2e-16 0.241 0.00666 -0.092
J2_J 0.168 6.7e-11 0.232 0.00619 0.063
J2_G 0.339 < 2e-16 0.313 0.00013 -0.025
J2_K 0.300 < 2e-16 0.351 1.6e-06 0.051
C9_D 0.236 < 2e-16 0.202 0.00883 -0.035
C9_C -0.135 4.8e-09 -0.043 0.55392 0.092
C10_A 0.279 < 2e-16 0.292 0.00259 0.013
C10_C 0.586 < 2e-16 0.593 3.4e-06 0.008
C10_D 0.251 < 2e-16 0.230 0.01306 -0.021
C11_A 0.201 < 2e-16 0.284 0.00010 0.083
C7_A 0.183 < 2e-16 0.078 0.29404 -0.105
B1 0.167 3.6e-11 0.178 0.04607 0.010

As diferenças de coeficiente entre o GLM não-ponderado e o svyglm ponderado são, em média, de magnitude modesta: Δ mediano de 0.051 e Δ máximo de 0.837 em log-odds. Há sinais de instabilidade na magnitude de alguns coeficientes quando a ponderação é aplicada (AUC ponderado = 0.830, não-ponderado = 0.831). Embora a direção dos efeitos mais importantes se preserve, a versão ponderada deveria ser reportada em conjunto com a não-ponderada na apresentação formal dos resultados.

NotaSíntese

A extensão do conjunto de variáveis com indicadores de intensidade de uso digital eleva o AUC de 0.767 para 0.830 (ΔAUC = +0.063), tanto no GLM quanto no Random Forest. A coincidência entre GLM e RF no espaço expandido indica estrutura aproximadamente linear, o que permite apresentar a logística expandida como modelo interpretável sem perda preditiva em relação ao random forest. O holdout temporal de 2025 confirma que o modelo generaliza para fora do período de treino e a análise ponderada via svyglm mostra robustez dos coeficientes à escolha de ignorar o desenho amostral no ajuste principal.

10 Discussão

10.1 Evolução do uso de governo eletrônico

A proporção de uso de e-gov entre usuários de internet brasileiros (16+) apresentou oscilação entre 52,6% (2018) e 74,0% (2015) ao longo da década, sem tendência monotônica de crescimento. Os picos em 2023 e 2021 podem estar associados à digitalização acelerada durante e após a pandemia de COVID-19, enquanto os vales em 2018 e 2024 sugerem ciclos que merecem investigação aprofundada.

O valor elevado de 2015 (74,0%) deve ser interpretado com cautela, pois o N é substancialmente menor (2.632 vs 10–16 mil nos demais anos), resultado da ausência da variável C5_Dispositivos naquele ano e de muitos missings em Classe_CB2015.

10.2 Estabilidade do modelo

O AUC-ROC manteve-se notavelmente estável entre 0,7392 e 0,7810 ao longo de toda a série, demonstrando que o conjunto de variáveis proposto por Vargas et al. (2021) mantém poder preditivo consistente ao longo de uma década. Este é um resultado relevante: modelos sociodemográficos frequentemente perdem validade com o tempo, mas neste caso a estrutura se manteve robusta, o que autoriza o uso desse conjunto como linha de base para extensões.

10.3 Determinantes do uso de e-gov no pós-pandemia

A extensão do modelo de Vargas et al. (2021) com as 16 variáveis de intensidade de uso digital eleva o AUC de 0.767 (vars do artigo) para 0.831 no pooled 2021-2025 (N = 68.933, CV 5-fold pareado), um ganho de +0.063 em AUC. Nessa configuração, o modelo atinge recall de 83.6% e precisão de 80.3% para identificar usuários de e-gov, com F1 = 0.819, situando-se dentro do patamar de 80 a 90% considerado como referência de desempenho aplicado.

Dois resultados metodológicos destacam-se dessa comparação. Primeiro, a substituição da logística pelo random forest sobre as mesmas variáveis do artigo original altera o AUC em apenas +0.003. Algoritmos não-lineares, isoladamente, não extraem informação adicional do conjunto original de preditores. Segundo, no espaço ampliado, o random forest iguala a logística (AUC = 0.830 vs 0.831), indicando que a estrutura da relação entre os preditores e o uso de e-gov é aproximadamente linear uma vez que o conjunto relevante de variáveis esteja presente. O ganho preditivo total vem, portanto, das variáveis e não do algoritmo.

A validação preditiva no holdout temporal (treino 2021-2024, teste 2025 cego) reforça esse achado: o GLM Expandido atinge AUC = 0.835 em 2025, com ΔAUC = +0.005 em relação ao desempenho intra-período. A degradação é desprezível, o que sustenta empiricamente a parametrização do ano como variável contínua: o padrão de determinantes identificado em 2021-2024 se transfere sem perda para 2025, habilitando projeções de curto prazo com o mesmo modelo.

Substantivamente, os coeficientes do GLM Expandido apontam para uma leitura ampliada do conceito de familiaridade digital originalmente sugerido pelo artigo de 2019. Enquanto naquele modelo o e-commerce (variável H2) concentrava o efeito associado a transações digitais, o modelo estendido distribui a explicação entre múltiplas formas de uso intensivo da internet, com destaque para busca de informação sobre saúde, busca de cursos, uso de mapas e aplicativos no celular, e compartilhamento de conteúdo. O padrão sugere que a probabilidade de uso de e-gov aumenta com a amplitude e a variedade de atividades digitais de uma pessoa, e não apenas com sua disposição específica a transacionar.

10.4 Habilidades digitais como mecanismo complementar (2022-2025)

A análise restrita ao período 2022-2025 (em que as variáveis de habilidades digitais autorreportadas, I1A_*, estão disponíveis) produziu ganhos de AUC de +0.008 na logística e +0.010 no random forest em relação aos respectivos modelos sem essas variáveis. O ganho é modesto mas direcionalmente consistente com a hipótese de que habilidades digitais se associam positivamente ao uso de e-gov. As I1A_* reforçam a interpretação do modelo principal sem, contudo, alterá-la qualitativamente.

10.5 Mudanças nos preditores

A análise longitudinal revela que enquanto alguns preditores são altamente estáveis (e-commerce, idade), outros apresentam variação temporal significativa:

  • A PEA perdeu força preditiva ao longo dos anos (de 0,526 em 2015 para 0,430 em 2025), possivelmente refletindo a expansão de serviços de e-gov voltados a populações economicamente inativas (programas sociais digitalizados)
  • O efeito do grau de instrução manteve-se forte, reforçando que a educação é uma barreira persistente ao uso de e-gov
  • O teste de razão de verossimilhança do modelo pooled confirma que há variação temporal significativa além das variáveis sociodemográficas (LR = 2172.2, p < 0,001)

10.6 Efeito da pandemia

Embora o módulo G não tenha sido coletado em 2020, os dados de 2021 mostram uma proporção de uso elevada (67,1%), sugerindo que a pandemia pode ter acelerado a adoção de serviços digitais do governo. Os coeficientes do modelo em 2021 não apresentaram mudanças abruptas, indicando que a estrutura dos determinantes socioeconômicos do uso de e-gov não se alterou qualitativamente — apenas o nível geral de adoção aumentou.

11 Limitações

  • 2020 excluído: o módulo G (governo eletrônico) não foi coletado na edição COVID-19 da TIC Domicílios — série com 10 edições em vez de 11
  • 2015 com N reduzido: ausência de C5_Dispositivos e muitos missings em Classe_CB2015 reduziram o N para 2.632 (vs 16.373 em 2025)
  • Grau de instrução em 2024–2025: variável agregada mudou de GRAU_INSTRUCAO_2 para GRAU_INST_1 — ambas com 4 categorias equivalentes (Analfabeto/Fundamental/Médio/Superior)
  • C5_Dispositivos em 2024–2025: novo nível 4 (“Nenhum dispositivo”) filtrado para manter comparabilidade com os 3 níveis originais
  • Critério Brasil: possíveis ajustes menores na classificação da ABEP em 2019 e 2022 podem afetar a comparabilidade da variável de classe econômica
  • 2025 inclui G1_H: nova questão sobre serviços de Justiça incluída no G1_AGREG oficial do Cetic.br — pode inflacionar levemente a proporção de uso em relação aos anos anteriores
  • Pesos amostrais: esta análise não utiliza pesos amostrais (design complexo), o que pode afetar a generalização para a população brasileira
  • Versão dos microdados: utilizamos a v1.1 de 2019 (única disponível no Cetic.br em abril/2026), mesma base de 20.536 observações utilizada no artigo original

12 Referências

  • Vargas, L.C.M., Macadar, M.A., Wanke, P.F., Antunes, J.J.M. (2021). Serviços de governo eletrônico no Brasil: uma análise sobre fatores de impacto na decisão de uso do cidadão. Cadernos EBAPE.BR, 19(Ed. Esp.), 792-810. DOI: 10.1590/1679-395120200206
  • Cetic.br — TIC Domicílios. https://cetic.br/pt/pesquisa/domicilios/
  • Microdados: https://cetic.br/pt/pesquisa/domicilios/microdados/