Skip to content

dimitribessa/r_rais

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sobre o repositório

A ideia aqui é demonstrar uma simples rotina de trabalho de dados com o R, realizando uma análise exploratória nos microdados da RAIS (Relação Anual de Informações Sociais). O intuito é mostrar os passos desde a extração de uma base de dados, à criação e transformação de variáveis necessárias para análises, usando comandos que possam ser compreendidos de forma a serem replicados e/ou modificados em outras bases de dados.

Outro ponto a esclarecer é que existem multiplos pacotes no R para fazer a mesma tarefa, ou comandos distintos que possibilitam os mesmos objetivos que exponho aqui. O que demonstro aqui é apenas uma forma.

Por que usei a RAIS? Esta é uma informação consolidada de um grupo populacional (simplificando a análise, já que não terei que fazer nenhuma inferência estatística), é um banco de dados bem estruturado (com informações completas) e uma quantidade de linhas grande o suficiente para justicar o uso do R.

Baixando e estruturando os microdados

Os microdados da RAIS são disponibilizadas pelo Programa de Disseminação das Estatísticas do Trabalho (PDET/MTE) e podem ser acessadas pelo ftp ftp://ftp.mtps.gov.br/pdet/microdados/ (recomendo o uso do FileZilla para navegar pelos diretórios do PDET). O Ftp também disponibiliza um arquivo de layout, que contém o dicionário dos dados.

Um outro canal onde se pode obter os dados é a Base dos Dados, que por utilizar o Google BigQuery, torna o processo de ETL bem leve e rápido. Entretanto, como quero expor alguns comandos de extração de dados no R, vou deixar este processo para um outro momento (o vídeo do Rocha Data in R explana bem a extração dos dados da RAIS a partir da Base dos Dados).

O processo a seguir consiste em i. baixar o arquivo compactado para um diretório temporário, ii. extrair e por fim iii. ler os dados brutos. Como os arquivos são muito grandes e pesados, este processo leva um certo tempo. Todavia uma opção mais célere é fazer diretamente os passos i. e ii., sem os comandos do R. Também caso se queira com dados de vários anos ou estados simultaneamente, recomendo seguir os passos disponibilizados por Matheus Stivali, podendo ser acessados aqui.

dim(dado)
## [1] 13873188       60

O objeto dado é um data.frame com 13.873.188 linhas e 60 colunas e que contém as informações de vínculos de trabalho dos estados da região sul. Os passos a seguir resume-se em formatar os nomes dos vetores e criar a variável uf (a partir do código IBGE do município), em vista que sintetizarei a análise a apenas ao estado de Santa Catarina.

dim(dado)
## [1] 4249448      60

Ao fim, o df dado ficou com 4.249.448 linhas e 61 colunas.

Análises de contingência simples

Nesta seção focaremos em comandos para realizar uma análise em variáveis qualitativas nominais.

Sobre a natureza dos dados da RAIS, ela contém dados sobre postos de trabalho no mercado formal em determinado ano. No caso aqui, pode-se afirmar portanto que no decorrer do ano de 2024 existiram 4.249.448 postos de trabalho formal, mas como alguns indivíduos foram desligados no decorrer do ano e outros (ou o mesmo) foram admitidos. Para saber a real força de trabalho formal no estado, utiliza-se a variável vinculo_ativo_31/12, que determina quantas pessoas (e cargos) existiam ao fim do ano de referência. Uma forma de se obter isso é tabulando esse vetor, que totaliza 2.545.564 vínculos ativos em 2024 no estado.

table(dado$`vinculo_ativo_31/12`)
## 
##       0       1 
## 1703884 2545564

O banco de dados fornece diversas variáveis qualitativas dos indivíduos, como sexo, faixa etária, nacionalidade e cor da pele, além das características da empresa empregadora, como a localidade (município), o ramo em que atua, o tamanho da empresa e a natureza jurídica, e alguns atributos do cargo, como a classificação da ocupação (CBO) e o salário.

Nesse sentido, farei uma tabulação simples por sexo, o que revela uma concentração maior de homens em relação às mulheres nas ocupações formais de emprego.

#a partir daqui reduzirei o df dado a apenas aos vínculos ativos em dez/24
dado <- dado[dado$`vinculo_ativo_31/12` == 1,]
sexo <- with(dado,as.data.frame(table(sexo_trabalhador)))
sexo$perc <- round(sexo$Freq*100/sum(sexo$Freq),2)
names(sexo)[-1]  <- c('Total', 'Percentual')

kable(rbind('Homens' = c(sexo[1,-1]), 'Mulheres' = c(sexo[2,-1])),align = "c",
      caption = "Quantidades de vínculos ativos em dezembro de 2024, por sexo") %>%
  kable_styling(full_width = F, bootstrap_options = "basic")
Quantidades de vínculos ativos em dezembro de 2024, por sexo
Total Percentual
Homens 1426303 56.03
Mulheres 1119261 43.97

Em seguida é possível construir diversas possibilidades de tabelas de contingência, seja sexo por município, setor econômico por municipio, ocupação por faixa etária, etc. Irei usar o exemplo de sexo por cor da pele. Ressalto que o R proporciona diversas maneiras de se construir uma tabela de contingência - seja via aggregate, tapply da família apply, uso do pacote data.table ou mesmo via groub_by e summarize do tidyverse. Todavia, apenas usei pelo table por opção própria. Enfim, qualquer escolha é válida!

obs. Daqui por diante sigo repetindo os filtros para vínculos ativos (dado[dado$vinculo_ativo_31/12 == 1,]). Poderia simplesmente criar um objeto somente com os dados filtrados ou mesmo reduzir o data.frame dado, mas por se tratar de um objeto relativamente grande, para este caso é de minha preferência repetir a linha de comando à ocupar muito espaço na memória.

sexo_cor_pele <- with(dado,(table(sexo_trabalhador, raca_cor)))
#editando os nomes das variáveis
row.names(sexo_cor_pele) <- c('Homens', 'Mulheres')
colnames(sexo_cor_pele) <- c('Indígena', 'Branca', 'Preta', 'Amarela', 'Parda', 'N. Identificada')

kable(sexo_cor_pele,align = "c",
      caption = "Quantidades de vínculos ativos em dezembro de 2024, por sexo e cor da pele") %>%
  kable_styling(full_width = F, bootstrap_options = "basic")
Quantidades de vínculos ativos em dezembro de 2024, por sexo e cor da pele
Indígena Branca Preta Amarela Parda N. Identificada
Homens 5298 931654 71178 10114 240776 167283
Mulheres 3127 756761 47591 9494 181795 120493

Por fim, podemos calcular as proporções da tabela acima, seja sobre o total ou apenas pelas margens de linha ou coluna. Abaixo demonstrarei uma análise por coluna (para manter o foco sobre o sexo), mas deixarei em comentário como seria o comando para todos os casos. Os números demonstram que a desconcentração de gênero no mercado formal de trabalho é ainda maior em mulheres indígenas, negras e pardas.

#prop_sexo_cor_pele <- prop.table(sexo_cor_pele)*100 #proporção sobre o total
#prop_sexo_cor_pele <- prop.table(sexo_cor_pele,1)*100 #margem de linha
prop_sexo_cor_pele <- prop.table(sexo_cor_pele,2)*100 #margem de coluna

kable(prop_sexo_cor_pele,align = "c",
      caption = "Quantidades de vínculos ativos em dezembro de 2023, proporção de sexo sob cor da pele") %>%
  kable_styling(full_width = F, bootstrap_options = "basic")
Quantidades de vínculos ativos em dezembro de 2023, proporção de sexo sob cor da pele
Indígena Branca Preta Amarela Parda N. Identificada
Homens 62.88427 55.17921 59.92978 51.58099 56.97883 58.12959
Mulheres 37.11573 44.82079 40.07022 48.41901 43.02117 41.87041

Análise de estatística descritiva.

Nesta seção focaremos em comandos para realizar uma análise simples de estatística descritiva, tomando como exemplo variáveis de salário.

O comando summary já resume bastante as principais medidas de posição (média, mediana e alguns quartis) e os valores mínimos e máximos, e somente com isso já demonstra-se algo curioso, que são remunerações zeradas. De acordo com a nota técnica para o ano base 2023 (disponível aqui) isto se dá em vista de uma subdeclaração do campo de remuneração da administração pública.

with(dado, summary(vl_remun_dezembro_nom)) #pegando apenas os vínculos ativos
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0    1951    2637    3330    3828  209022

De forma a retirar o viés de análise dos valores zerados dos salários, realizou-se um summary em cima dos valores de salários excluindo os zeros. Para complementar a análise, calcula-se a moda (o valor com mais frequência) e o desvio padrão (medida de dispersão), para em seguida construir uma tabela sintetizando estas medidas

#construindo vetor de salários, excluindo-se os zeros
salarios <- dado[dado$vl_remun_dezembro_nom > 0,'vl_remun_dezembro_nom']

tab_summary <- summary(salarios) %>% rbind %>% data.frame
moda <- sort(table(salarios), decreasing = T)[1]
dp <- sd(salarios)
#juntando os dados do summary com as informações de moda e de desvio padrão
tab_summary <- data.frame(tab_summary, 'Moda' = as.numeric(names(moda)), 'Desvio Padrão' = dp)
kable(tab_summary,align = "c",
      caption = "Estatísticas descritivas da variável Salário Nominal. 2024.", digits = 2) %>%
  kable_styling(full_width = F, bootstrap_options = "basic")
Estatísticas descritivas da variável Salário Nominal. 2024.
Min. X1st.Qu. Median Mean X3rd.Qu. Max. Moda Desvio.Padrão
. 423.6 2151.98 2800 3687.6 4027 209021.5 1412 3513.24

Os valores distintos de média, moda e mediana sugerem uma assimetria na distribuição dos valores (no caso aqui, como a moda é menor que a mediana, tem-se aqui uma assimetria positiva). Isto pode ser representado num histograma como no exemplo abaixo. Aponto que a Moda deveria ser representada pelo maior valor do histograma, todavia como apliquei a moda sobre uma variável contínua e o histograma é construído a partir de uma frequência absoluta, ao fim não casou os valores aqui.

Para inspiração dos gráficos em ggplot2, recomendo dá uma olhada nos layouts disponíveis no R-graph-gallery e no R-chcarts.

obs. como a distribuição conta com outliers, restringi o histograma até o valor de R$20.000,00 para melhor ilustrar.

#TODO minimizar linhas de código
label <- data.frame( label = c('Média', 'Moda', 'Mediana', '3o Quartil'), posicao = 
  with(tab_summary, c(Mean, Moda, Median, `X3rd.Qu.`)))
theme_set(theme_minimal()) #mudando o theme do ggplot
ggplot(data = as.data.frame(salarios[salarios < 20E3]), aes(x =salarios[salarios < 20E3])) + 
geom_histogram(bins = 25, alpha = .4, color = 'black') +
scale_x_continuous(breaks = seq(0,20E3, 5000)) +
geom_vline(xintercept = tab_summary$Mean, linetype = 'longdash', color = '#162fcf') +
geom_vline(xintercept = tab_summary$Moda, linetype = 'dashed', color = '#f42e13') +
geom_vline(xintercept = tab_summary$Median, linetype = 'dotdash', color = '#f42e13') +
geom_vline(xintercept = tab_summary$`X3rd.Qu.`, linetype = 'dotted', color = '#f42e13') +
ggrepel::geom_label_repel(data = label, aes(x = posicao,
           y = rep(100000,4), label = label), size =4) +
xlab('Salário Nominal\n(R$ em dez/2024)') +
ylab('Qtde de\nIndivíduos')

Podemos também fazer esta análise descritiva do salário para outros grupos de variáveis. Desta vez irei utilizar uma variável para os municípios, entretanto, Santa Catarina conta com 295 cidades, o que deixaria a análise bem extensa. Para simplificar, vou agrupá-los de acordo com o seu tamanho populacional e para tal, utilizarei a API do Sidra/IBGE, que permite extrair os resultados de população do Censo de 2022 (os códigos estão no script populacao_api_sidra.R).

 source('populacao_api_sidra.R')
 dado <- dplyr::left_join(dado, pop_2022[,c('municipio', 'faixa_pop')], by = 'municipio')
 tab_salario_faixa_pop <- tapply(dado[dado$vl_remun_dezembro_nom > 0,'vl_remun_dezembro_nom'],
                  dado[dado$`vinculo_ativo_31/12` == 1 & dado$vl_remun_dezembro_nom > 0,'faixa_pop'] , summary) %>%
                  do.call('rbind',.) #necessário, pois a saíuda do tapply é um array
 kable(tab_salario_faixa_pop,align = "c",
      caption = "Estatísticas descritivas da variável Salário Nominal, por grupos de tamanhos dos municípios. 2024.", digits = 2) %>%
  kable_styling(full_width = F, bootstrap_options = "basic") 
Estatísticas descritivas da variável Salário Nominal, por grupos de tamanhos dos municípios. 2024.
Min. 1st Qu. Median Mean 3rd Qu. Max.
Até 5.000 423.64 2029.16 2605.70 3176.14 3576.00 147013.7
5001-20.000 423.60 2101.02 2683.75 3273.19 3685.46 166857.8
20.001-50.000 423.60 2162.40 2752.85 3407.95 3812.21 162309.2
50.001-100.000 423.60 2176.57 2817.19 3606.86 3990.71 201499.3
100.001-500.000 423.60 2162.73 2832.19 3729.62 4118.29 209021.5
>500.000 423.60 2159.65 2898.00 4266.88 4518.24 194187.2

Uma maneira "clássica" de ilustrar medidas de posição e dispersão é utilizando o gráfico de boxplot. Abaixo, por conta dos outliers, restringi os valores para até R$10.000,00

#label com o "n" de cada grupo de município

ggplot(data = dado[dado$vl_remun_dezembro_nom > 0 & dado$vl_remun_dezembro_nom < 10E3,], aes(x =faixa_pop, y = vl_remun_dezembro_nom)) + 
 geom_boxplot(fill="gray", alpha=0.2) +
 xlab('Tamanho dos municípios') +
ylab('Salário nominal')

De tal forma como foi feito com as tabelas de contingências, é plausível uma análise cruzada com outras variáveis categóricas. Vou exemplificar com a mediana (pois aqui representa melhor a população do que a média) juntamente com variável de tamanho de município e de sexo.

tab_faixa_pop_sexo <- aggregate(vl_remun_dezembro_nom ~ faixa_pop + sexo_trabalhador, 
    data = dado[dado$vl_remun_dezembro_nom > 0,], FUN = median) %>%
    tidyr::spread(., value = vl_remun_dezembro_nom, key = sexo_trabalhador)
names(tab_faixa_pop_sexo) <- c('Faixa\npopulacional', 'Homens', 'Mulheres')

kable(tab_salario_faixa_pop,align = "c",
      caption = "Mediana dos salários nominais por Tamanho dos Municípios e Sexo dos trabalhadores. 2024.", digits = 2) %>%
  kable_styling(full_width = F, bootstrap_options = "basic") 
Mediana dos salários nominais por Tamanho dos Municípios e Sexo dos trabalhadores. 2024.
Min. 1st Qu. Median Mean 3rd Qu. Max.
Até 5.000 423.64 2029.16 2605.70 3176.14 3576.00 147013.7
5001-20.000 423.60 2101.02 2683.75 3273.19 3685.46 166857.8
20.001-50.000 423.60 2162.40 2752.85 3407.95 3812.21 162309.2
50.001-100.000 423.60 2176.57 2817.19 3606.86 3990.71 201499.3
100.001-500.000 423.60 2162.73 2832.19 3729.62 4118.29 209021.5
>500.000 423.60 2159.65 2898.00 4266.88 4518.24 194187.2

Por fim, uma maneira gráfica de ilustrar as diferenças salariais entre os homens e as mulheres é um gráfico quantis x quantis (q x q), ou seja, um gráfico ordenado dos quantis dos salários dos homens contra os mesmos quantis dos salários das mulheres (de novo, por conta de outliers, elaborei o gráfico terminando no quantil 95).

qq_data <- with(dado[dado$vl_remun_dezembro_nom > 0,],
         split(vl_remun_dezembro_nom, sexo_trabalhador))

qq_data <- data.frame('Homens' = quantile(qq_data[[1]], probs = seq(0, .95, 0.005)),
            'Mulheres' = quantile(qq_data[[2]], probs = seq(0,.95, 0.005)))

 ggplot(qq_data , aes(x =Homens, 
                       y = Mulheres)) + 
    geom_point() +
    geom_abline(aes(slope = 1, intercept = 0), linetype = 2) +
    coord_equal()

Considerações

Aqui foram expostas apenas alguns exemplos do que pode ser feito apenas com o uso de estatística descritiva. Com relação aos comandos do R, como ressaltei no início, existem outros caminhos que fazem o que expus aqui. Como eu particularmente já uso o R Base a muito tempo, tenho certa facilidade de ir por aí. Mas de uns anos pra cá, o tidyverse tem facilitado bastante i. os processos de estruturação dos bancos de dados e ii. análises de contingência e estatatísticas descritivas, na medida que vem incorporando funções que são mais amigáveis para entendimento.

Enfim, espero ter ajudado e contribuído com alguma linha de código!

Até a próxima!

About

A short statistical analysis from RAIS database

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages