Pipeline reproduzível para cálculo da Taxa de Chefia

Tratamento e tratamento dos dados da Pesquisa Distrital por Amostra de Domicílios Ampliada - 2024

Author

Phillippi Willian

Published

May 14, 2026

Status

Visão Geral

Este script apresenta um fluxo de trabalho reproduzível para o cálculo da taxa de chefia.

Fonte de dados

Os dados utilizados neste script são provenientes da Pesquisa Distrital por Amostra de Domicílios Ampliada - 2024.

Metodologia

A metodologia usada foi extraída do relatório “Déficit e Demanda Habitacional do Distrito Federal - 2021”, disponível no site do Instituto de Pesquisa Econômica Aplicada (IPEA) aqui.

O foco são pessoas de 24 a 64 anos, usando 3 grupos etários: 24-29, 30-39 e 40-64 anos. A taxa de chefia é calculada como a proporção de pessoas chefes de domicílio em relação ao total de pessoas em cada grupo etário:

\[ \text{Taxa de Chefia}_{i} = \frac{\text{Chefes de Domicílio}_{i}}{\text{Total de Pessoas}_{i}} \]

Onde \(i\) representa os grupos etários: 24-29, 30-39 e 40-64 anos.

Código em R - 2024

Carregar pacotes

# Verifica se o pacman está instalado. Caso não esteja, instala o pacote.
if (!require("pacman")) install.packages("pacman")

# Carrega todos os pacotes
pacman::p_load(
  tidyverse,  # Pacote para manipulação de dados
  readxl,     # Pacote para leitura de arquivos .xls e .xlsx
  lubridate,  # Pacote para manipulação de datas
  data.table, # Pacote para manipulação de dados
  survey,     # Pacote para manipulação de dados survey
  srvyr       # Pacote que ajusta a família tidyverse para dados survey     
  ) 

Download dos Dados

Primeiro, é feito o download dos dados em formato .zip. A função baixar_dados_zipados é responsável por baixar o arquivo, extrair o conteúdo e identificar se ele está em .csv ou .xlsx. Como a base de moradores está em .xlsx e a de domicílios em .csv, a função é capaz de ler ambos os formatos de forma dinâmica. Por fim, ela retorna um dataframe para cada base de dados.

baixar_dados <- function(url) {
  
  # 1. Definir arquivos e pastas temporárias
  temp_zip <- tempfile(fileext = ".zip")
  pasta_temp <- tempdir()
  
  # 2. Baixar o arquivo .zip
  tryCatch({
    download.file(url, temp_zip, mode = "wb", quiet = TRUE)
  }, error = function(e) {
    stop("Erro ao baixar o arquivo. Verifique sua conexão ou a validade da URL.\nDetalhes: ", e$message)
  })
  
  # 3. Listar o que tem dentro do zip
  arquivos_no_zip <- unzip(temp_zip, list = TRUE)$Name
  
  # 4. Buscar por qualquer arquivo que termine em .csv ou .xlsx
  arquivos_alvo <- arquivos_no_zip[grepl("\\.(csv|xlsx)$", arquivos_no_zip, ignore.case = TRUE)]
  
  # Verificações de segurança
  if (length(arquivos_alvo) == 0) {
    unlink(temp_zip)
    stop("Nenhum arquivo .csv ou .xlsx foi encontrado dentro do .zip.")
  } else if (length(arquivos_alvo) > 1) {
    warning("Mais de um arquivo de dados encontrado no .zip. Lendo apenas o primeiro: ", arquivos_alvo[1])
  }
  
  nome_arquivo <- arquivos_alvo[1]
  
  # 5. Extrair o arquivo encontrado para a pasta temporária
  unzip(temp_zip, files = nome_arquivo, exdir = pasta_temp)
  caminho_extraido <- file.path(pasta_temp, nome_arquivo)
  
  # 6. Identificar a extensão para escolher a função de leitura correta
  extensao <- tolower(tools::file_ext(nome_arquivo))
  
  if (extensao == "csv") {
    message("Lendo arquivo CSV...")
    dados <- readr::read_csv2(caminho_extraido)
  } else if (extensao == "xlsx") {
    message("Lendo arquivo Excel...")
    dados <- readxl::read_excel(caminho_extraido)
  }
  
  # 7. Limpeza dos arquivos temporários
  unlink(temp_zip)
  unlink(caminho_extraido)
  
  # 8. Retornar o dataframe
  return(dados)
}

# Dados Domicílios
pdad_dom_2024 <- baixar_dados("https://pdad.ipe.df.gov.br/files/reports/domicilios.zip")

# Dados Moradores
pdad_mor_2024 <- baixar_dados("https://pdad.ipe.df.gov.br/files/reports/moradores.zip")

Tratamento de Dados

Na etapa seguinte, realizamos a unificação das bases de domicílios e moradores. O cruzamento é feito utilizando as variáveis localidade, A01nficha e setor_distrito como chaves de identificação. Em seguida, os códigos numéricos originais da variável localidade são recodificados para criar a variável RA_nome.

# Fazer a junção das bases de moradores e domicílios
pdad_2024 <- pdad_dom_2024 %>%
  # Trazer as informações de pessoas para domicílios
  dplyr::left_join(
    pdad_mor_2024,
    by = c(
      "localidade"     = "localidade",
      "A01nficha" = "A01nficha",
      "setor_distrito"  = "setor_distrito"
    )
  ) %>%
  # Ajustar o nome das RAs
  dplyr::mutate(
    RA_nome = factor(
      case_when(
        localidade == 5301 ~ 'Plano Piloto',
        localidade == 5302 ~ 'Gama',
        localidade == 5303 ~ 'Taguatinga',
        localidade == 5304 ~ 'Brazlândia',
        localidade == 5305 ~ 'Sobradinho',
        localidade == 5306 ~ 'Planaltina',
        localidade == 5307 ~ 'Paranoá',
        localidade == 5308 ~ 'Núcleo Bandeirante',
        localidade == 5309 ~ 'Ceilândia',
        localidade == 5310 ~ 'Guará',
        localidade == 5311 ~ 'Cruzeiro',
        localidade == 5312 ~ 'Samambaia',
        localidade == 5313 ~ 'Santa Maria',
        localidade == 5314 ~ 'São Sebastião',
        localidade == 5315 ~ 'Recanto Das Emas',
        localidade == 5316 ~ 'Lago Sul',
        localidade == 5317 ~ 'Riacho Fundo',
        localidade == 5318 ~ 'Lago Norte',
        localidade == 5319 ~ 'Candangolândia',
        localidade == 5320 ~ 'Águas Claras',
        localidade == 5321 ~ 'Riacho Fundo II',
        localidade == 5322 ~ 'Sudoeste e Octogonal',
        localidade == 5323 ~ 'Varjão',
        localidade == 5324 ~ 'Park Way',
        localidade == 5325 ~ 'SCIA',
        localidade == 5326 ~ 'Sobradinho II',
        localidade == 5327 ~ 'Jardim Botânico',
        localidade == 5328 ~ 'Itapoã',
        localidade == 5329 ~ 'SIA',
        localidade == 5330 ~ 'Vicente Pires',
        localidade == 5331 ~ 'Fercal',
        localidade == 5332 ~ 'Sol Nascente / Pôr do Sol',
        localidade == 5333 ~ 'Arniqueira',
        localidade == 5334 ~ 'Arapoanga',
        localidade == 5335 ~ 'Água Quente',
        localidade == 5336 ~ 'Área Rural',
        localidade == 5241 ~ 'Águas Lindas de Goiás',
        localidade == 5242 ~ 'Alexânia',
        localidade == 5243 ~ 'Cidade Ocidental',
        localidade == 5244 ~ 'Cristalina',
        localidade == 5245 ~ 'Cocalzinho de Goiás',
        localidade == 5246 ~ 'Formosa',
        localidade == 5247 ~ 'Luziânia',
        localidade == 5248 ~ 'Novo Gama',
        localidade == 5249 ~ 'Padre Bernardo',
        localidade == 5250 ~ 'Planaltina de Goiás',
        localidade == 5251 ~ 'Santo Antônio do Descoberto',
        localidade == 5252 ~ 'Valparaíso de Goiás'
      )
    )
  )


# Excluir as bases parciais
rm(pdad_dom_2024, pdad_mor_2024)

Expansão da amostra

Nesta etapa, configuramos o desenho amostral da pesquisa para garantir que as estimativas representem corretamente a população. Primeiro, utilizamos a função svydesign do pacote survey para declarar a estrutura da amostra, definindo a ficha (A01nficha) como a unidade primária, o setor (setor_distrito) como estrato e o peso_mor como fator de expansão. Em seguida, convertemos esse objeto estatístico clássico para o formato de tibble através da função as_survey do pacote srvyr.

# Declarar o desenho incial
sample_pdad <- 
  survey::svydesign(id      = ~A01nficha,        # Identificador único da unidade amostrada
                    strata  = ~setor_distrito,   # Identificação do estrato
                    weights = ~peso_mor,         # Inverso da fração amostral
                    nest    = TRUE,              # Parâmetro de tratamento para os IDs dos estratos
                    data    = pdad_2024          # Declarar a base a ser utilizada
  )

# Ajustar objeto de amostra, para uso com o pacote srvyr (como tibble)
amostra_mor <- srvyr::as_survey(sample_pdad)

Resultados e inferências

Primeiro é calculada a taxa de chefia por grupo etário, utilizando a variável idade_calculada para criar os grupos etários (24-29, 30-39 e 40-64 anos). Em seguida, é feita uma filtragem para considerar apenas os chefes de domicílio (E04==1) e o total de chefes é calculado para cada grupo etário.

# Calcular a taxa de chefia por grupo etário.
tx_chefia <- amostra_mor %>% 
  srvyr::mutate(grupo_etario = case_when(idade_calculada %in% c(24:29) ~ "idade_24_29",
                                         idade_calculada %in% c(30:39) ~ "idade_30_39",
                                         idade_calculada %in% c(40:64) ~ "idade_40_64")) %>% 
  srvyr::filter(E04==1) %>% 
  srvyr::group_by(grupo_etario) %>% 
  srvyr::summarise(total_chefes=survey_total(vartype = c("cv", "ci")))

tx_chefia <- subset(tx_chefia, !is.na(grupo_etario))

# Calcular o total de pessoas na população.
pop_total <- amostra_mor %>%
  srvyr::mutate(
    grupo_etario = case_when(
      idade_calculada %in% c(24:29) ~ "idade_24_29",
      idade_calculada %in% c(30:39) ~ "idade_30_39",
      idade_calculada %in% c(40:64) ~ "idade_40_64"
    )
  ) %>%
  srvyr::group_by(grupo_etario) %>%
  srvyr::summarise(pop_total = survey_total(vartype = c("cv", "ci")))

pop_total <- subset(pop_total,!is.na(grupo_etario))

# Juntar as tabelas para calcular a taxa de chefia por idade.
tx_chefia_idade <- cbind(tx_chefia, pop_total[, -1])

tx_chefia_idade$tx_chefia <- tx_chefia_idade$total_chefes / tx_chefia_idade$pop_total

# Teste para ver se é possível fazer inferência sobre os dados.
# Necessário coeficiente de variação (cv) menor do que 25%
tx_chefia_idade <- as.data.frame(tx_chefia_idade)

tx_chefia_idade$tx_chefia <-
  ifelse(tx_chefia_idade$total_chefes_cv > 0.25,
         NA,
         tx_chefia_idade$tx_chefia)

rm(tx_chefia, pop_total)

Após o cálculo da taxa de chefia por grupo etário, o mesmo processo é repetido para calcular a taxa de chefia por grupo etário e região administrativa (RA). A variável RA_nome é utilizada para identificar as RAs, e a taxa de chefia é calculada para cada combinação de grupo etário e RA.

  # Cálculo a taxa de chefia por idade e RA.
tx_chefia_idade_ra <- amostra_mor %>% 
  srvyr::mutate(grupo_etario = case_when(idade_calculada %in% c(24:29) ~ "idade_24_29",
                                         idade_calculada %in% c(30:39) ~ "idade_30_39",
                                         idade_calculada %in% c(40:64) ~ "idade_40_64")) %>% 
  srvyr::filter(E05==1) %>% 
  srvyr::group_by(grupo_etario, localidade) %>% 
  srvyr::summarise(total_chefes=survey_total(vartype = c("cv", "ci")))

tx_chefia_idade_ra <- subset(tx_chefia_idade_ra, !is.na(grupo_etario))

pop_idade_ra <- amostra_mor %>% 
  srvyr::mutate(grupo_etario = case_when(idade_calculada %in% c(24:29) ~ "idade_24_29",
                                         idade_calculada %in% c(30:39) ~ "idade_30_39",
                                         idade_calculada %in% c(40:64) ~ "idade_40_64")) %>% 
  srvyr::group_by(grupo_etario, localidade) %>% 
  srvyr::summarise(pop_total=survey_total(vartype = c("cv", "ci")))

pop_idade_ra <- subset(pop_idade_ra, !is.na(grupo_etario))

tx_chefia_idade_raf <-
  cbind(tx_chefia_idade_ra, pop_idade_ra[, -c(1, 2)])

tx_chefia_idade_raf$tx_chefia <-
  tx_chefia_idade_raf$total_chefes / tx_chefia_idade_raf$pop_total

tx_chefia_idade_raf <-
  subset(tx_chefia_idade_raf,!is.na(grupo_etario))

  # Teste para ver se inferências podem ser feitas 
tx_chefia_idade_raf <- as.data.frame(tx_chefia_idade_raf)

tx_chefia_idade_raf$tx_chefia <-
  ifelse(tx_chefia_idade_raf$total_chefes_cv > 0.25,
         NA,
         tx_chefia_idade_raf$tx_chefia)

Código em R - 2021

Leitura dos Dados

Os links do antigo código para a base de dados estão quebrados, assim, pelo curto espaço de tempo, os arquivos estão sendo lidos localmente.

pdad_dom_2021 <- read_csv2('dados/01_bruto/PDAD_2021-Domicilios.csv')
pdad_mor_2021 <- read_csv2('dados/01_bruto/PDAD_2021-Moradores.csv')

Tratamento dos Dados

Primeiro, juntou-se os banco de moradores com o de domicílios. Após isso, as variável A01_ra foi decodificada.

# Fazer a junção das bases de moradores e domicílios
pdad_2021 <- pdad_dom_2021 %>%
  # Trazer as informações de pessoas para domicílios
  dplyr::left_join(
    pdad_mor_2021 #%>%
    #dplyr::select(-FATOR_PROJ)
    ,
    by = c(
      "A01ra"     = "A01ra",
      "A01nficha" = "A01nficha",
      "A01setor"  = "A01setor"
    )
  ) %>%
  # Ajustar o nome das RAs
  dplyr::mutate(
    RA_nome = factor(
      case_when(
        A01ra == 1 ~ "Plano Piloto",
        A01ra == 2 ~ "Gama",
        A01ra == 3 ~ "Taguatinga",
        A01ra == 4 ~ "Brazlândia",
        A01ra == 5 ~ "Sobradinho",
        A01ra == 6 ~ "Planaltina",
        A01ra == 7 ~ "Paranoá",
        A01ra == 8 ~ "Núcleo Bandeirante",
        A01ra == 9 ~ "Ceilândia",
        A01ra == 10 ~ "Guará",
        A01ra == 11 ~ "Cruzeiro",
        A01ra == 12 ~ "Samambaia",
        A01ra == 13 ~ "Santa Maria",
        A01ra == 14 ~ "São Sebastião",
        A01ra == 15 ~ "Recanto das Emas",
        A01ra == 16 ~ "Lago Sul",
        A01ra == 17 ~ "Riacho Fundo",
        A01ra == 18 ~ "Lago Norte",
        A01ra == 19 ~ "Candangolândia",
        A01ra == 20 ~ "Águas Claras",
        A01ra == 21 ~ "Riacho Fundo II",
        A01ra == 22 ~ "Sudoeste/Octogonal",
        A01ra == 23 ~ "Varjão",
        A01ra == 24 ~ "Park Way",
        A01ra == 25 ~ "SCIA/Estrutural",
        A01ra == 26 ~ "Sobradinho II",
        A01ra == 27 ~ "Jardim Botânico",
        A01ra == 28 ~ "Itapoã",
        A01ra == 29 ~ "SIA",
        A01ra == 30 ~ "Vicente Pires",
        A01ra == 31 ~ "Fercal",
        A01ra == 32 ~ "Sol Nascente/Pôr do Sol",
        A01ra == 33 ~ "Arniqueira"
      )
    )
  )


# Excluir as bases parciais
rm(pdad_dom_2021, pdad_mor_2021)

Expansão da amostra

Nesta etapa, configuramos o desenho amostral da pesquisa para garantir que as estimativas representem corretamente a população. Primeiro, utilizamos a função svydesign do pacote survey para declarar a estrutura da amostra, definindo a ficha (A01nficha) como a unidade primária, o setor (A01setor) como estrato e o PESO_MOR como fator de expansão. Em seguida, é feita uma correção pó-extrato e por fim convertemos esse objeto estatístico clássico para o formato de tibble através da função as_survey do pacote srvyr.

  # Declarar o desenho incial
sample_pdad <- 
  survey::svydesign(id      = ~A01nficha,        # Identificador único da unidade amostrada
                    strata  = ~A01setor,         # Identificação do estrato
                    weights = ~PESO_MOR,         # Inverso da fração amostral
                    nest    = TRUE,              # Parâmetro de tratamento para os IDs dos estratos
                    data    = pdad_2021 # Declarar a base a ser utilizada
  )

# Criar um objeto para pós estrato
post_pop <- pdad_2021 %>%
  dplyr::group_by(POS_ESTRATO) %>%              # Agrupar por pós-estrato
  dplyr::summarise(Freq=max(POP_AJUSTADA_PROJ)) # Capturar o total da população

# Declarar o objeto de pós-estrato
# Estamos dizendo nesse passo qual é a população alvo para cada
# pós-estrato considerado
amostra <-
  survey::postStratify(sample_pdad,  ~ POS_ESTRATO, post_pop)

# Ajustar para tratamento de estratos com apenas uma UPA (adjust=centered)
options(survey.lonely.psu = "adjust")

# Ajustar objeto de amostra, para uso com o pacote srvyr (como tibble)
amostra_mor <- srvyr::as_survey(amostra)

# Exclui arquivos não mais usados
rm(amostra, sample_pdad, post_pop, pdad_2021)

Resultados e inferências

# Calculando a taxa de chefia por grupo etário.
tx_chefia <- amostra_mor %>% 
  srvyr::mutate(grupo_etario = case_when(idade %in% c(24:29) ~ "idade_24_29",
                                         idade %in% c(30:39) ~ "idade_30_39",
                                         idade %in% c(40:64) ~ "idade_40_64")) %>% 
  srvyr::filter(E05==1) %>% 
  srvyr::group_by(grupo_etario) %>% 
  srvyr::summarise(total_chefes=survey_total(vartype = c("cv", "ci")))

tx_chefia <- subset(tx_chefia, !is.na(grupo_etario))

  # Calculando o total de pessoas na população.
pop_total <- amostra_mor %>%
  srvyr::mutate(
    grupo_etario = case_when(
      idade %in% c(24:29) ~ "idade_24_29",
      idade %in% c(30:39) ~ "idade_30_39",
      idade %in% c(40:64) ~ "idade_40_64"
    )
  ) %>%
  srvyr::group_by(grupo_etario) %>%
  srvyr::summarise(pop_total = survey_total(vartype = c("cv", "ci")))

pop_total <- subset(pop_total,!is.na(grupo_etario))

  # Juntando as tabelas para calcular a taxa de chefia por idade.
tx_chefia_idade_21 <- cbind(tx_chefia, pop_total[, -1])

tx_chefia_idade_21$tx_chefia <-
  tx_chefia_idade_21$total_chefes / tx_chefia_idade_21$pop_total

  # Teste para ver se é possível fazer inferência sobre os dados.
  # Necessário coeficiente de variação (cv) menor do que 25%
tx_chefia_idade_21 <- as.data.frame(tx_chefia_idade_21)

tx_chefia_idade_21$tx_chefia <-
  ifelse(tx_chefia_idade_21$total_chefes_cv > 0.25,
         NA,
         tx_chefia_idade_21$tx_chefia)

rm(tx_chefia, pop_total)
# Cálculo a taxa de chefia por idade e RA.
tx_chefia_idade_ra <- amostra_mor %>% 
  srvyr::mutate(grupo_etario = case_when(idade %in% c(24:29) ~ "idade_24_29",
                                         idade %in% c(30:39) ~ "idade_30_39",
                                         idade %in% c(40:64) ~ "idade_40_64")) %>% 
  srvyr::filter(E05==1) %>% 
  srvyr::group_by(grupo_etario, RA_nome) %>% 
  srvyr::summarise(total_chefes=survey_total(vartype = c("cv", "ci")))

tx_chefia_idade_ra <- subset(tx_chefia_idade_ra, !is.na(grupo_etario))

pop_idade_ra <- amostra_mor %>% 
  srvyr::mutate(grupo_etario = case_when(idade %in% c(24:29) ~ "idade_24_29",
                                         idade %in% c(30:39) ~ "idade_30_39",
                                         idade %in% c(40:64) ~ "idade_40_64")) %>% 
  srvyr::group_by(grupo_etario, RA_nome) %>% 
  srvyr::summarise(pop_total=survey_total(vartype = c("cv", "ci")))

pop_idade_ra <- subset(pop_idade_ra, !is.na(grupo_etario))

tx_chefia_idade_raf_21 <-
  cbind(tx_chefia_idade_ra, pop_idade_ra[, -c(1, 2)])

tx_chefia_idade_raf_21$tx_chefia <-
  tx_chefia_idade_raf_21$total_chefes / tx_chefia_idade_raf_21$pop_total

tx_chefia_idade_raf_21 <-
  subset(tx_chefia_idade_raf_21,!is.na(grupo_etario))

  # Teste para ver se inferências podem ser feitas 
tx_chefia_idade_raf_21 <- as.data.frame(tx_chefia_idade_raf_21)

tx_chefia_idade_raf_21$tx_chefia <-
  ifelse(tx_chefia_idade_raf_21$total_chefes_cv > 0.25,
         NA,
         tx_chefia_idade_raf_21$tx_chefia)

Gráficos

Taxa Chefia por idade em 2024

dados <- tx_chefia_idade

# Formatar os nomes para o eixo X 
dados$grupo_etario_formatado <- factor(dados$grupo_etario, 
                                       levels = c("idade_24_29", "idade_30_39", "idade_40_64"),
                                       labels = c("Entre 24 a 29 anos", "Entre 30 a 39 anos", "Entre 40 a 64 anos"))

# Criar o gráfico
ggplot(dados, aes(x = grupo_etario_formatado, y = tx_chefia, fill = grupo_etario_formatado)) +
    geom_bar(stat = "identity", size = 0.3) +
    geom_text(aes(label = scales::percent(tx_chefia, accuracy = 0.01)),
            vjust = -0.5,
            size = 4,
            color = "black",
            fontface = "bold") +
    scale_fill_manual(values = c("Entre 24 a 29 anos" = "#8c8c8c",  
                               "Entre 30 a 39 anos" = "#e3d17c",  
                               "Entre 40 a 64 anos" = "#b09e33")) + 
    scale_y_continuous(labels = scales::percent_format(accuracy = 1), 
                     limits = c(0, 0.65), 
                     breaks = seq(0, 0.6, 0.1)) + 
    theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.text.x = element_text(angle = 0, hjust = 0.5, face = "bold", size = 10, color = "black"),
    axis.text.y = element_text(size = 10, color = "black"),
    panel.grid.major = element_line(color = "grey95"),
    panel.grid.minor = element_blank(),
    axis.line.x = element_line(color = "grey", size = 0.5),
    legend.position = "none"
  ) +
    labs(y = "Taxa de Chefia")

Taxa Chefia por idade em 2024 e 2021

dados <- tx_chefia_idade |>
  select(
    grupo_etario, 
    tx_chefia_24 = tx_chefia
    ) |>
  left_join(
    tx_chefia_idade_21 |>
      select(
        grupo_etario, 
        tx_chefia_21 = tx_chefia
      )
  ) |>
  pivot_longer(
    cols = c(tx_chefia_24, tx_chefia_21),
    names_to = "ano",
    values_to = "taxa"
    )

dados$grupo_etario <- factor(dados$grupo_etario, 
                                  levels = c("idade_24_29", "idade_30_39", "idade_40_64"),
                                  labels = c("Entre 24 a 29 anos", "Entre 30 a 39 anos", "Entre 40 a 64 anos"))

dados$ano <- factor(dados$ano, 
                         levels = c("tx_chefia_21", "tx_chefia_24"), 
                         labels = c("2021", "2024"))

ggplot(dados, aes(x = grupo_etario, y = taxa, fill = ano)) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
  geom_text(aes(label = scales::percent(taxa, accuracy = 0.1)),
            position = position_dodge(width = 0.8),
            vjust = -0.5,
            size = 3.5,
            fontface = "bold") +
    scale_fill_manual(values = c("2021" = "#d3d3d3", "2024" = "#b09e33")) +
  scale_y_continuous(labels = scales::percent_format(), limits = c(0, 0.65)) +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.text.x = element_text(face = "bold", color = "black"),
    legend.position = "top",
    legend.title = element_blank(),
    panel.grid.minor = element_blank()
  ) +
  labs(y = "Taxa de Chefia")