10.3 Restruturação de dados retangulares

Até 80% do tempo da análise dados é dedicada ao processo de limpeza e preparação dos dados (Dasu and Johnson 2003, New York Times 2014/08/18).

10.3.1 Dados arrumados

O conceito "dados arrumados" foi estabelecido por H. Wickham (2014) e representa uma forma padronizada de conectar a estrutura (formato) de um conjunto de dados a sua semântica (significado).

Dados bem estruturados servem para:

  • fornecer dados propícios para o processamento e análise de dados por softwares;

  • revelar informações e facilitar a percepção de padrões

Dados no "formato arrumado" atendem as seguintes regras para dados retangulares:

  1. cada variável está em uma coluna

  2. cada observação corresponde a uma linha

  3. cada valor corresponde a uma célula

  4. cada tipo de unidade observacional deve compor uma tabela

Como sinônimo de observações você pode encontrar os termos: registros, casos, exemplos, instâncias ou amostras dependendo da área de aplicação.

Estrutura de dados padronizados

Estrutura de dados padronizados

Um exemplo de dados no formato arrumado é o tibble prec_anual_tbl mostrado abaixo:

Os dados acima tem duas variáveis: precipitação (prec) e intensidade da precipitação (intensidade). As unidades observacionais são as colunas site e ano. A primeira unidade observacional informa o ponto de amostragem espacial e a segunda o ponto de amostragem temporal.

Uma variável contém todos valores que medem um mesmo atributo ao longo das unidades observacionais. Uma observação contém todos valores medidos na mesma unidade observacional ao longo dos atributos. Cada valor (número ou caractere) pertence a uma variável e uma observação.

Exemplo de diferentes tipos de unidades observacionais são a tabela com a séries temporais dos elementos meteorológicos (exemplo acima) e a tabela com os metadados das estações de superfície que contém atributos das estações meteorológicas (site no exemplo acima), tais como: longitude, latitude, altitude, nome, município, estado e etc.

A estrutura de dados "arrumados" parece óbvia, mas na prática, dados neste formatos são raros de serem encontrados. As razões para isso incluem:

  • quem projeta a coleta e o registro de dados nem sempre é aquele que gasta tempo trabalhando sobre os dados;

  • a organização dos dados busca tornar o registro de dados o mais fácil possível;

Consequente, dados reais sempre precisarão ser arrumados. O primeiro passo é identificação das variáveis e das observações. O passo seguinte é resolver os seguintes problemas mais comuns:

  • distribuir observações (que estão armazenadas nas colunas) ao longo das linhas

  • distribuir variáveis (que estão armazenada nas linhas) ao longo das colunas

Essas duas operações são realizadas com as principais funções do pacote tidyr:

  • pivot_longer(): para pivotar colunas ao longo das linhas (reunir "variáveis" nas linhas);

  • pivot_wider(): para pivotar linhas ao longo das colunas (espalhar "observações" nas colunas)

10.3.2 Formatos de dados mais comuns

O pacote tidyr é a extensão do que fornece funcionalidades para reestruturar os dados entre diferentes formatos.

Os principais formatos de dados são:

  • dados longos, são tabelas com mais valores ao longo das linhas; geralmente mistura variáveis com observações;

  • dados amplos, são tabelas com valores mais distribuídos nas colunas, geralmente contém pelo menos uma unidade observacional misturada com variáveis;

10.3.2.1 Formato de dados longo

Para exemplificar o formato de dados longo vamos partir dos "dados arrumados" do exemplo, prec_anual_tbl. Primeiro vamos renomear a variável int prec para intensidade para seguir um o padrão de nome das variáveis mais conveniente para o seu processamento no .

prec_anual_tbl <- rename(
  prec_anual_tbl,
  "intensidade" = `int prec`
) 
prec_anual_tbl

Vamos usar a função tidyr::pivot_longer() para reestruturar os dados prec_anual_tbl em uma nova tabela de dados que chamaremos prec_anual_long.

Na nova tabela, manteremos as colunas site, ano e teremos dois novos pares de variáveis: variavel e valor. Na coluna variavel pivotaremos as variáveis prec e intensidade. Na coluna valor pivotaremos os valores das variáveis prec e intensidade.


prec_anual_long <- pivot_longer(
  data = prec_anual_tbl,
  cols = c(prec, intensidade), # ou c("prec", "intensidade"),
  names_to = "variavel",
  values_to = "medida"
)
prec_anual_long

# prec_anual_long <- gather(
#   data = prec_anual_tbl,
#   key = variavel,
#   value = medida,
#   prec, intensidade
# )

O código acima demonstra os principais argumentos requeridos pela função gather:

  • data = prec_anual_tbl, o quadro de dados ou tibble que será reestruturado;

  • cols = c("prec", "intensidade"), variáveis a serem pivotadas no formato longo;

  • names_to = variavel, um vetor caractere com nome que nós escolhemos para dar à nova coluna que armazenará os dados nos nomes das variáveis dos dados de entrada (data).

  • values_to = medida, um caractere com o nome que nós escolhemos para dar à nova coluna que armazenará os dados contidos nos valores das células;

As demais colunas dos dados (site e ano) serão mantidas inalteradas e seus valores serão repetidos quando necessário.

Como em outras funções dos pacotes do tidyverse você perceberá que alguns argumentos não são especificados como caracteres e sim como nomes (ou seja o nome da variável sem aspas), como aqueles usados quando definimos variáveis (p.ex.: nome_var <- 10). Os argumentos names_to e values_to podem ser especificados à gosto do usuário e não precisam ter relação com os dados existentes.

Se nós desejássemos que todas colunas do quadro de dados fossem reunidas em uma nova coluna variavel e os seus valores em uma nova coluna valor, isso poderia intuitivamente ser feito simplesmente especificando as variáveis de interesse por everything()29 no trecho de código anterior.

prec_anual_longo <- pivot_longer(
  data = prec_anual_tbl, 
  cols = everything(),
  names_to = "atributo",
  values_to = "valor",
  values_ptypes = list(site = 'numeric')
)

Entretanto, como a variável site é do tipo caractere, ela não pode ser combinada com variáveis do tipo numérico. Então temos que transformar a variável site para numérico se isso for realmente necessário.

prec_anual_tbl_num <- transform(
  prec_anual_tbl,
  site = parse_number(site)
)
prec_anual_tbl_num

A função parse_number() é uma função auxiliar do pacote readr para extrair números de um caractere.

pivot_longer(
  data = prec_anual_tbl_num, 
  cols = everything(),
  names_to = "atributo",
  values_to = "valor"
)

A tabela de dados resultante conterá todos os 32 pares de valores, formados pelas 4 colunas por 8 linhas, dos dados originais.

Se não forem especificados nomes para os argumentos names_to e values_to na chamada da função tidyr::pivot_longer, serão atribuídos os valores default: name e value.

pivot_longer(
  data = prec_anual_tbl_num, 
  cols = everything()
)

10.3.2.2 Formato de dados amplo

Utilizando os dados meteo_long, vamos reestruturá-lo no formato amplo para demostrar a funcionalidade da função tidyr::pivot_wider(). Esta função é complementar à tidyr::pivot_longer().

prec_anual_long

Nosso objetivo é então gerar uma nova tabela de dados reestruturada, de forma que os nomes das variáveis (contidos na coluna variavel) sejam pivotados em duas colunas. Estas colunas receberão os nomes prec e intensidade e serão preenchidas com os dados das células da coluna medida. Para fazer isso usamos o seguinte código:

prec_anual_amplo <- pivot_wider(
  data = prec_anual_long,
  names_from = variavel,
  values_from = medida
)
prec_anual_amplo

Esta operação serviu para colocar os dados originais (prec_anual_long) no formato "arrumado" (prec_anual_amplo).

10.3.3 Funções adicionais do tidyr

Você pode unir duas colunas inserindo um separador entre elas com a função tidyr::unite():

(prec_anual_long_u <- unite(
  data = prec_anual_long,
  col = site_ano,
  site, ano,
  sep = "_"
))

Se ao contrário, você quer separar uma coluna em duas variáveis, utilize a função tidyr::separate():

separate(
  data = prec_anual_long_u,
  col = site_ano,
  sep = "_",
  into = c("site", "ano")
)

Para completar valores das variáveis para unidades observacionais faltantes podemos utilizar a função tidyr::complete():

prec_anual
prec_anual_comp <- complete(
  data = prec_anual,
  site, ano
)
prec_anual_comp

10.3.4 Exercícios

Pacotes necessários

pcks <- c("rio", "tidyverse", "lubridate")
easypackages::libraries(pcks)

  1. Nós veremos mais sobre funções do tipo seletoras na seção de manipulação de dados.