Transformando colunas em linhas e outras loucuras com tidyr
- Cada célula é um valor único.
- Cada coluna é uma variável.
- Cada linha é uma observação.
O pacote tidyr foi criado com esse propósito.
Quando temos um banco de dados, uma das primeiras preocupações deve estar relacionada à qualidade desses dados. Eles precisam estar organizados e limpos para que as análises sejam feitas.
Já falamos aqui sobre a manipulação de um banco de dados em Python e em R (com o pacote dplyr). Além de manipular dados, é importante verificar se eles estão organizados. A equipe do tidyverse.org preparou o checklist acima para entender se um banco de dados está organizado.
Esse é um tutorial para te ensinar a fazer as seguintes transformações:
1. Separar uma coluna em duas ou mais colunas
2. Transformar colunas em linhas
3. Transformar linhas em colunas
4. Unir colunas
A gente vai usar esse banco de dados aqui. Esse banco contém dados fictícios do número de telefonemas e cartas que passaram por essas cidades pequenas.
Atualmente o banco tem 20 linhas e 10 colunas.
Ao final, ele vai ter 70 linhas e 6 colunas.
A coluna id representa o código de identificação da cidade. A coluna cidade contém o nome das cidades. A informação sobre as cartas são sempre pegas no mesmo dia do ano, já as colunas hora_coleta e minutos_coleta representa o horário em que as informações sobre a cidade foram coletadas naquele ano — sempre entre 11h da manhã e 13h da tarde.
Os anos estão separados por colunas, sendo que as últimas colunas, infelizmente, tiveram seu valor colocado em uma mesma coluna… Uma pena, embora seja conveniente para o que queremos aprender.
Transformação inicial
Antes de começar, vamos apenas carregar o banco de dados e retirar a primeira coluna que carrega com ele.
data_url <- "https://raw.githubusercontent.com/GabrielReisR/R/master/estrutura%20de%20dados/dados/untidy.csv"
untidy <- read.csv(data_url)untidy <- untidy[,-c(1)] # retirando primeira coluna
Vamos começar?
Separar uma coluna em duas ou mais colunas
Vamos lembrar da primeira regra: cada célula deve ser um valor único.
Para ter a certeza de que nosso banco cumpra isso, utilizaremos a função separate()
do tidyr.
O primeiro grande erro do banco, como já citado, está na computação da coluna ano_1994_1995_1996.
Vamos usar a função separate()
para separar os valores da coluna ano_1994_1995_1996.
separate()
é bem simples, então vamos exemplificar fazendo
Basta adicionar o nome da coluna atual ("ano_1994_1995_1996"
), a separação que existe entre as variáveis daquela coluna (nesse caso, um espaço sep = " "
), e quais as novas colunas que devem ser criadas (into = c("ano_1994", "ano_1995", "ano_1996")
). Pronto!
O que antes estava contido em uma só coluna agora está separado por coluna. Vários valores que estavam em uma só célula agora estão em outras.
Transformar colunas em linhas
Agora a gente vai entrar nas funções pivot. Vamos lembrar: Cada coluna deve ser uma variável.
Para ter a certeza de que nosso banco cumpra isso, utilizaremos pivot_longer()
. Nos livraremos de colunas repetitivas e alongaremos o banco de dados ao acrescentar mais linhas nele.
A parte mais fácil passou. Era óbvio que os dados dos anos precisavam ser separados.
Entretanto, nem tudo é óbvio quando se trata de dados organizados. Às vezes pode ser difícil enxergar que precisamos deixar apenas uma coluna para cada variável.
Todos os anos de coleta dizem respeito a apenas uma variável, a variável ano. Como sabemos disso? Pois isso é algo que varia em cada observação. Ao invés de termos uma coluna para cada um dos anos, o ideal seria criar uma coluna ano para armazenar todos esses anos.
Quais colunas entrarão na nova coluna ano?
A nossa nova coluna ano armazenará todos os nomes das colunas que representam o ano. Já os valores dessas colunas serão armazenados em uma nova coluna chamada de casos.
Como escrever isso? Usaremos a função pivot_longer()
.
Transformar linhas em colunas
Olhando o banco acima podemos perceber que existem duas observações para cada um dos 6 anos coletados. Isso porque há uma divisão entre o tipo “cartas” e “telefonemas”.
Isso quebra nossa terceira regra. Vamos lembrá-la: cada linha é uma observação só.
Para ter a certeza de que nosso banco cumpra isso, utilizaremos pivot_wider()
. Nos livraremos de linhas repetitivas e alargaremos o banco de dados ao acrescentar mais colunas nele.
Agora que temos o nosso banco quase pronto, vamos refletir sobre duas colunas importantes: tipo e casos.
- tipo informa qual meio de comunicação essa cidade usou.
- casos informa quantas vezes essa cidade usou esse meio.
O problema aqui é que temos duas linhas para uma observação só! Em 1990, Butte, às 11h27, desde o ano anterior, havia enviado 4275 cartas e feito 3450 telefonemas.
A questão é que “cartas” e “telefonemas” são coisas diferentes, elas não são variáveis contidas em “tipo” (assim como os anos estão contidos ano, telefonemas e cartas não estão contidas em tipo). Estamos alongando o banco sem necessidade, já que estamos falando de coisas diferentes e poderíamos ter duas colunas para cada uma dessas variáveis.
Torna-se interessante alargar esses dados (essa é uma escolha, não uma regra) — ou seja, criar colunas para cartas e telefonemas. Para isso, usamos pivot_wider()
.
Agora sim!
- Perceba que agora temos apenas uma linha para cada ano, ao invés de 2 linhas para cada ano.
- Da mesma forma, ‘casos’ não é mais necessário, e nosso banco se tornou mais fácil de ser lido.
Unir colunas
Uma coluna para cada variável e uma célula para um caso único. Aqui, a gente vai se preocupar com duas colunas, utilizando unite()
para resolver um probleminha que temos.
Algo que ainda não conversamos sobre é a redundância das colunas hora_coleta e minutos_coleta. Essa pode ser apenas uma coluna, não precisa ser duas. Vamos criar uma nova coluna que vai se chamar horario_coleta.
Vamos juntar as duas com unite()
.
Vamos entender:
- Iniciamos com a primeira coluna que queremos. O valor dessa coluna irá na frente (
hora_coleta
). - A segunda coluna informa o valor que irá em segundo lugar (
minutos_coleta
). - Definimos uma separação para nossas variáveis. Nesse caso, tratando-se de horários, preferi
sep = ":"
. - É possível definir sem separação: nesse caso,
sep = ""
. - Em
col = "horario_coleta"
, definimos o nome da nossa coluna como horario_coleta.
Como prometido, passamos de 20 linhas para 70 linhas, de 10 colunas para 6 colunas.
Espero que tenha ajudado, de alguma forma, a entender um pouco mais sobre dados organizados usando tidyr.
Como procurar ajuda?
O tutorial apresentado nesse post também pode ser encontrado aqui.
- Fóruns: https://pt.stackoverflow.com/
- Documentação: https://cran.r-project.org/web/packages/tidyr/tidyr.pdf
- Página no tidyverse: https://tidyr.tidyverse.org/index.html
- Cheatsheet (folha de códigos): https://github.com/rstudio/cheatsheets/blob/master/data-import.pdf
Contato
Espero que tenha gostado! Qualquer dúvida, observação ou comentário são muito bem-vindos! Fique à vontade para se manifestar e vamos aprender juntos 😄
Para falar comigo, é só entrar em qualquer um desses links.
☕️ Gostou do post e vai usar algo? Se quiser, você pode me pagar um café.