5  Manipulando dados no R

5.1 Dataframes no R

DataFrames são objetos de dados genéricos em formato tabular, onde os dados são organizados de maneira lógica em linha-e-coluna semelhante ao de uma planilha do Excel. O dataframe é uma estrutura bidimensional. Os DataFrames podem ser formados com objetos criados previamente, desde que tenham o mesmo comprimento (1).

Uma das formas de criar um DataFrame no R é a partir de um conjunto de vetores como, por exemplo, este relacionados a 15 nascimentos em uma determinada maternidade:

id <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
pesoRN <- c (3340,3345,3750,3650,3220,4070,3380,3970,3060,3180,  
             2865,2815,3245,2051,2630)  
compRN <- c (50,48,52,48,50,51,50,51,47,47,47,49,51,50,44)
sexo <- c (2,2,2,1,1,1,2,1,1,1,2,2,1,1,2)
tipoParto <- c (1,1,2,1,2,2,1,2,1,1,1,2,1,1,1)
idadeMae <- c (40,19,26,19,32,24,27,20,21,19,23,36,21,23,23) 

Este grupo de vetores (variáveis) isolados fica difícil de manusear. Portanto, seria útil reuni-los em um só objeto. Pode-se fazer isso, usando a função data.frame(), do R base. Este DataFrame será atribuído a um novo objeto de nome dadosNeonatos.

dadosNeonatos <- data.frame (id,
                             pesoRN, 
                             compRN, 
                             sexo, 
                             tipoParto, 
                             idadeMae)

Verificando a classe deste novo objeto, tem-se:

class (dadosNeonatos)
[1] "data.frame"

Para observar a modificação realizada, pode-se usar a função str() do R base, digitando no R Script:

str(dadosNeonatos)
'data.frame':   15 obs. of  6 variables:
 $ id       : num  1 2 3 4 5 6 7 8 9 10 ...
 $ pesoRN   : num  3340 3345 3750 3650 3220 ...
 $ compRN   : num  50 48 52 48 50 51 50 51 47 47 ...
 $ sexo     : num  2 2 2 1 1 1 2 1 1 1 ...
 $ tipoParto: num  1 1 2 1 2 2 1 2 1 1 ...
 $ idadeMae : num  40 19 26 19 32 24 27 20 21 19 ...

Na saida da função, verifica-se que o dataframe contém 15 linhas e 6 colunas.

5.1.1 Acrescentando variáveis a um dataframe

Será adicionada ao dataframe uma nova variável chamada utiNeo, que indica se cada recém-nascido foi encaminhado ou não para a UTI neonatal logo após o nascimento. Essa variável será construída a partir de um vetor contendo a situação de cada um dos 15 recém-nascidos, e será incorporada como uma nova coluna no dataframe. A sintaxe utilizada para essa operação segue o padrão , resultando em: nome-do-dataframe$nome-da-variável.

dadosNeonatos$utiNeo <- c ("não","não","não","não","sim","não","sim","não","não","não","não","sim","não","não","não")

Com isso, ´utiNeopassa a fazer parte do conjunto de dados, permitindo análises específicas sobre a necessidade de cuidados intensivos neonatais. A funçãostr()`, pode ser usada, novamente, para observar a transformação:

str(dadosNeonatos)
'data.frame':   15 obs. of  7 variables:
 $ id       : num  1 2 3 4 5 6 7 8 9 10 ...
 $ pesoRN   : num  3340 3345 3750 3650 3220 ...
 $ compRN   : num  50 48 52 48 50 51 50 51 47 47 ...
 $ sexo     : num  2 2 2 1 1 1 2 1 1 1 ...
 $ tipoParto: num  1 1 2 1 2 2 1 2 1 1 ...
 $ idadeMae : num  40 19 26 19 32 24 27 20 21 19 ...
 $ utiNeo   : chr  "não" "não" "não" "não" ...

5.1.2 Transformação de variáveis

Observa-se que todas as variáveis estão como variáveis numéricas (num), exceto a variável ´utiNeoquestá como caractere (chr). Isto não está correto, pois as variáveissexo,tipoPartosão variáveis categóricas, bem como a a variávelutiNeo, adicionada posteriormente. Elas necessitam ser transformadas para fatores, usando a funçãofactor()`. Os principais argumentos dessa função são:

  • x \(\to\) vetor numérico
  • levels \(\to\) vetor opcional dos valores que x pode assumir
  • labels \(\to\) vetor de caracteres dos rótulos para os níveis, na mesma ordem
  • ordered \(\to\) vetor lógico (TRUE ou FALSE). Se TRUE, os níveis dos fatores são assumidos como ordenados

No exemplo, as variáveis não têm uma ordem lógica, então, o argumento ordered não é necessário.

dadosNeonatos$tipoParto <- factor(dadosNeonatos$tipoParto, 
                                  levels = c(1,2),
                                  labels = c("normal","cesareo"))
dadosNeonatos$sexo <- factor (dadosNeonatos$sexo, 
                               levels = c(1,2), 
                               labels = c("M","F")) 

A variável utiNeo já foi inserida como string (texto) e pertence a classe character, então, basta usar a as.factor() sem necessidade de alterar os rótulos (labels) nos níveis (levels)

dadosNeonatos$utiNeo <- as.factor (dadosNeonatos$utiNeo)

Após a transformação, executa-se, novamente, a função str() para ver como ficou a estrutura do dataframe:

str(dadosNeonatos)
'data.frame':   15 obs. of  7 variables:
 $ id       : num  1 2 3 4 5 6 7 8 9 10 ...
 $ pesoRN   : num  3340 3345 3750 3650 3220 ...
 $ compRN   : num  50 48 52 48 50 51 50 51 47 47 ...
 $ sexo     : Factor w/ 2 levels "M","F": 2 2 2 1 1 1 2 1 1 1 ...
 $ tipoParto: Factor w/ 2 levels "normal","cesareo": 1 1 2 1 2 2 1 2 1 1 ...
 $ idadeMae : num  40 19 26 19 32 24 27 20 21 19 ...
 $ utiNeo   : Factor w/ 2 levels "não","sim": 1 1 1 1 2 1 2 1 1 1 ...

Agora, as três varáveis passaram a ser fatores e as outras mantiveram-se numéricas.

5.1.3 Salvando um dataframe

O dataframe, criado e modificado anteriormente, pode ser salvo para uso posterior no diretório de trabalho.

A função save() realiza esta ação, usando como argumentos o dataframe a ser salvo e o nome do arquivo (file =) entre aspas. Por convenção, esta função salva com a extensão .RData que deve ser digitada, pois o R não a adiciona automaticamente.

save(dadosNeonatos, file = "dadosNeonatos.RData")

Este comando colocará o arquivo no diretório de trabalho em uso. Portanto, se o objetivo é salvar em outro local, deve ser informado qual o novo diretório.

Para carregar o objeto salvo anteriormente com o comando save(), usa-se a função load(). Se o arquivo a ser lido não estiver no diretório de trabalho da sessão, há necessidade de especificar o caminho até o arquivo:

load("dadosNeonatos.RData")

É possível salvar em outro tipo de extensão como Excel (.xlsx), Valores Separados por Vírgula (.csv), etc. O procedimento é o mesmo, mudando a função. Para salvar em uma extensão .xlsx,utiliza-se a função write_xlsx () do pacote writexl (2):

writexl::write_xlsx(dadosNeonatos, "dados/dadosNeonatos.xlsx")

Para salvar com a extensão .csv, usar a função write.csv() ou write.csv2() que faz parte do pacote utils, incluido no R base. A primeira função, usa "." para a separação dos decimais e "," para separar as variáveis; a segunda função usa "," para os decimais e ";" para separar as variáveis, convenção do Excel para algumas localidades, como o Brasil (3). Portanto, uma maneira de salvar o arquivo é:

write.csv2 (dadosNeonatos, "dados/dadosNeonatos.csv")

5.2 Importando dados de outros softwares

É possível inserir dados diretamente no R Script, como mostrado na Seção 5.1. Entretanto, se o conjunto de dados for muito extenso, torna-se complicado. Desta forma, é melhor construir o dataframe em outro software, como o Excel, SPSS, etc. e, após, quando necessário, importar os dados para o R.

5.2.1 Importando dados de um arquivo CSV

O formato CSV significa Comma Separated Values, ou seja, é um arquivo de valores separados por vírgula. Esse formato de armazenamento é simples e agrupa informações de arquivos de texto em planilhas. É possível gerar um arquivo .csv, a partir de uma planilha do Excel, usando o menu salvar como e escolher CSV.

As funções read.csv() e read.csv2(), incluídas no R base, podem ser utilizadas para importar arquivos CSV. Existe uma pequena diferença entre elas. Dois argumentos dessas funções têm padrão diferentes em cada uma. São eles: sep (separador de colunas) e dec (separador de decimais). Na read.csv(), o padrão é sep = ”,” e dec = ”.” e em read.csv2() o padrão é sep = “;” e dec = ”,”. Portanto, quando se importa um arquivo .csv, é importante saber qual a sua estrutura. Verificar se os decimais estão separados por ponto ou por vírgula e se as colunas (variáveis), por vírgula ou ponto e vírgula. Para ver isso, basta abrir o arquivo em um bloco de notas (por exemplo, Bloco de Notas do Windows, Notepad ++).

Quando se usa o read.csv() há necessidade de informar o separador e o decimal, pois senão ele usará o padrão inglês e o arquivo não será lido. Já com read.csv2(), que usa o padrão brasileiro, não há necessidade de informar qual o separador de colunas e nem o separador dos decimais.

Além disso, é necessário saber em que diretório do computador está o arquivo para informar ao comando. Recomenda-se colocar o arquivo na pasta do diretório de trabalho, pois assim basta apenas colocar o nome do arquivo na função de leitura dos dados. Caso contrário, tem-se que se usar todo o caminho (path).

Como exemplo, será importado o arquivo dadosNeonatos.csv que se encontra no diretório de trabalho do autor, salvo anteriormente. Para obter o arquivo, siga os passos da Seção 5.1 ou clique aqui e salve em seu diretório de trabalho.

A estrutura deste arquivo mostra que as colunas estão separadas por ponto-e-virgula e, portanto, a leitura dos dados será feita com a função read.csv2() e, como o arquivo está no diretório de trabalho, não há necessidade de informar o diretório completo. Os dados serão colocados em um objeto de nome neonatos 1:

neonatos <- read.csv2("dados/dadosNeonatos.csv")

Use a função str() para visualizar o conjunto de dados:2

str(neonatos)
'data.frame':   15 obs. of  8 variables:
 $ X        : int  1 2 3 4 5 6 7 8 9 10 ...
 $ id       : int  1 2 3 4 5 6 7 8 9 10 ...
 $ pesoRN   : int  3340 3345 3750 3650 3220 4070 3380 3970 3060 3180 ...
 $ compRN   : int  50 48 52 48 50 51 50 51 47 47 ...
 $ sexo     : chr  "F" "F" "F" "M" ...
 $ tipoParto: chr  "normal" "normal" "cesareo" "normal" ...
 $ idadeMae : int  40 19 26 19 32 24 27 20 21 19 ...
 $ utiNeo   : chr  "não" "não" "não" "não" ...

Como se observa na saída do comando, as variáveis foram importadas em classes que vão necessitar transformações para serem usadas. Isto deve ser feito como foi visto na Seção 5.1.2.

Atenção

Toda vez que se importa um dataset, deve-se verificar atentamente a sua estrutura antes de dar seguimento as análises

Recentemente, foi desenvolvido o pacote readr, incluído no conjunto de pacotes tidyverse (4), para lidar rapidamente com a leitura de grandes arquivos. O pacote fornece substituições para funções como read.csv(). As funções read_csv() e read_csv2() oferecidas pelo readr são análogas às do R base. Entretanto, são muito mais rápidas e fornecem mais recursos, como um método compacto para especificar tipos de coluna. Além disso, produzem tibbles (ver adiante, Seção 5.3) que são mais reproduzíveis, pois as funções básicas do R herdam alguns comportamentos do sistema operacional e das variáveis de ambiente, portanto, o código de importação que funciona no seu computador pode não funcionar no de outra pessoa. Para usar a função é necessário instalar e ativar o pacote readr. A função read_csv2() será utilizada para criar um outro objeto de nome recemNascidos, mas o conjunto de dados a ser ativado é o mesmo (dadosNeonatos):

 library(readr)
 recemNascidos <- read_csv2("dados/dadosNeonatos.csv")

Quando você executa read_csv2(), ele imprime uma especificação de coluna que fornece o nome e o tipo de cada coluna.

Novamente, a função str() mostrará a estrutura do arquivo, incluindo mais detalhes 3:

str(recemNascidos)
spc_tbl_ [15 × 8] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ ...1     : num [1:15] 1 2 3 4 5 6 7 8 9 10 ...
 $ id       : num [1:15] 1 2 3 4 5 6 7 8 9 10 ...
 $ pesoRN   : num [1:15] 3340 3345 3750 3650 3220 ...
 $ compRN   : num [1:15] 50 48 52 48 50 51 50 51 47 47 ...
 $ sexo     : chr [1:15] "F" "F" "F" "M" ...
 $ tipoParto: chr [1:15] "normal" "normal" "cesareo" "normal" ...
 $ idadeMae : num [1:15] 40 19 26 19 32 24 27 20 21 19 ...
 $ utiNeo   : chr [1:15] "não" "não" "não" "não" ...
 - attr(*, "spec")=
  .. cols(
  ..   ...1 = col_double(),
  ..   id = col_double(),
  ..   pesoRN = col_double(),
  ..   compRN = col_double(),
  ..   sexo = col_character(),
  ..   tipoParto = col_character(),
  ..   idadeMae = col_double(),
  ..   utiNeo = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

5.2.2 Importando um arquivo do Excel

O pacote readxl, pertencente ao conjunto de pacotes do tidyverse, facilita a obtenção de dados do Excel para o R, através da função read_excel(). esta função tem o argumento sheet = , que deve ser usado indicando o número ou o nome da planilha, colocado entre aspas. Este argumento é importante se houver mais de uma planilha, caso contrário, ele é opcional. Para saber os outros argumentos da função, colque o cursor dentro da função e aperte a tecla Tab (Figura 5.1). Isto abrirá um menu com os argumentos:

Figura 5.1: Argumentos da função para importar arquivos .xlsx

Será feita a leitura dos mesmos dados, usados na leitura de dados csv, apenas o arquivo agora está no formato .xlsx. Para obter o arquivo, siga os mesmos passos, usados anteriormente. Clique aqui e salve em seu diretório de trabalho.

Os dados serão atribuídos a um objeto com outro nome (recemNatos):

recemNatos <- readxl::read_excel("dados/dadosNeonatos.xlsx")
str(recemNatos)
tibble [15 × 7] (S3: tbl_df/tbl/data.frame)
 $ id       : num [1:15] 1 2 3 4 5 6 7 8 9 10 ...
 $ pesoRN   : num [1:15] 3340 3345 3750 3650 3220 ...
 $ compRN   : num [1:15] 50 48 52 48 50 51 50 51 47 47 ...
 $ sexo     : chr [1:15] "F" "F" "F" "M" ...
 $ tipoParto: chr [1:15] "normal" "normal" "cesareo" "normal" ...
 $ idadeMae : num [1:15] 40 19 26 19 32 24 27 20 21 19 ...
 $ utiNeo   : chr [1:15] "não" "não" "não" "não" ...

Como se vê ao analisar a estrutura, deve-se proceder transformações nas variáveis, como visto na Seção 5.1.2.

Na Figura 5.1, o duplo dois pontos (::) precedido do nome do pacote, no caso readxl, especifica a procedência da função usada. Nesta situação, não há necessidade de usar a função library() para carregar o pacote já instalado em um diretório (biblioteca) previamente.

5.2.3 Importando arquivos com o RStudio

O RStudio permite importar arquivos sem a necessidade de digitar comandos, que, para alguns podem ser tediosos.

Na tela inicial do RStudio, à direita, na parte superior, clique na aba Environment e em Import Dataset. Esta ação abre um menu que permite importar arquivos .csv, Excel, SPSS, etc.

Por exemplo, para importar o arquivo dadosNeonatos.xlsx, clicar em From Excel... Abre uma janela com uma caixa de diálogo. Clicar no botão Browse..., localizado em cima à direita, para buscar o arquivo dadosNeonatos.xlsx. Assim que o arquivo for aberto, ele mostra uma preview do arquivo e, em baixo, à direita mostra uma preview do código (Figura 5.2)), igual ao digitado anteriormente, que cria um objeto denominado dadosNeonatos, nome do objeto escolhido pelo R, mas pode ser modificado na janela, à esquerda, Import Option em Name, onde pode-se digitar qualquer nome. Após encerrar as escolhas, clicar em Import. É um caminho diferente para fazer o mesmo. Este é um dos fascínios do R!

Figura 5.2: Importando arquivos do excel com o RStudio

5.3 Tibble

A maneira mais comum de armazenar dados no R é usar data.frames ou tibble.

Tibble é um novo tipo de dataframe. É como se fosse um dataframe mais moderno. Ele mantém muitos recursos importantes do data frame original, mas remove muitos dos recursos desatualizados.

A maioria dos pacotes do R usa dataframes tradicionais, entretanto é possível transformá-los para tibble, usando a função as_tibble(), incluída no pacote tidyr (5). O único propósito deste pacote é simplificar o processo de criação dados arrumados organizados (tidy data). A transformação de um dataframe tradicional em um tibble, é um procedimento rescomendável, em função da maior flexibilidade destes.

Como exemplo deste procedimento, será usado o dataframes criado na Seção 5.1: dadosNeonatos.

Este é um conjunto de dados da classe data.frame, contendo 15 observações de 7 variáveis (colunas), pode convetrtido a um tibble, usando a função as.tibble():

library(tidyr)
as_tibble(dadosNeonatos)
# A tibble: 15 × 7
      id pesoRN compRN sexo  tipoParto idadeMae utiNeo
   <dbl>  <dbl>  <dbl> <fct> <fct>        <dbl> <fct> 
 1     1   3340     50 F     normal          40 não   
 2     2   3345     48 F     normal          19 não   
 3     3   3750     52 F     cesareo         26 não   
 4     4   3650     48 M     normal          19 não   
 5     5   3220     50 M     cesareo         32 sim   
 6     6   4070     51 M     cesareo         24 não   
 7     7   3380     50 F     normal          27 sim   
 8     8   3970     51 M     cesareo         20 não   
 9     9   3060     47 M     normal          21 não   
10    10   3180     47 M     normal          19 não   
11    11   2865     47 F     normal          23 não   
12    12   2815     49 F     cesareo         36 sim   
13    13   3245     51 M     normal          21 não   
14    14   2051     50 M     normal          23 não   
15    15   2630     44 F     normal          23 não   

Por padrão, quando o dataset é muito longo, apenas as primeiras dez linhas são mostradas. Aqui, aparece o toda a estrutura dos dados. São apresentadas a dimensão da tabela e as classes de cada coluna. Verifica-se que não houve grandes mudanças, apenas o conjunto de dados está estruturalmente mais organizado, mais flexível.

5.4 Pacote tidyverse

A denominada ciência de dados é difícil de definir, pois a definição depende da formação específica de cada cientista de dados. Entretanto, é possível mostrar como a ciência de dados pode ser realizada na prática, constituindo aquilo que se costuma chamar de Ciclo da Ciência de Dados (Figura 5.3).
Primeiramente, os dados brutos são coletados de diversas maneiras (veja Capítulo 3). Após, são armazenados, por exemplo, em Excel, e, em seguida, são arrumados para reduzir problemas de padronização, conceituais e erros ou exclusão de variáveis e casos que não fazem parte do objetivo estabelecido no projeto de pesquisa. Isto constituirá a base de dados analítica.
A base de dados analítica é então transformada, refinada, para produzir medidas resumidoras, tabela e gráficos. Quando necessário, são produzidos modelos estatíticos. O resultado final deve ser comunicado através dos meios de divulgação científica (relatórios, periódicos, livros, jornadas, congressos, GitHub, etc.).

Figura 5.3: Ciclo da Ciência de Dados

O pacote tidyverse é uma coleção de pacotes para a linguagem de programação R, pensada e desenvolvida para facilitar e otimizar o fluxo de trabalho em ciência de dados (4).
Em vez de ser um pacote único, ele é um “meta-pacote”, o que significa que, ao instalá-lo, você instala vários pacotes menores que trabalham em conjunto.

A filosofia principal por trás do tidyverse é a de dados “tidy” (arrumados ou organizados) (6), onde:

  • Cada variável está em uma coluna.

  • Cada observação está em uma linha.

  • Cada valor está em uma célula.

Seguindo essa lógica, as funções e pacotes do tidyverse são projetados para facilitar a manipulação dos dados dentro do Ciclo da Ciência de Dados (@fig-ciclo), tornando a manipulação, a análise e a visualização de dados mais consistentes e intuitivas.

5.4.1 Principais Pacotes do tidyverse

O tidyverse simplifica tarefas complexas, oferecendo ferramentas específicas para cada etapa do Ciclo de Ciências de Dados. Alguns dos pacotes mais importantes são:

  • dplyr: Para manipulação de dados. Contém funções essenciais para filtrar linhas, selecionar colunas, criar novas variáveis, e resumir dados.

  • ggplot2: Para visualização de dados. É um dos pacotes mais populares do R para criar gráficos esteticamente agradáveis e informativos.

  • tidyr: Para organizar os dados. Ele transforma dados “bagunçados” (que não seguem o formato tidy) em um formato mais limpo e organizado.

  • readr: Para importar dados. Permite ler arquivos de texto (como CSVs) de forma rápida e robusta.

  • tibble: Uma versão aprimorada do data.frame do R base. O tibble é mais fácil de usar e interage melhor com os pacotes do tidyverse.

  • stringr: Para manipular strings (textos). Simplifica as tarefas de trabalhar com dados de texto.

  • forcats: Para lidar com fatores (variáveis categóricas).

5.4.2 Princípios do tidyverse

O tidyverse causou quase uma revolução na comunidade do R. Aguns chegam a dizer que existe uma linguagem R antes e depois do tidyverse. Pode parecer exagero, mas o certo é que o uso dos princípios do tidyverse foi abraçado pela maioria dos usuários de R e, em função disso, foram criados uma grande quantidade de pacotes que conversam entre si, facilitando o manuseio dos dados.

Os princípios fundamentais são:

  1. Reutilizar estruturas de dados existentes.

  2. Organizar funções simples usando o pipe.4. Esse operador, introduzido por Stefan Milton Bache no pacote magrittr (7), permite encadear múltiplas operações em uma sequência clara e legível, de forma que a saída de uma função se torna a entrada da próxima. Isso torna o código mais fácil de ler e entender, eliminando a necessidade de criar muitas variáveis intermediárias. O pipe pode ser acionado digitando %>% ou usando o atalho ctrl + shift + M. 5

  3. Usar uma sintaxe consistente: As funções dos pacotes tidyverse seguem uma lógica de nomeação e de argumentos parecida, facilitando a memorização e o uso.

  4. Projetado com foco nos seres humanos, priorizando a eficiência do programador.

Quando o tidyverse é carregado, todos os pacotes embutidos nele, serão carregados.

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ purrr     1.1.0
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.2     ✔ tibble    3.3.0
✔ lubridate 1.9.4     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Conflito de funções ao carregar tidyverse

Ao carregar o pacote tidyverse ou qualquer outro, podem surgir mensagens de conflito indicando que funções previamente disponíveis foram sobrescritas por versões de mesmo nome.

No exemplo apresentado, as funções filter() e lag() do pacote stats foram substituídas pelas versões do pacote dplyr.

Para utilizar as funções originais do pacote stats após esse carregamento, é necessário especificar o namespace diretamente:
stats::filter() e stats::lag().

5.5 Pacote dplyr

Um dos pacotes de maior utilidade abarcado pelo tidyverse é o dplyr. Ele permite realizar transformação dos dados de uma forma simples e eficiente. O uso dos verbos dplyr, aliado ao operador pipe, tendem a tornar os scripts mais “enxutos” e elegantes (8).
As principais funções do dplyr são:

  • select() - seleciona colunas
  • arrange() - ordena uma variável em ordem crescente ou descrescente
  • filter() - filtra linhas
  • mutate() - cria/modifica colunas
  • group_by() - agrupa por fatores
  • summarise() - sumariza a base

Todas as funções tem as mesmas características: o primeiro argumento é um tibble e o que será a ação da função nos outrso argumentos.

Neste capítulo e em muitos outros deste livro, será outilizado o dataframe dadosMater.xlsx.

5.6 Dataframe dadosMater.xlsx

O arquivo dadosMater.xlsx é um dataframe constituído por dados de 1568 partos consecutivos do Hospital Geral de Caxias do Sul (HGCS) 6 , durante um estudo sobre infecções congênitas (9). Para baixar esses dados, clique aqui e faça o download para o diretório de trabalho, para uso posterior.

5.6.1 Leitura dos dados

Para ler arquivos do Excel (.xlsx), o pacote ideal é o readxl, que também faz parte do tidyverse. Ele é leve, rápido e não depende do Excel instalado. A função a ser usada é read_excel(). O objeto mater será utilizado para receber os dados:

mater <- readxl::read_excel("dados/dadosMater.xlsx")
Importante

O comando para carregar o conjunto de dados somente funciona ,sem colocar o caminho completo, se tudo está sendo realizado no diretório de trabalho

Como rotina, em análise de dados, após a leitura é interessante explorar a estrutura do dados. A função as_tibble() é interessante para ver a estrutura de um tibble:

as_tibble(mater)
# A tibble: 1,368 × 30
      id idadeMae altura  peso ganhoPeso anosEst   cor eCivil renda  fumo
   <dbl>    <dbl>  <dbl> <dbl>     <dbl>   <dbl> <dbl>  <dbl> <dbl> <dbl>
 1     1       42   1.65  69.9       3.9       3     2      1  1.45     2
 2     2       29   1.66  78        16.5      11     1      2  2.41     2
 3     3       19   1.72  81         5         9     2      1  1.93     2
 4     4       31   1.55  74        43         5     2      2  1.45     2
 5     5       34   1.6   60        15         7     2      2  0.48     2
 6     6       29   1.5   60        11.4       8     2      2  0.96     1
 7     7       30   1.54  75.5      10.5       4     1      2  1.2      1
 8     8       34   1.63  61         9         6     1      2  2.41     2
 9     9       17   1.68  57        15        10     1      2  2.17     2
10    10       32   1.5   70        11.4       1     2      2  0.72     2
# ℹ 1,358 more rows
# ℹ 20 more variables: quantFumo <dbl>, prenatal <dbl>, para <dbl>,
#   droga <dbl>, ig <dbl>, tipoParto <dbl>, pesoPla <dbl>, sexo <dbl>,
#   pesoRN <dbl>, compRN <dbl>, pcRN <dbl>, apgar1 <dbl>, apgar5 <dbl>,
#   utiNeo <dbl>, obito <dbl>, hiv <dbl>, sifilis <dbl>, rubeola <dbl>,
#   toxo <dbl>, infCong <dbl>

Por padrão, a função retorna as dez primeiras linhas. Além disso, colunas que não couberem na largura da tela serão omitidas. Também são apresentadas a dimensão da tabela e as classes de cada coluna. Observa-se que ele tem 1368 linhas (observações) e 30 colunas (variáveis). Além disso, verifica-se que todas as variáveis estão como numéricas (dbl) e, certamente, algumas, dependendo do objetivo na análise, precisarão ser transformadas.

O significado de cada uma das variáveis do tibble mater é o seguinte:

  • id \(\to\) identificação do participante
  • idadeMae \(\to\) idade da parturiente em anos
  • altura \(\to\) altura da parturiente em metros
  • peso \(\to\) peso da parturiente em kg
  • ganhoPeso \(\to\) aumento de peso durante a gestação
  • anosEst \(\to\) anos de estudo completos
  • cor \(\to\) cor declarada pela parturiente: 1 = branca; 2 = não branca
  • eCivil \(\to\) estado civil: 1 = solteira; 2 = casada ou companheira
  • renda \(\to\) renda familiar em salários minimos
  • fumo \(\to\) tabagismo: 1 = sim; 2 = não
  • quantFumo \(\to\) quantidade de cigarros fumados diariamente
  • prenatal \(\to\) realizou pelo menos 6 consultas no pré-natal? 1 = sim; 2 = não
  • para \(\to\) número de filhos paridos
  • droga \(\to\) drogadição? 1 = sim; 2 = não
  • ig \(\to\) idade gestacional em semanas
  • tipoParto \(\to\) tipo de parto: 1 = normal; 2 = cesareana
  • pesoPla \(\to\) peso da placenta em gramas
  • sexo \(\to\) sexo do recém-nascido (RN): 1 = masc; 2 = fem
  • pesoRN \(\to\) peso do RN em gramas
  • compRN \(\to\) comprimento do RN em cm
  • pcRN \(\to\) perímetro cefálico dorecém-nascido em cm
  • apgar1 \(\to\) escore de Apgar no primeiro minuto
  • apgar5 \(\to\) escore de Apgar no quinto minuto
  • utiNeo \(\to\) RN necessitou de terapia intesiva? 1 = sim; 2 = não
  • obito \(\to\) obito no período neonatal? 1 = sim; 2 = não
  • hiv \(\to\) parturiente portadora de HIV? 1 = sim; 2 = não
  • sifilis \(\to\) parturiente portadora de sífilis? 1 = sim; 2 = não
  • rubeola \(\to\) parturiente portadora de rubéola? 1 = sim; 2 = não
  • toxo \(\longrightarrow\) parturiente portadora de toxoplasmose? 1 = sim; 2 = não
  • infCong \(\to\) parturiente portadora de alguma infecção congênita? 1 = sim; 2 = não

O tibble mater pode ser facilmente modificado com os verbos do pacote dplyr.

5.6.2 Selecionando colunas

A função select () pode ser usada para escolher quais colunas (variáveis) entrarão na análise. Ela recebe como primeiro argumento o conjunto de dados e os demais argumentos são os nomes das colunas. O nome das colunas devem estar entre aspas.
O conjunto de dados mater contém 30 colunas e muitas podem ser removidas, dependendo do objetivo da análise.

mater <- dplyr::select(mater, - obito, -hiv, -sifilis, -rubeola, -toxo)

Note que foi usado o sinal de menos (-) antes das variáveis, porque elas foram removidas. Também poderiam ser listadas as variáveia que permanecem que, automaticamente, as não listadas serão removidas.

Outra maneira, pode ser colocando o número da coluna como abaixo, o sinal de subtração antes da função concatenar c()com os números das colunas a serem removidas (25 a 29):

mater <- dplyr::select(mater, - c(25:29))

A função str() permite visualizar a nova estrutura:

str(mater)
tibble [1,368 × 25] (S3: tbl_df/tbl/data.frame)
 $ id       : num [1:1368] 1 2 3 4 5 6 7 8 9 10 ...
 $ idadeMae : num [1:1368] 42 29 19 31 34 29 30 34 17 32 ...
 $ altura   : num [1:1368] 1.65 1.66 1.72 1.55 1.6 1.5 1.54 1.63 1.68 1.5 ...
 $ peso     : num [1:1368] 69.9 78 81 74 60 60 75.5 61 57 70 ...
 $ ganhoPeso: num [1:1368] 3.9 16.5 5 43 15 11.4 10.5 9 15 11.4 ...
 $ anosEst  : num [1:1368] 3 11 9 5 7 8 4 6 10 1 ...
 $ cor      : num [1:1368] 2 1 2 2 2 2 1 1 1 2 ...
 $ eCivil   : num [1:1368] 1 2 1 2 2 2 2 2 2 2 ...
 $ renda    : num [1:1368] 1.45 2.41 1.93 1.45 0.48 0.96 1.2 2.41 2.17 0.72 ...
 $ fumo     : num [1:1368] 2 2 2 2 2 1 1 2 2 2 ...
 $ quantFumo: num [1:1368] 0 0 0 0 0 10 20 0 0 0 ...
 $ prenatal : num [1:1368] 2 1 2 2 2 1 1 2 2 1 ...
 $ para     : num [1:1368] 5 0 0 1 2 1 2 1 0 4 ...
 $ droga    : num [1:1368] 2 2 2 2 2 2 2 2 2 2 ...
 $ ig       : num [1:1368] 29 33 33 33 33 33 33 33 34 34 ...
 $ tipoParto: num [1:1368] 2 2 1 1 2 1 2 1 1 2 ...
 $ pesoPla  : num [1:1368] 224 1118 452 432 574 ...
 $ sexo     : num [1:1368] 2 2 2 2 2 2 2 2 2 2 ...
 $ pesoRN   : num [1:1368] 1035 2300 1580 1840 2475 ...
 $ compRN   : num [1:1368] 35.5 45 39 41 47 41 44 44 47 48 ...
 $ pcRN     : num [1:1368] 28 32 28 32 32 29 32 32 30 27 ...
 $ apgar1   : num [1:1368] NA NA NA NA NA NA NA NA NA NA ...
 $ apgar5   : num [1:1368] NA NA NA NA NA NA NA NA NA NA ...
 $ utiNeo   : num [1:1368] 1 2 1 1 1 1 2 2 1 1 ...
 $ infCong  : num [1:1368] 2 2 2 2 1 2 2 2 2 2 ...

A função select () pode ser combinada com outras funções, como filter ().

5.6.3 Modificando e criando novas colunas

Para esta ação, usa-se a função mutate(). Por exemplo, todas as variáveis no tibble mater foram lidas como numéricas. Entretanto, as variáveis cor, estCivil, fumo, prenatal, droga, tipoParto, sexo, utiNeo e infCong são categóricas e devem ser convertidas para fator, usando a função factor() associada a mutate():

mater <- dplyr::mutate(mater,
                        cor = factor(cor, 
                                     levels = c(1,2), 
                                     labels = c("branca", "não branca")), 
                        eCivil = factor(eCivil, 
                                          levels = c(1,2), 
                                          labels = c("solteira", "não branca")),
                        fumo = factor(fumo, 
                                      levels = c(1,2), 
                                      labels = c("sim", "não")), , 
                        prenatal = factor(prenatal, 
                                          levels = c(1,2), 
                                          labels = c("sim", "não")), 
                        droga = factor(droga, 
                                       levels = c(1,2), 
                                       labels = c("sim", "não")), 
                        tipoParto = factor(tipoParto, 
                                           levels = c(1,2), 
                                           labels = c("normal", "cesareo")), 
                        sexo = factor(sexo, 
                                      levels = c(1,2), 
                                      labels = c("masc", "fem")), 
                        utiNeo = factor(utiNeo, 
                                        levels = c(1,2), 
                                        labels = c("sim", "não")),
                        infCong = factor(infCong, 
                                         levels = c(1,2), 
                                         labels = c("sim", "não")))

O conjunto de dados está, agora, estruturado de forma correta.

str(mater)
tibble [1,368 × 25] (S3: tbl_df/tbl/data.frame)
 $ id       : num [1:1368] 1 2 3 4 5 6 7 8 9 10 ...
 $ idadeMae : num [1:1368] 42 29 19 31 34 29 30 34 17 32 ...
 $ altura   : num [1:1368] 1.65 1.66 1.72 1.55 1.6 1.5 1.54 1.63 1.68 1.5 ...
 $ peso     : num [1:1368] 69.9 78 81 74 60 60 75.5 61 57 70 ...
 $ ganhoPeso: num [1:1368] 3.9 16.5 5 43 15 11.4 10.5 9 15 11.4 ...
 $ anosEst  : num [1:1368] 3 11 9 5 7 8 4 6 10 1 ...
 $ cor      : Factor w/ 2 levels "branca","não branca": 2 1 2 2 2 2 1 1 1 2 ...
 $ eCivil   : Factor w/ 2 levels "solteira","não branca": 1 2 1 2 2 2 2 2 2 2 ...
 $ renda    : num [1:1368] 1.45 2.41 1.93 1.45 0.48 0.96 1.2 2.41 2.17 0.72 ...
 $ fumo     : Factor w/ 2 levels "sim","não": 2 2 2 2 2 1 1 2 2 2 ...
 $ quantFumo: num [1:1368] 0 0 0 0 0 10 20 0 0 0 ...
 $ prenatal : Factor w/ 2 levels "sim","não": 2 1 2 2 2 1 1 2 2 1 ...
 $ para     : num [1:1368] 5 0 0 1 2 1 2 1 0 4 ...
 $ droga    : Factor w/ 2 levels "sim","não": 2 2 2 2 2 2 2 2 2 2 ...
 $ ig       : num [1:1368] 29 33 33 33 33 33 33 33 34 34 ...
 $ tipoParto: Factor w/ 2 levels "normal","cesareo": 2 2 1 1 2 1 2 1 1 2 ...
 $ pesoPla  : num [1:1368] 224 1118 452 432 574 ...
 $ sexo     : Factor w/ 2 levels "masc","fem": 2 2 2 2 2 2 2 2 2 2 ...
 $ pesoRN   : num [1:1368] 1035 2300 1580 1840 2475 ...
 $ compRN   : num [1:1368] 35.5 45 39 41 47 41 44 44 47 48 ...
 $ pcRN     : num [1:1368] 28 32 28 32 32 29 32 32 30 27 ...
 $ apgar1   : num [1:1368] NA NA NA NA NA NA NA NA NA NA ...
 $ apgar5   : num [1:1368] NA NA NA NA NA NA NA NA NA NA ...
 $ utiNeo   : Factor w/ 2 levels "sim","não": 1 2 1 1 1 1 2 2 1 1 ...
 $ infCong  : Factor w/ 2 levels "sim","não": 2 2 2 2 1 2 2 2 2 2 ...

O Índice de Massa Corporal (IMC) é um cálculo que relaciona o peso e a altura de uma pessoa para avaliar se ela está com o peso ideal, abaixo do peso, acima do peso ou obesa. É uma ferramenta simples e amplamente utilizada na área da saúde para triagem e acompanhamento do estado nutricional. Para obter esse índice, serão utilizadas as variáveis peso e altura da gestante no início da gravidez. Como visto na Seção 4.4, o cálculo do IMC é dado pela razão entre o peso em kg e a altura em metros elevada ao quadrado. Para criar uma nova coluna com a variável imc, pode-se também usar o mutate().

mater <- mutate(mater,
                imc = peso/altura^2)

5.6.4 Filtrando linhas

A função filter() é usada para criar um subconjunto de dados que obedeçam determinadas condições lógicas: & (e), | (ou) e ! (não). Por exemplo:

  • y & !x \(\to\) seleciona y e não x
  • x & !y \(\to\) seleciona x e não y
  • x | !x \(\to\) seleciona x ou y
  • x & y \(\to\) seleciona x e y

Um recém-nascido é dito a termo quando a duração da gestação é igual a 37 a 42 semanas incompletas. Para extrair do banco de dados mater os recém-nascidos a termo (dadosRNT), pode-se usar a função filter():

dadosRNT <- dplyr::filter (mater, ig>=37 & ig<42)

Observe que, agora, o conjunto de dados dadosRNT tem 1085 linhas, número de recém-nascidos a termo do banco de dados original mater (1368). Logo, os recém nascidos a termo correspondem a 79.3% dos nascimentos, nesta maternidade.

Outro exemplo

Para selecionar apenas os meninos, nascidos a termo (dadosRNT), codificados como "masc", procede-se da seguinte maneira:

dadosRNT_masc <- filter (dadosRNT, sexo == 'masc')
Alerta

Não esquecer que o sinal de igualdade, no R, é representado por um == (duplo igual)

5.6.5 Sumarizando uma coluna

Para resumir uma coluna, utilizando uma métrica de interesse, como média, mediana, desvio padrão, etc. (Capítulo 6), pode-se usar a função summarize().

resumo <- dplyr::summarize(dadosRNT,
  n = length (id),
  media = mean(pesoRN, na.rm = TRUE),
  desvpad = sd(pesoRN, na.rm = TRUE)
)
resumo
# A tibble: 1 × 3
      n media desvpad
  <int> <dbl>   <dbl>
1  1085 3216.    462.

Muitas vezes, há necessidade de sumarizar uma coluna agrupada pelas categorias de uma segunda coluna. Por exemplo, peso dos recém-nascidos a termo por sexo. Para isso, além do summarize(), utilizamos também a função group_by().
Para facilitar o trabalho, será usado o operador pipe que pode ser acionado digitando %>% ou usando o atalho ctrl + shift + M7, como observado na Seção 5.4.2. Em vez de passar o argumento para a função separadamente, é possível escrever o valor ou objeto e, em seguida, usar o pipe para convertê-lo como o argumento da função na mesma linha. Funciona como se o pipe jogasse o objeto dentro da função seguinte.

library(dplyr)
resumo <- dadosRNT %>% 
        group_by(sexo) %>% 
        summarize(
  n = length (id),
  media = mean(pesoRN, na.rm = TRUE),
  desvpad = sd(pesoRN, na.rm = TRUE)
)
resumo
# A tibble: 2 × 4
  sexo      n media desvpad
  <fct> <int> <dbl>   <dbl>
1 masc    592 3274.    458.
2 fem     493 3147.    458.

5.6.6 Selecionando linhas específicas

A função slice() do pacote dplyr é usada para selecionar linhas específicas de um dataframe (ou tibble) com base em suas posições. Ela é bastante útil quando se quer extrair subconjuntos de dados sem usar condições lógicas, mas sim índices de linha.

Diferente de filter(), que seleciona linhas baseado em condições, slice() usa números de linhas. Por exemplo, para visualizar as cinco primeiras linhas do conjunto de dados dadosRNT, usa-se:

slice(dadosRNT, 1:5)
# A tibble: 5 × 26
     id idadeMae altura  peso ganhoPeso anosEst cor        eCivil    renda fumo 
  <dbl>    <dbl>  <dbl> <dbl>     <dbl>   <dbl> <fct>      <fct>     <dbl> <fct>
1    20       28   1.5   48.5      11         6 não branca não bran…  3.13 não  
2    21       31   1.55  65        24         5 branca     não bran…  0.72 não  
3    22       27   1.6   60        15         8 não branca não bran…  2.41 sim  
4    23       28   1.58  47         9         8 branca     não bran…  1.69 não  
5    24       18   1.76  65.5       6.5       7 branca     solteira   1.93 sim  
# ℹ 16 more variables: quantFumo <dbl>, prenatal <fct>, para <dbl>,
#   droga <fct>, ig <dbl>, tipoParto <fct>, pesoPla <dbl>, sexo <fct>,
#   pesoRN <dbl>, compRN <dbl>, pcRN <dbl>, apgar1 <dbl>, apgar5 <dbl>,
#   utiNeo <fct>, infCong <fct>, imc <dbl>

A função slice() é compatível com agrupamentos, por exemplo, para selecionar os cinco primeiros casos do tibble dadosRNT por sexo:

dadosRNT %>%
        group_by(sexo) %>% 
        slice(1:5)
# A tibble: 10 × 26
# Groups:   sexo [2]
      id idadeMae altura  peso ganhoPeso anosEst cor        eCivil   renda fumo 
   <dbl>    <dbl>  <dbl> <dbl>     <dbl>   <dbl> <fct>      <fct>    <dbl> <fct>
 1    20       28   1.5   48.5      11         6 não branca não bra…  3.13 não  
 2    21       31   1.55  65        24         5 branca     não bra…  0.72 não  
 3    22       27   1.6   60        15         8 não branca não bra…  2.41 sim  
 4    23       28   1.58  47         9         8 branca     não bra…  1.69 não  
 5    24       18   1.76  65.5       6.5       7 branca     solteira  1.93 sim  
 6   751       17   1.65  60        11.4       7 não branca solteira  1.92 não  
 7   752       30   1.6   54        12         5 branca     não bra…  1.92 não  
 8   753       27   1.53  43.5      20.5      11 branca     não bra…  1.93 não  
 9   755       28   1.4   60        11.4       8 não branca não bra…  2.17 não  
10   756       17   1.55  78        20        10 branca     solteira  4.82 sim  
# ℹ 16 more variables: quantFumo <dbl>, prenatal <fct>, para <dbl>,
#   droga <fct>, ig <dbl>, tipoParto <fct>, pesoPla <dbl>, sexo <fct>,
#   pesoRN <dbl>, compRN <dbl>, pcRN <dbl>, apgar1 <dbl>, apgar5 <dbl>,
#   utiNeo <fct>, infCong <fct>, imc <dbl>

O tidyverse introduziu funções auxiliares como:

  • slice_head(): que seleciona as primeiras n linhas. A saída dessa função é a mesma anterior, se for solicitado n = 5:
# A tibble: 5 × 26
     id idadeMae altura  peso ganhoPeso anosEst cor        eCivil    renda fumo 
  <dbl>    <dbl>  <dbl> <dbl>     <dbl>   <dbl> <fct>      <fct>     <dbl> <fct>
1    20       28   1.5   48.5      11         6 não branca não bran…  3.13 não  
2    21       31   1.55  65        24         5 branca     não bran…  0.72 não  
3    22       27   1.6   60        15         8 não branca não bran…  2.41 sim  
4    23       28   1.58  47         9         8 branca     não bran…  1.69 não  
5    24       18   1.76  65.5       6.5       7 branca     solteira   1.93 sim  
# ℹ 16 more variables: quantFumo <dbl>, prenatal <fct>, para <dbl>,
#   droga <fct>, ig <dbl>, tipoParto <fct>, pesoPla <dbl>, sexo <fct>,
#   pesoRN <dbl>, compRN <dbl>, pcRN <dbl>, apgar1 <dbl>, apgar5 <dbl>,
#   utiNeo <fct>, infCong <fct>, imc <dbl>
  • slice_tall(): que seleciona as últimas n linhas.
  • slice_sample(): seleciona linhas aleatórias. Uma amostra de n = 200 será extraída do tibble dadosRNT, como exemplo:
dadosRNT200 <- dadosRNT %>% slice_sample(n = 200)
  • slice_min(): selecioan as linhas com os menores valores em uma coluna específica. Não ordena todo o dataframe, mas sim identifica e extrai as linhas que têm os menores valores na coluna indicada com order_by. Por exemplo, se o objetivo é extrarir do tibble dadosRNT so cinco menores pesos ao nascer por sexo:
dadosRNT %>% 
  select(pesoRN, sexo) %>% 
  slice_min(order_by = pesoRN, 
            n = 5, 
            with_ties = TRUE, 
            by = sexo)
# A tibble: 10 × 2
   pesoRN sexo 
    <dbl> <fct>
 1   1425 masc 
 2   1440 masc 
 3   1795 masc 
 4   1810 masc 
 5   1980 masc 
 6   1715 fem  
 7   1785 fem  
 8   1895 fem  
 9   2090 fem  
10   2095 fem  
  • slice_max(): funcion a da mesma que o slice_min(), apenas para os maiores valores.
Exercício

Verificar a média e o desvio padrão dos pesos dos recém-nascidos a termo de mães fumantes e não fumantes, por sexo.

5.6.7 Ordenando uma coluna

Para ordenar os dados de uma coluna, pode-se usar a função arrange() do dplyr. O primeiro argumento é o conjunto de base. Os demais argumentos são as colunas a serem ordenadas.
Por padrão, a função ´ coloca os dados em ordem crescente, mas é possível alterar e organizar em ordem decrescente usando a função desc(), que recebe o nome da coluna como argumento e ordena os valores em ordem decrescente.

Por exemplo, a renda familiar das parturientes será ordenada de forma ascendente. Em primeiro lugar, apenas como exercício, a renda familiar em salários mínimos será convertida em reais, tomando como base o valor de 2025 de 1518 reais. Após, a variável renda será colocada em ordem crescente com a função arrange(). A seguir, usando as funções slice_head() e slice_tail(), se verificará as 5 menores e as 5 maiores rendas que serão atribuídos a dois objetos (menores e maiores). Estes vão ser exibidos juntos, usando a função bind_rows(), também do dplyr:

# Cinco menores salários em ordem crescente
menores <- mater %>% select(renda) %>% 
    mutate(renda = renda *1518.00) %>% 
    arrange(renda) %>% 
    slice_head(n=5)
maiores <- mater %>% select(renda) %>% 
    mutate(renda = renda *1518.00) %>% 
    arrange(renda) %>% 
    slice_tail(n=5)

# Exibição
bind_rows(menores, maiores)
# A tibble: 10 × 1
    renda
    <dbl>
 1   288.
 2   364.
 3   622.
 4   653.
 5   729.
 6 14634.
 7 14634.
 8 14634.
 9 16227.
10 16455.

5.6.8 Função count()

Permite contar rapidamente os valores únicos de uma ou mais variáveis. Esta função tem os seguintes argumentos.

  • x \(\to\) dataframe
  • wt \(\to\) pode ser NULL (padrão) ou uma variável
  • sort \(\to\) padrão = FALSE; se TRUE, mostrará os maiores grupos no topo
  • name \(\to\) O nome da nova coluna na saída; padrão = NULL

Quando o argumento name é omitido, a função retorna n como nome padrão.

Usando o dataframe mater, a função count() irá contar o número de parturientes fumantes, variável dicotômica fumo:

count(mater, fumo)
# A tibble: 2 × 2
  fumo      n
  <fct> <int>
1 sim     301
2 não    1067
Exercício

Calcule o percentual de partos cesáreos no tibble mater.

5.7 Pacote forcats()

O pacote forcats() é uma das maravilhas do tidyverse voltada exclusivamente para o tratamento de variáveis categóricas no R — ou seja, os fatores. O nome vem de “for categorical variables”, e ele foi criado para resolver os desafios que surgem ao lidar com fatores, especialmente em visualizações e modelagens (10).

A finalidade do pacote forcats():

Oferece funções intuitivas e poderosas para:

  • Reordenar os níveis de um fator;

  • Modificar, combinar e recodificar níveis;

  • Lidar com níveis raros ou ausentes;

  • Preparar fatores para gráficos com ggplot2 (Seção 8.3)
    As principais funções doforcats() são:

  • fct_reorder() - Reordena os níveis com base em outra variável (ex: média);

  • fct_infrequent() - Reordena os níveis pela frequência (mais comum primeiro);

  • fct_rev() - Inverte a ordem dos níveis;

  • fct_lump() - Agrupa níveis menos frequentes em “outros”:

  • fct_recode() - Renomeia níveis manualmente;

  • fct_drop() - Remove níveis não utilizados;

  • fct_expand() - Adiciona novos níveis.

Como exemplo, será modificada a ordem de como a variável sexo será apresentada. Para ver a ordem dos níveis, pode-se usar:

levels(mater$sexo)
[1] "masc" "fem" 

Ou seja, o sexo masculino está colocado antes do feminino. Como é uma variável dicotômica, basta inverter a ordem, usando a função fct_rev():

mater$sexo <- fct_rev(mater$sexo)

levels(mater$sexo)
[1] "fem"  "masc"

5.8 Manipulação de datas

Originalmente, todos os que trabalham com o R queixavam-se de como era frustrante trabalhar com datas. Era um processo que causava grande perda de tempo nas análises. O pacote lubridate (11) foi criado para simplificar ao máximo a leitura de datas e extração de informações das mesmas.

library(lubridate)

Quando o lubridate é carregado aparece uma mensagem, avisando que alguns nomes de funções também estão contidas no pacote base do R.
Para evitar confusões e verificar que as funções corretas estão sendo usadas, usa-se o duplo dois pontos (::) antes do nome da função, precedido do nome do pacote, por exemplo: lubridate::date().

Para obter a data atual ou a data-hora, você pode usar as funções today() ou now():

today()
[1] "2025-10-20"
now()
[1] "2025-10-20 21:34:36 -03"

5.8.1 Convertendo strings ou caractere para data

Para converter string ou caracteres em datas, basta executar funções específicas adequadas aos dados. Elas determinam automaticamente o formato quando você especifica a ordem do componente. Para usá-los, identifique a ordem em que o ano, o mês e o dia aparecem em suas datas e, em seguida, organize “y”, “m” e “d” na mesma ordem. Isso lhe dá o nome da função do lubridate que analisará a data. Por exemplo, suponhamos a data de 25/12/2022:

natal <- "25/12/2022"
natal
[1] "25/12/2022"

Aparentemente, o R aceitou a informação como uma data. Entretanto, se for verificada a classe do objeto, tem-se:

class(natal)
[1] "character"

Estando como caractere, esta data não poderá ser usada em operações com datas, pois necessitaria estar como uma classe date. Para converte-la em data, usa-se a função dmy():

natal <- dmy(natal)
natal
[1] "2022-12-25"
class(natal)
[1] "Date"

Dessa forma, a data, agora está sendo reconhecida pelo R como date. É sempre importante verificar a classe da data.

Às vezes, as datas escritas estão com o mês abreviado, como 25/dez/2022. O procedimento é o mesmo

minha.data <- "25/dez/2022"
class (minha.data)
[1] "character"
minha.data <- dmy(minha.data)
class (minha.data)
[1] "Date"

Se além da data, houver necessidade de especificar o horário, basta usar dmy_h(), dmy_hm() e dmy_hms(). No padrão americano, pode ser usado ymd().

O lubridate traz diversas funções para extrair os componentes de um objeto da classe date.

  • second() \(\to\) extrai os segundos.
  • minute() \(\to\) extrai os minutos.
  • hour() \(\to\) extrai a hora.
  • wday() \(\to\) extrai o dia da semana.
  • mday() \(\to\) extrai o dia do mês.
  • month() \(\to\) extrai o mês.
  • year() \(\to\) extrai o ano.

Por exemplo, usando a data de nascimento (dn) de um dos netos do autor:

dn <- dmy("06/06/2018")
year(dn)
[1] 2018

Para acrescentar um horário ao objeto data de nascimento (dn)^[UTC = Coordinated Universal Time}:

hour(dn) <- 18
dn
[1] "2018-06-06 18:00:00 UTC"

5.8.2 Juntando componentes de datas

Para juntar componentes de datas e horas, pode-se utilizar as funções make_date() e make_datetime(). Em muitos arquivos, os componentes da data estão em colunas diferentes e há necessidade de juntá-los em uma única coluna para compor a data:

felix <- make_date(year = 2018, month = 06, day = 06)
felix
[1] "2018-06-06"

Para juntar ano, mês, dia, hora e minuto:

minha.data <- make_datetime(year = 2018, 
                            month = 06, 
                            day = 06, 
                            hour = 18 ,
                            min = 00, 
                            sec = 15)
minha.data
[1] "2018-06-06 18:00:15 UTC"

5.8.3 Extraindo componentes de datas

Quando temos objetos do tipo POSIXt8 podemos extrair componentes ou elementos deles. Para isso são usadas algumas funções específicas do pacote lubridate como mostrado a seguir.

data <- now()

year(data)            # Extrai o ano
[1] 2025
month(data)           # Extrai o mês
[1] 10
week(data)            # Extrai a semana
[1] 42
day(data)             # Extrai o dia
[1] 20
minute(data)          # Extrai o minuto
[1] 34
second(data)          # Extrai o segundo
[1] 36.8432

Para verificar o número de dias tem em um determinado mês, usa-se a função days_in_month():

 data1 <- dmy("25/02/2000")
 days_in_month(data1)          
Feb 
 29 

5.8.4 Operações com datas

O pacote lubridate possui funções de duração e de período para manipular as datas. As funções de duração calculam o número de segundos em um determinado num determinado número de dias. As funções de duração não levam em consideração anos bissextos e horário de verão, enquanto as funções de período consideram esses fatores.

ddays (1)           # Número de segundos em 1 dia
[1] "86400s (~1 days)"
dhours (1)          # Número de segundos em 1 hora
[1] "3600s (~1 hours)"
dminutes (1)        # Número de segundos em 1 minuto
[1] "60s (~1 minutes)"
days (5)            # Cria um período de 5 dias
[1] "5d 0H 0M 0S"
weeks (5)           # Cria um período de 5 semanas
[1] "35d 0H 0M 0S"

Suponha-se que haja necessidade de saber em qual dia cairá após acrescentarmos 5 semanas à data1 (25/02/2000), criada acima:

data1 + weeks (5)           
[1] "2000-03-31"

Adicionando 1 ano à data1 (25/02/2000) com uma função de duração, tem-se:

data1 + dyears (1)           
[1] "2001-02-24 06:00:00 UTC"

Se for adicionado um ano à mesma data, mas agora com uma função de período, tem-se:

data1 + years (1)           
[1] "2001-02-25"

Um intervalo de tempo pode ser obtido a partir de uma data inicial e uma data final. Suponha que uma gestante tenha como data da sua última menstruação 04/10/2022 e o bebê tenha nascido em 30/06/2023. Qual a idade gestacional em dias? A sintaxe para calcular um intervalo é dada pela subtração das duas datas:

data.inicial <- dmy("04/10/2022")
data.final <- dmy("30/06/2023")
idade_gesta <- data.final - data.inicial
idade_gesta
Time difference of 269 days

Ou seja a gestação durou 269 dias, constituindo-se em um parto a termo, entre 37 (259 dias) e 42 semanas (294 dias).

Para mais informações sobre o lubridate, consulte a ajuda do pacote ou o capítulo 16 do livro R for Data Science, Hadley Wickman e Garrett Grolemund, 2017 [https://r4ds.had.co.nz/index.html] .


  1. A mudança do nome do dataframe de dadosNeonatos para neonatos é desnecessária. Foi realizada apenas por questões didáticas.↩︎

  2. Observe, na saída, que a variável utiNeo aparece palavras com acentuação (“não”). Às vezes, ao abrir o arquivo com a função read.csv2(), pode acontecer de esta palavra aparecer, por exemplo, como: “n3o”. Louco, não é? Se ocorrer isso, use, após o nome do arquivo e separado por vírgula, o argumento fileEncoding = “latin1”. Dessa forma, o erro será corrigido.↩︎

  3. Da mesma maneira, como acontece com a função read.csv2(), a função equivalente do readr pode retornar erro na leitura de palavras com acento. Para corrigir isso, usa-se o argumento locale (encoding = "latin1")↩︎

  4. O nome é uma referência ao famoso quadro do pintor belga René Magritte La Trahison des images (Ceci n’est pas une pipe).↩︎

  5. Além do pipe, indiretamente, embutido no tidyverse, existe o pipe nativo do R (|>) que também pode ser usado com as mesmas funções do %>%.↩︎

  6. Hospital Escola da Universidade de Caxias do Sul, RS.↩︎

  7. Para que o pipe (%>%) seja ativado é necessário carregar o pacote dplyr; para o pipe nativo (|>) não há necessidade.↩︎

  8. POSIXt é uma classe de objetos do R que representa datas e horas. POSIXt significa Portable Operating System Interface for Unix Time, que é um padrão para medir o tempo em segundos desde 1 de janeiro de 1970. Existem duas formas internas de implementar POSIXt: POSIXct e POSIXlt. POSIXct armazena os segundos desde a época UNIX e POSIXlt armazena uma lista de dia, mês, ano, hora, minuto, segundo, etc.↩︎