Pré-processamento e Tratamento de Dados com Tidyverse em R

Jessica Quintanilha Kubrusly

jessicakubrusly@id.uff.br

Patrícia Lusié Velozo da Costa

patricialusie@id.uff.br

Universidade Federal Fluminense

Instituto de Matemática e Estatística

Departamento de Estatística

9 de Dezembro de 2025

Mini bio da Jessica Quintanilha Kubrusly

Mini bio da Patrícia Lusié Velozo da Costa

Participação feminina nas áreas de Exatas

  • Apesar dos avanços em inclusão no ensino superior, a participação feminina nas áreas de Exatas ainda é significativamente menor do que a masculina.

  • Segundo a UNESCO (2021), apenas 30% dos pesquisadores em STEM (ciência, tecnologia, engenharia e matemática) no mundo são mulheres.

  • No Brasil, os dados do INEP (2022) mostram que, embora as mulheres sejam maioria nas universidades, continuam sub-representadas em cursos como matemática, física, engenharia e computação.

  • Essa desigualdade de gênero ainda reflete barreiras sociais, culturais e institucionais que precisam ser enfrentadas.

Sobre o R-Ladies

  • O R-Ladies é uma organização global que promove a diversidade de gênero na comunidade R, incentivando a participação ativa de mulheres e minorias de gênero no uso e desenvolvimento do R.

  • Embora a prioridade seja valorizar e evidenciar que as mulheres têm plena capacidade e alcançam sucesso na área, a participação dos homens é muito bem-vinda e enriquecedora, seja nos minicursos, palestras ou nas discussões.

  • No Brasil e no mundo, os capítulos do R-Ladies realizam eventos, workshops, grupos de estudo e ações de networking para fortalecer a comunidade.

Saiba mais:

Objetivos do minicurso

  • Apresentar o ecossistema Tidyverse
  • Demonstrar técnicas práticas de:
    • Importação
    • Limpeza
    • Transformação
    • Organização de dados
  • Preparar dados para:
    • análises estatísticas
    • visualizações
  • Mostrar boas práticas de reprodutibilidade

Instalando o R

✅ O R é a linguagem de programação que utilizaremos ao longo deste minicurso.

📥 Acesse o site oficial: https://cran.r-project.org

✅ Clique em Download R e escolha o sistema operacional.

✅ Basta seguir as instruções na tela para finalizar a instalação.

Instalando o RStudio

✅ O RStudio é um ambiente de desenvolvimento integrado (IDE) que facilita muito o uso do R.

📥 Acesse: https://posit.co/download/rstudio-desktop/

✅ Clique em Download RStudio Desktop (versão gratuita).

✅ Escolha o instalador correspondente ao seu sistema operacional.

✅ Basta seguir as instruções na tela para finalizar a instalação.

✅ Com o R e o RStudio instalados:

Abra o RStudio → ele automaticamente reconhecerá a instalação do R.

Pronto! Você já pode começar a programar.

Rstudio

Fonte: Irizarry (2023)

Dados utilizados: 1ª base

Neste minicurso, utilizaremos os dados de mortalidade materna do Sistema de Informações sobre Mortalidade (SIM), referentes ao ano de 2010.

O SIM é a principal fonte oficial de informações sobre óbitos no Brasil, permitindo análises epidemiológicas, espaciais e temporais.

A base contém variáveis como:

  • sexo, faixa etária

  • município de residência e ocorrência

  • datas relevantes como a de óbito

  • informações adicionais do atestado de óbito

Dados utilizados: 2ª base

Neste minicurso, também utilizaremos dados de nascidos vivos do Sistema de Informações sobre Nascidos Vivos (SINASC), referentes ao ano de 2010 para o estado do Rio de Janeiro.

O SINASC é a principal fonte oficial de informações sobre nascimentos no Brasil.

A base contém variáveis como:

  • sexo, idade e escolaridade da mãe

  • município de residência e ocorrência

  • informações sobre pré-natal e tipo de parto

  • características do recém-nascido (peso ao nascer, Apgar, anomalias)

Vamos colocar a mão na massa! 🧰✨

📂 Acesse os arquivos do minicurso

👉 Clique aqui para abrir a pasta no Google Drive

Os materiais incluem dados, scripts e exemplos
que usaremos nas atividades práticas.

Como começar?

1️⃣ Faça download dos arquivos e os salve em uma pasta no seu computador.

Caso os arquivos baixados estejam zipados, extraia-os para uma pasta no seu computador.

2️⃣ Abra o arquivo chamado Script zerado.r que está salvo na pasta Scripts.

Pacotes

  • O R é um software gratuito e de código aberto, permitindo que qualquer pessoa desenvolva códigos e funções para ele.

  • Pacotes no R são coleções dessas funções, criadas pela comunidade, que ampliam e facilitam as capacidades do programa, oferecendo soluções prontas para manipulação, análise e visualização de dados.

  • Novos pacotes surgem continuamente para atender a diferentes demandas em um ecossistema em constante evolução e passam por um processo de manutenção e atualização.

  • A instalação padrão do R traz apenas o essencial, mantendo o programa leve e simples, e deixando ao usuário a escolha de quais pacotes adicionais deseja instalar.

  • Para utilizar um pacote, é necessário instalá-lo (uma única vez) com install.packages() e, em seguida, carregá-lo em cada sessão com library() ou require().

  • A diferença entre eles é que library() gera um erro se o pacote não estiver instalado, enquanto require() apenas retorna FALSE e emite um aviso, o que pode ser útil dentro de funções ou condicionais.

# Um exemplo de diferenca entre require e library

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Forma 1: Usando apenas library()
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

library(paco)   # Se o pacote nao estiver instalado, o codigo para aqui com erro.

install.packages("paco") # Primeiro preciso instalar o pacote (somente uma vez).

library(paco) # Depois de instalado, preciso carregar o pacote.

# Se eu fechar o RStudio e abrir este script outro dia, basta rodar:
library(paco) # Apenas carrega o pacote ja instalado.


#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Forma 2: Usando require() para tornar o codigo mais "automatico"
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

if (!require(paco)) {           # require() tenta carregar o pacote.
  install.packages("paco")      # Se nao estiver instalado, o codigo continua e instala.
  require(paco)                 # Depois de instalar, carrega o pacote.
}

# Se eu fechar o RStudio e rodar esse bloco em outro dia, o R verificara se o pacote existe:
# - Se o pacote ja estiver instalado, ele sera apenas carregado.
# - Se nao estiver instalado, sera instalado e depois carregado.
# Assim, o script fica mais robusto e funciona em qualquer maquina.

O que é Tidyverse?

O tidyverse é um conjunto de pacotes do R voltados para ciência de dados.

Principais características:

  • 📦 Conjunto de pacotes integrados
  • 🧹 Foco em dados tidy (organizados)
  • 🔗 A gramática é coerente entre os pacotes
  • 🚀 Facilita leitura, transformação, modelagem e visualização de dados

Pacotes incluídos no Tidyverse:

  • dplyr: manipula e transforma dados com verbos simples.

  • forcats: simplifica o trabalho com variáveis fator.

  • ggplot2: cria gráficos de forma elegante e flexível.

  • purrr: ajuda a trabalhar com listas e programação funcional.

  • readr: importa arquivos de texto de forma rápida.

  • stringr: facilita manipulação de textos e strings.

  • tibble: oferece um formato moderno e mais seguro de data frame.

  • tidyr: organiza dados, deixando-os no formato “arrumado”.

1 Carregando pacotes

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Carregando pacotes ----
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

# caret: funções para modelagem, machine learning e validação cruzada
if (!require(caret)){
  install.packages("caret")
  require(caret)
}

# janitor: limpa nomes de colunas e faz rotinas simples de limpeza de dados
if (!require(janitor)){
  install.packages("janitor")
  require(janitor)
}

# naniar: ferramentas para explorar e visualizar valores faltantes
if (!require(naniar)){
  install.packages("naniar")
  require(naniar)
}

# read.dbc: Pacote para leitura de arquivos .dbc (muito usados no Datasus).
# Não está disponível no CRAN; por isso, fornecemos a alternativa para instalar via devtools, caso necessário.

# Caso seja necessário instalar o pacote via GitHub:
# if (!require(devtools)) {
#   install.packages("devtools")
#   require(devtools)
# }
# devtools::install_github("danicat/read.dbc")

if (!require(read.dbc)) {  
  install.packages("read.dbc");   
  require(read.dbc)
}

# readxl: importa planilhas Excel (.xls e .xlsx) para o R
if (!require(readxl)){
  install.packages("readxl")
  require(readxl)
}

# tidyverse: conjunto de pacotes para manipulação, transformação e visualização de dados
if (!require(tidyverse)){
  install.packages("tidyverse")
  require(tidyverse)
}

# writexl: exporta data frames do R para arquivos Excel (.xlsx)
if (!require(writexl)){
  install.packages("writexl")
  require(writexl)
}

Definindo a pasta de trabalho

  • O R sempre executa comandos a partir de uma pasta de trabalho (working directory), que é o local padrão onde ele procura e salva arquivos.

  • Por isso, é importante verificar qual pasta está sendo usada no momento e, se necessário, alterá-la para o diretório onde seus arquivos estão armazenados.

  • É possível também salvar o caminho de uma pasta em uma variável, o que torna o script mais organizado e evita repetir caminhos ao longo do código.

Imagine que você tem a seguinte estrutura de pastas:

C/
│
├─ Minicurso/
│  └── Dados/
│      └── DOMAT18.csv
│      └── DOMAT18.xlsx
│      └── DOMAT18.dbc
│
│  └── Scripts/
│      └── analise.R
│
│  └── Figuras/
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Definindo a pasta de trabalho ----
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

## Verificar a pasta de trabalho atual
getwd()

## Alterar a pasta manualmente (exemplo)
# setwd("c:/Minicurso/")

## Salvar o caminho de uma pasta em uma variável
# pasta = paste0(getwd(), "/Dados")       
# Alternativamente, usar caminho relativo:
pasta = "../Dados"       # volta uma pasta
# pasta = "../../Dados"    # volta duas pastas

## Construir o caminho completo até um arquivo da pasta
paste0(pasta, "/DOMAT18.csv")

## Mudar temporariamente o diretório do R
atual = getwd()  # salvar o caminho atual
setwd(pasta)      # mudar para a pasta desejada
getwd()           # verificar se mudou corretamente

## Voltar ao diretorio original
setwd(atual)
getwd()

## mostrar o que ha na pasta atual
dir()           

## voltar uma pasta
setwd("..")     
dir()  

## entrar na pasta Dados
setwd("Dados")  
dir()           

# Voltar ao diretorio original
setwd(atual)

2 Processamento de Dados

Antes de qualquer gráfico bonito, modelo sofisticado ou resultado estatístico interessante, existe uma etapa essencial: o processamento de dados.
É aqui que a base bruta se transforma em algo utilizável — limpo, organizado e pronto para responder às perguntas do estudo.

No dia a dia, grande parte do trabalho de quem analisa dados envolve tarefas como:

  • Padronizar nomes de colunas, categorias e tipos de variáveis.
  • Identificar e tratar valores faltantes e possíveis inconsistências.
  • Criar novas variáveis que tornem a análise mais clara e eficiente.
  • Filtrar e selecionar apenas as informações relevantes.
  • Agrupar e resumir dados para extrair insights iniciais.
  • Combinar diferentes bases usando junções (joins).

É justamente nesse ponto que o tidyverse brilha: ele reúne funções pensadas para deixar essas operações mais simples, naturais de ler e fáceis de reproduzir. Tudo gira em torno da ideia de dados organizados no formato tidy: cada coluna é uma variável, cada linha é uma observação e cada célula contém apenas um valor. Essa estrutura consistente facilita todo o fluxo de análise.

Ao aprender funções como mutate(), filter(), select(), arrange(), summarise(), group_by() e os diversos tipos de join(), você passa a ter um conjunto de ferramentas poderoso, capaz de resolver desde pequenas transformações até fluxos de pré-processamento complexos.

Com isso, o processamento de dados deixa de ser um gargalo e passa a ser uma parte natural — e até prazerosa — do trabalho analítico: eficiente, reprodutível e integrada ao restante da análise.

2.1 Importação

  • A importação de dados é o primeiro passo para qualquer análise no R.

  • Consiste em trazer informações armazenadas em diferentes formatos — como planilhas Excel, arquivos CSV ou bancos de dados — para dentro do ambiente do R.

  • Os dados importados são transformados em data frames ou tibbles, que podem ser manipulados, limpos e analisados.

  • Pacotes como readr, readxl e janitor tornam esse processo mais rápido e organizado, permitindo ler arquivos de forma eficiente e preparar os dados para análises posteriores.

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Importando dados ----
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

## Arquivo DBC (DATASUS)
dados_dbc = read.dbc( paste0(pasta, "/DOMAT18.dbc") )

## CSV
dados = read_csv( paste0(pasta, "/DOMAT18.csv") )   # separador = virgula

## CSV com ponto e vírgula (BR)
dados_csv2 = read_csv2( paste0(pasta, "/DOMAT18_2.csv") ) # separador = ponto e virgula

## Excel (.xlsx)
dados_xlsx = read_excel( paste0(pasta, "/DOMAT18.xlsx") )

## RDS (formato interno do R)
dados_rds = read_rds( paste0(pasta, "/DOMAT18.rds") )

## TXT delimitado por TAB
dados_txt_tab = read_delim(
  paste0(pasta, "/DOMAT18.txt"),
  delim = "\t"
)

## TXT delimitado por PIPE (|)
dados_txt_pipe = read_delim(
  paste0(pasta, "/DOMAT18_pipe.txt"),
  delim = "|"
)

## Importar ZIP sem precisar descompactar
dados_zip = read_csv(unz(
  paste0(pasta, "/Exemplo.zip"),
  "DOMAT18.csv"
))

## Ler todos os arquivos de uma pasta
arquivos = list.files(path = paste0(pasta,"/Exemplo2"), pattern = "*.csv", full.names = TRUE)
arquivos
lista_dados = arquivos %>%
  map(read_csv)
dados_todos = bind_rows(lista_dados)

# ## TXT com múltiplos espaços
# dados_txt_espacos = read_table(
#   paste0(pasta, "/DOMAT18.txt")
# )

# ## Importar dados com encoding
# dados_csv_lat1 = read_csv(
#   paste0(pasta, "/DOMAT18.csv"),
#   locale = locale(encoding = "ISO-8859-1")  # ou latin1
# )

## Importar múltiplas planilhas de um XLSX
arquivo = paste0(pasta, "/Exemplo2/Base.xlsx")
arquivo
abas = excel_sheets(arquivo)
abas
lista_abas = map(abas, ~ read_excel(arquivo, sheet = .x))
names(lista_abas) = abas
View(lista_abas)
View(lista_abas[[1]])
View(lista_abas[[2]])

# ## Ler colunas com tipos específicos (evita erros de parsing - que ocorrem quando o R nao consegue interpretar corretamente os dados de um arquivo)
# dados_tipos = read_csv(
#   paste0(pasta,"/DORJ2024.csv"),
#   col_types = cols(
#     DTOBITO = col_character(),
#     CODMUNRES = col_integer(),
#     IDADE = col_double(),
#     ESC = col_character(),
#     .default = col_guess()
#   )
# )

2.2 Manipulação da base de dados

Antes de iniciar qualquer análise, é importante explorar a base de dados para entender sua estrutura, os tipos de variáveis e os valores presentes. Isso ajuda a identificar possíveis problemas, como valores ausentes ou inconsistências, e a planejar as etapas de limpeza e transformação dos dados.

2.2.1 Glimpse

  • A função glimpse() oferece uma visão rápida e resumida da estrutura de um data frame ou tibble.
  • Mostra os tipos de dados de cada coluna e alguns valores de exemplo, de forma mais clara e compacta do que a função str().
  • É especialmente útil para entender rapidamente a composição da base de dados antes de começar a análise.
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## Visualizando estruturas ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

spec(dados) #mostra a especificacao das colunas lidas

str(dados) #mostra tipo do objeto, classes das colunas e alguns valores

glimpse(dados) #visao compacta e horizontal da estrutura 
#    # Leitura mais amigavel e limpa, ideal para tibbles com muitas colunas.

glimpse(dados_xlsx)

glimpse(dados_dbc)
#O arquivo DBC guarda internamente valores como texto, mesmo quando parecem números.

glimpse(dados_xlsx)

glimpse(dados_csv)
#Vamos remover da memoria as bases de dados duplicadas
rm(dados_csv2, dados_rds, dados_txt_pipe, dados_txt_tab, dados_xlsx, 
   dados_zip, dados_todos, lista_dados, arquivos, lista_abas, abas, arquivo)

2.2.2 mutate

  • Função do pacote dplyr usada para criação e transformação de variáveis em um data frame.

  • Permite gerar novas colunas ou modificar colunas existentes de forma clara, organizada e encadeada.

  • As variáveis criadas podem ser utilizadas imediatamente dentro do mesmo mutate(), permitindo operações sucessivas.

  • Integra-se naturalmente com funções como across(), case_when(), if_else() e replace_na(), facilitando regras condicionais e substituições.

  • Essencial para tarefas de pré-processamento, limpeza e manipulação de dados no R, mantendo a legibilidade do código.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## mutate ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Um tibble eh uma versao moderna e mais amigavel do data frame 
# tradicional do R, projetada pelo tidyverse. Ele exibe dados de 
# forma mais limpa, mantem os tipos de cada coluna sem conversoes 
# automaticas e facilita o trabalho com bases grandes ao mostrar 
# apenas as primeiras linhas e informacoes essenciais.

aux = tibble(
  nome   = c("Ana", "Bruno", "Carla", "Daniel"),
  idade  = c(23, 35, 29, 41),
  salario = c(2500, 3800, 3100, 4500)
)
aux

aux = aux %>%
  mutate(idade_em_meses = idade * 12,
         faixa_etaria = if_else(idade < 30, "Jovem", "Adulto"), #if_else: Funcao vetorizada para criar classificacoes
         across(c(idade, salario), ~ .x / 10, .names = "{.col}_div10") #across: Aplica uma funco a várias colunas ao mesmo tempo
         )
aux

2.2.3 Corrigindo classes de variáveis

  • Antes de analisar os dados, é importante garantir que cada coluna esteja no tipo correto, como numeric, integer, character, factor ou logical.

  • Variáveis podem vir importadas com o tipo errado, por exemplo, números como caractere.

  • É recomendado verificar a classe de cada variável com funções como class() ou glimpse() antes e depois da conversão.

  • Funções úteis para corrigir classes:

    • as.numeric() / as.integer() – converte para valores numéricos;
    • as.character() – converte para texto;
    • as.factor() – transforma em fator;
    • as.ordered() – cria fator ordenado;
    • Operadores lógicos, como %in%, podem gerar variáveis logical.
  • Corrigir classes é essencial para calcular estatísticas corretamente, criar gráficos e aplicar modelos.

  • No R, um fator é um tipo de variável usado para representar categorias ou grupos, como gênero, estado civil ou nível de escolaridade.

  • Fatores são importantes para análises estatísticas e gráficos, pois permitem que o R entenda que a variável é categórica e, se necessário, ordenada.

  • Funções úteis para manipulação de fatores (pacote forcats):

    • factor() – cria um fator a partir de uma variável;
    • as.ordered() – cria um fator ordenado;
    • fct_recode() – renomeia ou recodifica níveis;
    • fct_relevel() – reorganiza a ordem dos níveis;
    • fct_lump() – agrupa níveis pouco frequentes em “outros”.
  • Fatores podem ser nominais (sem ordem) ou ordenados (com hierarquia), dependendo do contexto da análise.

  • Corrigir e ordenar fatores corretamente é essencial para estatísticas, visualizações e modelagem, garantindo que a interpretação dos resultados seja adequada.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## convertendo automaticamente  ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Fazendo um "backup" dos dados
aux = dados
#dados = dados_dbc

#PASSO 1 — Converte fatores para texto (preserva zeros das datas)
glimpse(dados)

dados = dados %>%
  mutate(across(everything(), as.character))

glimpse(dados)

#PASSO 2 — Converte DATAS primeiro (antes de virar número!)

dados = dados %>%
  mutate(across(matches("^DT"), ~ as.Date(.x, format = "%d%m%Y")))

glimpse(dados)

#PASSO 3 — Converte automaticamente o que é número, SEM mexer nas datas

dados = dados %>%
  mutate(
    across(
      .cols = where(~ !inherits(.x, "Date")),  # ignora datas
      .fns  = ~ type.convert(.x, as.is = TRUE)
    )
  )

glimpse(dados)

class(dados$DTATESTADO)

#vizualizando a variavel depois da manipulacao
aux$DTATESTADO[1:10]
dados$DTATESTADO[1:10]
year(dados$DTATESTADO[5])
month(dados$DTATESTADO[5])
day(dados$DTATESTADO[5])

2.2.4 Corrigindo a classe das variáveis - PASSO A PASSO

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## convertendo manualmente  ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Para isso, usaremos a base de dados inicial, salva em aux

#vizualizando a variavel antes da manipulacao
aux$DTATESTADO[1:10]
class(aux$DTATESTADO)

### transformando em data
# Formato DDMMAAAA
aux = aux %>%
  mutate(
    # Usa a função dmy() do pacote lubridate para converter o formato Dia/Mês/Ano
    DTATESTADO2 = lubridate::dmy(DTATESTADO) #ymd(), dmy(), mdy()
  )

#vizualizando a variavel depois da manipulacao
aux$DTATESTADO2[1:10]
class(aux$DTATESTADO2)
year(aux$DTATESTADO2[5]) #extrai o ano
month(aux$DTATESTADO2[5]) #extrai o med
day(aux$DTATESTADO2[5]) #extrai o dia
wday(aux$DTATESTADO2[5]) #informa o dia da semana

# O problema da conversao manual ocorre quando ha muitas colunas, que eh o caso presente aqui!

# Para mostrar outras formas de conversao, usaremos uma base curta para ilustracao:

# Simulando uma variável
aux2 = tibble(
  ESC = sample(c("FI", "FII", "M", "SI", "S"), size = 20, replace = TRUE)
)

# Criando tres versoes de fatores
aux2 = aux2 %>%
  mutate(
    # Fator simples com labels
    ESC_mod = factor(ESC, labels = c("FundI", "FundII", "Médio", "Sem instrução", 
                                     "Superior") ),
    # Recode via fct_recode
    ESC_mod2 = ESC %>%
      as.character() %>%
      fct_recode(
        "Sem instrução" = "SI",
        "FundI"         = "FI",
        "FundII"        = "FII",
        "Médio"         = "M",
        "Superior"      = "S"
      ),
    # Ordered factor com ordem explícita
    ESC_mod3 = ESC_mod2 %>%
      fct_relevel(
        "Sem instrução", 
        "FundI", 
        "FundII", 
        "Médio", 
        "Superior" 
      ) %>% 
      as.ordered(),
    
    # Convertendo para outras classes
    ESC_char = as.character(ESC),           # variavel como caractere
    ESC_numeric = as.numeric(factor(ESC)),  # variavel como numerica (usando ordem dos fatores)
    ESC_logical = ESC %in% c("FI", "FII")   # variavel logica: TRUE se FundI ou FundII
    
  )

# Visualizando tabelas
table(aux2$ESC)
table(aux2$ESC_mod) #PROBLEMA!!!!
table(aux2$ESC_mod2)
table(aux2$ESC_mod3)

# Visualizando as novas classes
head(aux2[, c("ESC_char", "ESC_numeric", "ESC_logical")])

2.2.5 Cuidado!

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## Cuidado!  ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@


# Voltaremos agora a base de dados com as classes convertidas automaticamente.

# Veja um exemplo de problema na conversao automatica:
dados$IDADE[1:5]
class(dados$IDADE)
aux$IDADE[1:5]
class(aux$IDADE)

# Removendo o primeiro algarismo dessa variavel
dados = dados %>%
  mutate(
    # garantir que está em texto
    IDADE = as.character(IDADE),
    # remover o 1º caractere (unidade da idade)
    IDADE = substring(IDADE, 2, 3) |> as.numeric()
  )
dados$IDADE[1:5]
class(dados$IDADE)

# Recodificando variaveis do tipo fatores
dados = dados %>% 
  mutate(ESC2010_mod = ESC2010 %>%
      as.character() %>%
      fct_recode(
        "Sem instrução"        = "0",
        "FundI"                = "1",
        "FundII"               = "2",
        "Médio"                = "3",
        "Superior Incompleto"  = "4",
        "Superior"             = "5",
        "Ignorado"             = "9"
      ) %>% 
      fct_relevel(
        "Sem instrução", 
        "FundI", 
        "FundII", 
        "Médio", 
        "Superior Incompleto",
        "Superior",
        "Ignorado"
      ) %>% 
      as.ordered()
  )
table(dados$ESC2010)
table(dados$ESC2010_mod)

dados = dados %>% 
  mutate(RACACOR_mod = RACACOR %>%
           as.character() %>%
           fct_recode(
             "Branca"   = "1",
             "Preta"    = "2",
             "Amarela"  = "3",
             "Parda"    = "4",
             "Indigena" = "5"
           )
  )

tibble(dados$RACACOR[1:5],dados$RACACOR_mod[1:5])
table(dados$RACACOR)
table(dados$RACACOR_mod)

2.2.6 filter

  • A função filter(), do pacote dplyr, é usada para selecionar linhas de um data frame ou tibble que atendem a certas condições.

  • Permite trabalhar com condições lógicas, como ==, >, <, >=, <=, %in%, entre outras.

  • É útil para reduzir o conjunto de dados e focar apenas nas observações que são relevantes para a análise.

  • Pode combinar múltiplas condições usando vírgula (equivalente a AND) ou o operador | (equivalente a OR).

  • Sempre retorna um novo data frame ou tibble, mantendo as colunas originais, mas apenas com as linhas que satisfazem os critérios especificados.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## filter ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Filtra apenas pessoas com escolaridade "FundI"
aux = dados %>% 
  filter(ESC2010_mod == "FundI")

# Filtra pessoas cuja escolaridade é "FundI" OU "Superior"
aux = dados %>% 
  filter(ESC2010_mod %in% c("FundI", "Superior"))

# Filtra pessoas com idade maior que 30 anos
aux = dados %>% 
  filter(IDADE > 30)

# Filtra pessoas com escolaridade "FundI" E idade maior ou igual a 25 anos
aux = dados %>% 
  filter(ESC2010_mod == "FundI", IDADE >= 25)

# Filtra apenas linhas onde o valor de IDADE NÃO é NA (ou seja, idade informada)
aux = dados %>% 
  filter(!is.na(IDADE))

# Filtra apenas linhas onde o valor de IDADE é NA (idade não informada)
aux = dados %>% 
  filter(is.na(IDADE))

# Filtra pessoas com idade ENTRE 20 e 40 anos (limites incluídos)
aux = dados %>% 
  filter(between(IDADE, 20, 40))

2.2.7 select

  • A função select(), do pacote dplyr, é usada para escolher colunas específicas de um data frame ou tibble.

  • Permite criar um novo objeto com apenas as colunas desejadas, facilitando a manipulação e análise.

  • É possível selecionar colunas por:

    • Nome exato: select(dados, coluna1, coluna2)
    • Padrão de nomes com helpers como starts_with(), ends_with(), contains(), matches().
    • Negação: -coluna remove a coluna do resultado.
  • select() é útil para reduzir a base de dados, mantendo apenas o que é relevante para análise ou visualização.

  • Combinar select() com outras funções do dplyr (como filter(), mutate()) permite criar fluxos de manipulação de dados claros e eficientes.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## select ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Seleciona apenas algumas colunas
aux = dados %>% 
  select(IDADE, ESC2010)

# Seleciona todas menos uma 
aux = dados %>% 
  select(-IDADE)

# Seleciona colunas por padrão no nome
aux = dados %>% 
  select(starts_with("F"))   

# Seleciona colunas que terminam com "R"
aux = dados %>% 
  select(ends_with("R"))    

# Selecionar por tipo de dado
aux = dados %>% 
  select(where(is.character))

# Reordena colunas (nome primeiro, o resto depois)
aux = dados %>% 
  select(IDADE, everything())

# Renomeia colunas dentro do select
aux = dados %>% 
  select(Escolaridade = ESC2010, Idade = IDADE)

2.2.8 janitor

  • O pacote janitor oferece funções simples e eficientes para limpar e organizar bases de dados.

  • É especialmente útil para dados importados de planilhas Excel ou CSV, que podem conter nomes de colunas inconsistentes, espaços extras ou caracteres especiais.

  • Funções mais comuns:

    • clean_names() – padroniza os nomes das colunas para letras minúsculas e formato “snake_case”;
    • remove_empty() – remove linhas ou colunas vazias;
    • get_dupes() – identifica duplicatas;
    • tabyl() – cria tabelas de frequência simples e rápidas.
  • Usar janitor ajuda a preparar a base de dados para análise, tornando o código mais limpo e evitando erros por nomes inconsistentes.

  • Funciona muito bem em combinação com dplyr e tidyverse, permitindo pipelines claros e organizados.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## janitor ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Base com nomes de colunas "problematicos"
aux = tibble(
  "Nome do Aluno" = c("Ana", "Bruno"),
  "Idade (anos)" = c(20, 22),
  "% Presença" = c(0.95, 0.87)
)
names(aux)

# Limpando e padronizando os nomes das colunas
aux_limpos = aux %>% 
  clean_names()
names(aux_limpos)

rm(aux, aux_limpos, aux2)

2.2.9 slice

  • A função slice(), do pacote dplyr, permite selecionar linhas específicas de um data frame ou tibble com base na posição das linhas.

  • Diferente de filter(), que usa condições lógicas, slice() seleciona linhas por índice numérico.

  • Funções relacionadas:

    • slice_head(n = ) – seleciona as primeiras n linhas;
    • slice_tail(n = ) – seleciona as últimas n linhas;
    • slice_sample(n = ) – seleciona n linhas aleatórias;
    • slice_min(order_by = ) / slice_max(order_by = ) – seleciona linhas com valores mínimo ou máximo de uma coluna.
  • slice() é útil para inspecionar rapidamente partes do dataset, testar scripts ou criar subconjuntos de dados para análise ou visualização.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## slice ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Base de exemplo
aux = tibble(
  id = 1:10,
  valor = c(5, 8, 3, 9, 2, 7, 6, 4, 1, 10)
)

# Selecionar as linhas 2, 5 e 7
aux %>% slice(2, 5, 7)

# Selecionar as 3 primeiras linhas
aux %>% slice_head(n = 3)

# Selecionar 4 linhas aleatórias
aux %>% slice_sample(n = 4)

# Ou selecionar 30% da base aleatoriamente
aux %>% slice_sample(prop = 0.3)

# Últimas 3 linhas da base
aux %>% slice_tail(n = 3)

# Selecionar as 2 menores observações da coluna "valor"
aux %>% slice_min(valor, n = 2)

#Também pode selecionar pela proporção
aux %>% slice_min(valor, prop = 0.2)  # 20% das linhas com menor valor

# Selecionar as 3 maiores observações da coluna "valor"
aux %>% slice_max(valor, n = 3)

2.2.10 rename

  • As funções rename() e rename_with(), do pacote dplyr, servem para alterar os nomes das colunas de um data frame ou tibble.

  • rename() é usada para renomear colunas individualmente, informando o novo nome seguido do nome antigo.

  • rename_with() aplica uma função a vários nomes de coluna ao mesmo tempo, como toupper(), tolower() ou funções do pacote janitor como clean_names().

  • Renomear colunas ajuda a padronizar nomes, evitar espaços ou caracteres especiais e deixar os scripts mais claros e organizados.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## rename ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

aux = tibble(
  idade = c(10, 20, 30),
  sexo = c("F", "M", "F"),
  renda_mensal = c(1200, 2500, 3000)
)

# Renomeando colunas específicas
aux %>%
  rename(
    #novo_nome = nome_antigo
    idade_anos = idade,
    renda = renda_mensal
  )

#coloca tudo em maiúsculas
aux %>%
  rename_with(toupper)

#coloca tudo em minúsculas
aux %>%
  rename_with(tolower)

#substitui espaços por underline em todas as colunas
aux %>%
  rename_with(~ gsub(" ", "_", .x))

#renomeia apenas colunas que começam com "r"
aux %>%
  rename_with(toupper, starts_with("r"))

#adiciona um prefixo em todos os nomes
aux %>%
  rename_with(~ paste0("var_", .x))

2.2.11 group_by

  • A função group_by() é utilizada para agrupar os dados por uma ou mais variáveis, permitindo que operações posteriores sejam realizadas separadamente para cada grupo.

  • Esse agrupamento é especialmente útil em conjunto com funções como summarise(), mutate() e count(), possibilitando cálculos agregados por categoria.

  • Após o uso, recomenda-se aplicar ungroup() para evitar que operações subsequentes continuem sendo feitas por grupo de forma indesejada.

  • O uso de group_by() torna análises por sexo, faixa etária, município, ano ou qualquer outra variável mais simples, organizadas e transparentes no fluxo do tidyverse.

# Exemplo 1: Contagem de obitos por Escolaridade

dados_resumo1 = dados %>% 
  group_by(ESC2010_mod) %>%            # cria grupos por Escolaridade
  summarise(
    n = n(),                    # numero total de registros por Escolaridade
    idade_media = mean(IDADE, na.rm = TRUE)  # idade media
  ) 

dados_resumo1

# Exemplo 2: Contar obitos por raca/cor e escolaridade
dados_resumo2 = dados %>% 
  group_by(RACACOR_mod, ESC2010_mod) %>%   # grupos cruzando duas variaveis
  summarise(
    total = n(),
    idade_media = mean(IDADE, na.rm = TRUE)
  ) 

dados_resumo2

# Quando devo usar o ungroup?

#ERRADO sem ungroup()
dados %>% 
  group_by(ESC2010_mod) %>% 
  summarise(n = n()) %>% 
  mutate(prop = n / sum(n))  

#Codigo correto
dados %>% 
  group_by(ESC2010_mod) %>% 
  summarise(n = n()) %>% 
  ungroup() %>% 
  mutate(prop = n / sum(n))

rm(dados_resumo1, dados_resumo2)

2.2.12 arrange

  • A função arrange() é usada para ordenar linhas de um data frame de acordo com uma ou mais variáveis.
  • Por padrão, a ordenação é crescente, mas é possível ordenar em ordem decrescente usando desc().
  • A função é especialmente útil para identificar valores extremos, organizar relatórios ou preparar dados para visualizações.
  • Como não altera os nomes das colunas nem cria novos grupos, arrange() é uma etapa simples, rápida e muito utilizada no fluxo de manipulação de dados no tidyverse.
aux = tibble(
  NOME = c("Ana", "Fernanda","Carla", "Daniel", "Bruno", "Eduardo"),
  IDADE = c(23, 35, 28, 35, 19, 42),
  ESCOLARIDADE = c("Superior", "Médio", "Superior", "Fundamental", "Fundamental", "Médio"),
  RENDA = c(3500, 2500, 4200, 1800, 1200, 5200)
)
aux

# Ordenar os dados pelos nomes em ordem alfabetica crescente
aux %>% 
  arrange(NOME)

# Ordenar os dados pelos nomes em ordem alfabetica decrescente
aux %>% 
  arrange(desc(NOME))

# Primeiro pela escolaridade e, dentro de cada grupo, pela idade
aux %>% 
  arrange(ESCOLARIDADE, IDADE)

2.2.13 Outras funções

# Criando uma base de exemplo
aux = tibble(
  nome   = c("Ana", "Bruno", "Carlos", "Ana"),
  idade  = c(23, 35, 29, 23),
  cidade = c("Niteroi", "Rio de Janeiro", "Niteroi", "Sao Goncalo"),
  renda_2023 = c(3000, 4500, 5000, 3200),
  renda_2024 = c(3200, 4700, 5200, NA),
  data_nasc = c("2000-05-10", "1988/12/03", "1994-01-28", "2000/05/10"),
  codigo = c("ID:45-A", "ID:22-B", "ID:77-A", "ID:45-A")
)

# Numero de cidades distintas
n_distinct(aux$cidade)

# Selecionar colunas que começam com "renda"
aux %>% select(starts_with("renda"))

# Selecionar colunas que contenham "idade"
aux %>% select(contains("idade"))

# Selecionar colunas que começam com "renda"
aux %>% select(starts_with("renda"))

# Selecionar colunas que contenham "idade"
aux %>% select(contains("idade"))

# Cria novas variaveis mantendo apenas as novas colunas
aux %>% 
  transmute(
    nome,
    renda_total = renda_2023 + renda_2024
  )

# Permite operacoes linha a linha (util quando a soma nao deve ser feita por coluna)
aux %>%
  rowwise() %>%
  mutate(renda_media = mean(c(renda_2023, renda_2024), na.rm = TRUE))

# Trocar caractere
aux %>%
  mutate(data_nasc = str_replace(data_nasc, "/", "-"))

# Extrair apenas o numero do codigo
aux %>%
  mutate(numero_codigo = str_extract(codigo, "\\d+"))

# Resumo estatistico de varias colunas
aux %>%
  summarise(
    across(starts_with("renda"), 
           list(media = mean, mediana = median), 
           na.rm = TRUE)
  )

# Mover colunas de posicao
aux %>%
  relocate(codigo, .before = nome)

# Remove linhas duplicadas
aux %>% distinct()

# Distintos apenas por nome
aux %>% distinct(nome, .keep_all = TRUE)

# Transformar colunas em linhas
aux_long = aux %>%
  pivot_longer(
    cols = starts_with("renda"),
    names_to = "ano",
    values_to = "valor"
  )

# Separar codigo em duas partes
aux_sep = aux %>%
  separate(codigo, into = c("tipo", "valor"), sep = ":")

# Unir colunas novamente
aux_sep %>% unite("codigo2", tipo, valor, sep = "-")

# Preencher NAs com o ultimo valor observado
aux_long %>%
  arrange(nome, ano) %>%
  fill(valor, .direction = "down")

# Retornar o primeiro valor nao NA entre varias colunas
aux %>%
  mutate(
    renda_final = coalesce(renda_2024, renda_2023)
  )

# Transformar linhas em colunas (wide)
aux_wide = aux_long %>%
  pivot_wider(
    names_from = ano,
    values_from = valor
  )

2.2.14 Tratamento de valores faltantes

  • Valores faltantes (NA) são comuns em bases de dados e podem afetar estatísticas, gráficos e modelos se não forem tratados corretamente.

  • O R possui funções específicas para lidar com NAs, como:

    • is.na() – identifica valores faltantes;
    • na.omit() ou drop_na() (do dplyr) – remove linhas com NAs;
    • replace_na() (do tidyr) – substitui NAs por um valor definido;
    • Funções de resumo, como mean() ou sum(), permitem o argumento na.rm = TRUE para ignorar NAs nos cálculos.
  • É importante avaliar a quantidade e o padrão de valores faltantes antes de decidir o tratamento, pois remover dados indiscriminadamente pode viésar a análise.

  • Estratégias comuns de tratamento incluem remoção, substituição por média/mediana/moda ou imputação avançada, dependendo do tipo de variável e do objetivo da análise.

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
## Tratamento de valores faltantes ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

# Visualizando o número de colunas antes da limpeza
ncol(dados)

# Retirando colunas completamente vazias (todas NA)
# `select(where(...))` mantém apenas as colunas que atendem à condição
# O `.` refere-se à coluna atual sendo testada
dados = dados %>%
  select(where(~ !all(is.na(.))))

# Visualizando o número de colunas depois da limpeza
ncol(dados)

# Removendo todas as linhas onde pelo menos uma coluna contém NA
nrow(dados) # número de linhas antes da remoção
dados_sem_na = dados %>% drop_na()
nrow(dados_sem_na) # número de linhas depois da remoção

# Removendo linhas apenas quando NAs ocorrerem em colunas específicas
nrow(dados)
aux = dados %>% drop_na(c("IDADE", "RACACOR"))
nrow(aux)

# Substituindo valores ausentes por um valor especifico
# Exemplo: na coluna ESC2010, substituir NA por "9"
table(dados$ESC2010) # valores originais
length(which(is.na(dados$ESC2010))) + length(which(dados$ESC2010 == 9)) 
      #contando NAs + código 9

dados = dados %>%
  mutate(
    ESC2010_ = replace_na(ESC2010, 9)  # substituindo NA por 9 quando a classe da variavel for numerica
    #ESC2010_ = replace_na(ESC2010, "9")  # substituindo NA por "9" quando a classe da variavel for categorica
  )
table(dados$ESC2010_) # visualizando os valores apos substituição
table(dados$ESC2010) # visualizando os valores apos substituição

# Contando quantos NA existem por coluna
dados %>%
  summarise(across(everything(), ~ sum(is.na(.))))

# Contando quantos NA existem por linha
dados = dados %>% 
  mutate(qtd_na = rowSums(is.na(.)))
dados$qtd_na

# Filtrando linhas que estao “quase vazias” (por exemplo, 30% de NA)
nrow(dados)
dados3 = dados %>% 
  filter(rowMeans(is.na(.)) < 0.3)
      #rowMeans: calcula a media de cada linha de uma matriz ou 
      #data frame. Apenas para colunas numericas.
nrow(dados3)

# Identificando quais linhas estao “quase vazias” 
dados_flag = dados %>%
  mutate(
    removida = rowMeans(is.na(.)) >= 0.3   # TRUE = será removida
  )

# linhas removidas
linhas_removidas = dados_flag %>% 
  filter(removida)

# linhas mantidas
linhas_mantidas = dados_flag %>% 
  filter(!removida)

2.3 Agregação

#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@
# Agrupando por municipio de residencia ----
#-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@-@

dados_agregados = dados %>%
  group_by(CODMUNRES) %>%
  summarise(
    total_mortes = n(),
    idade_media = mean(IDADE, na.rm = TRUE),
    
    # total por raca
    total_raca = list(table(RACACOR)),
    
    # total por escolaridade
    total_escolaridade = list(table(ESC2010_mod))
  )

# ordenando a base pelos nomes das colunas
dados_agregados = dados_agregados %>% 
  select(sort(names(.)))

# visualizando a base
dados_agregados

2.4 Exportação

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Exportando dados ----
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

getwd() #para saber onde o R salvara os arquivos exportados

base = dados_agregados

# Exportar como RDS
write_rds(base, "dados_agregados.rds")
#write_rds(base, paste0(pasta,"/dados_agregados.rds")) #caso queira mudar o caminho de onde sera salvo o arquivo

# Exportar como xlsx
write_xlsx(base, "dados_agregados.xlsx")

# Exportar como CSV (vírgula)
write_csv(base, "dados_agregados.csv")

# Exportar como CSV brasileiro (ponto e vírgula)
write_csv2(base, "dados_agregados_PontoVirg.csv")

# Exportar como TXT
write.table(
  base,
  file = "dados_agregados.txt",
  sep = "\t",
  row.names = FALSE,
  quote = FALSE
)

# Exportar como TXT separado por pipe
write.table(
  base,                       # seu data frame
  file = "dados_agregados_pipe.txt",     # nome do arquivo
  sep = "|",                   # PIPE como delimitador
  row.names = FALSE,           # não salvar nomes das linhas
  quote = FALSE                # não colocar aspas em textos
)

3 Referências

📖 BRASIL. Ministério da Saúde. Secretaria de Vigilância em Saúde. Sistema de Informações sobre Mortalidade – SIM. Brasília: Ministério da Saúde, [s.d.]. Disponível em: https://datasus.saude.gov.br/sistema-de-informacoes-sobre-mortalidade-sim/ . Acesso em: 25 de novembro de 2025.

📖 R Core Team. (2024). R: A Language and Environment for Statistical Computing. Vienna: R Foundation for Statistical Computing. Disponível em: https://www.R-project.org/ . Acesso em: 24 de maio de 2025.

📖 BRASIL. Ministério da Saúde. Secretaria de Vigilância em Saúde. Sistema de Informações sobre Mortalidade – SIM. Brasília: Ministério da Saúde, ano-base 2010. Disponível em: https://datasus.saude.gov.br/transferencia-de-arquivos/# . Acesso em: 25 de novembro de 2025.

📖 BRASIL. Ministério da Saúde. Secretaria de Vigilância em Saúde. Sistema de Informações sobre Nascidos Vivos – SINASC. Brasília: Ministério da Saúde, ano-base 2010. Disponível em: https://datasus.saude.gov.br/transferencia-de-arquivos/# . Acesso em: 25 de novembro de 2025.

📖 Wickham, H.; Grolemund, G. (2023). R para ciência de dados: importe, organize, transforme, visualize e modele dados. 2. ed. Rio de Janeiro: Alta Books.

Agradecemos a participação!