O conceito tidy data
A ideia central desse post é bem simples: dados bem organizados valem a pena e economizam seu tempo!
Em minha primeira iniciação científica (quando comecei a trabalhar com o R), propus um experimento para avaliar a eficiência de 2 inseticidas para o controle de uma praga que ataca mudas de eucalipto (Cegatta and Villegas 2013). Eu estava no primeiro ano da faculdade, sabia muito pouco de Excel e nada de R.
Neste post vou retomar os dados brutos desse experimento e organizá-los de uma forma eficiente, pois na época não o fiz.
No experimento tivemos 5 coletas sucessivas de dados para acompanhar a evolução do número de galhas em mudas de eucalipto com diferentes tratamentos de inseticidas. Galha é uma reação da planta que tem diversas causas, nesse caso específico, é devido à postura de uma vespa em busca de abrigo para seus ovos.
A estrutura do banco de dados que obtive no fim do experimento está apresentada na Figura 1. Para a época, foi o melhor que consegui fazer e pela inexperiência cometi os seguintes erros:
- Uso de caracteres especiais.
- Uso de espaço entre as palavras.
- Células mescladas.
- Observações (Nº de galhas no pecíolo, nervura e caule) organizadas em colunas.
O uso de caracteres especiais não é recomentado em muitas ocasiões, essa dica vale para quase tudo que envolve computação. O mesmo se aplica para os espaços entre as palavras, mas podemos ser mais flexíveis neste caso. Mesclar uma célula será o seu maior problema em uma planilha eletrônica, cuidado com isso! Recomendo mesclar células em raríssimas exceções, como formatação de tabelas em Word ou PowerPoint. O meu último erro foi o maior deles, confundi observações com variáveis. Em minha defesa, o inexperiente Ítalo tentou organizar os dados em um layout de fácil visualização. Veja que é fácil acompanhar a evolução das galhas ao longo do tempo. Para a percepção humana, organização de dados no formato longitudinal é muito prática e rápida. Mas temos que pensar em como o computador trabalha e como ele faz todos os cálculos que precisamos. No fim, eu consegui fazer tudo que eu queria com os dados nesse formato, mas acredite, foi sofrível e muito ineficiente.
O conceito tidy data está muito bem descrito por Wickham (2014), onde ele apresenta o pacote tidyr que contém uma gama de funções muito úteis para esse fim. Wickham também dedicou um capítulo específico sobre esse conceito em seu livro (Grolemund and Wickham 2016). Por tidy data, entendemos que:
- Variáveis estão dispostas em colunas.
- Observações estão dispostas em linhas.
- Os valores atribuídos às variáveis em cada observação formam a tabela.
Agora vamos aplicar esse conceito ao meu banco de dados. Podemos fazer isso de várias formas, vai depender de como iremos entrar com os dados no R. Vou mostrar 2 métodos que penso ser os mais práticos e genéricos.
# Pacotes utilizados neste post
if (!require("pacman")) install.packages("pacman")
pacman::p_load(readxl, dplyr, tidyr, httr)
Método 1
Partindo da base de dados original, fiz uma pequena alteração separando em cada aba as coletas que foram realizadas (Figura 2).
Como são apenas 4 abas, podemos importá-las usando um comando por linha.
Mas e se tivéssemos 50 coletas? Deu preguiça. Vamos melhorar a importação e deixar o computador trabalhar por nós.
# Faz o mesmo que os comandos anteriores, mas utiliza um ´for´ para repetir
# o precesso em todas as abas.
dados1 <- list()
for(i in 1:5) {
dados1[[paste0("c",i)]] <- read_excel(base_vespa1, paste0("Coleta", i))
}
Agora precisamos de um fator (nº da coleta) para diferenciarmos cada medição e colocar tudo em um único data frame.
# Cria um fator para diferenciar as medições
for(i in names(dados1)) {
dados1[[i]][ , "Coleta"] = i
}
dados1 <- bind_rows(dados1)
Como minhas análises vão considerar o local da galha como variável, devo organizar Peciolo, Nervura e Caule em uma só coluna denominada Local.
# Transforma as columas ´Peciolo´, ´Nervura´ e ´Caule´ em uma só coluna
# denominada ´Local´.
dados1 <- gather(dados1, "Local", "Galhas", c(Peciolo, Nervura, Caule))
dados1
## # A tibble: 2,100 x 5
## Tratamento Individuo Coleta Local Galhas
## <chr> <dbl> <chr> <chr> <dbl>
## 1 Actara d1 1 c1 Peciolo 1
## 2 Actara d1 2 c1 Peciolo NA
## 3 Actara d1 3 c1 Peciolo NA
## 4 Actara d1 4 c1 Peciolo NA
## 5 Actara d1 5 c1 Peciolo NA
## 6 Actara d1 6 c1 Peciolo NA
## 7 Actara d1 7 c1 Peciolo NA
## 8 Actara d1 8 c1 Peciolo NA
## 9 Actara d1 9 c1 Peciolo NA
## 10 Actara d1 10 c1 Peciolo NA
## # ... with 2,090 more rows
Método 2
Nesse método, não fiz nenhuma grande alteração na base de dados. Apenas corrigi o nome das colunas com um fator que indica o número da coleta e em seguida o local (Figura 3).
Vamos agora importar e organizar os dados no mesmo formato que no método 1, mas com um código bem mais simples.
# Lê os dados, transforma as variáveis que estão em várias colunas em uma só e
# Separa as informações que estão na coluna ´Local´ em duas colunas (variáveis)
# ´Coleta´ e ´Local´.
dados2 <- read_excel(base_vespa2) %>%
gather("Local", "Galhas", 3:dim(.)[2]) %>%
separate(Local, c("Coleta", "Local"))
dados2
## # A tibble: 2,100 x 5
## Tratamento Individuo Coleta Local Galhas
## <chr> <dbl> <chr> <chr> <dbl>
## 1 Actara d1 1 1 Peciolo 1
## 2 Actara d1 2 1 Peciolo NA
## 3 Actara d1 3 1 Peciolo NA
## 4 Actara d1 4 1 Peciolo NA
## 5 Actara d1 5 1 Peciolo NA
## 6 Actara d1 6 1 Peciolo NA
## 7 Actara d1 7 1 Peciolo NA
## 8 Actara d1 8 1 Peciolo NA
## 9 Actara d1 9 1 Peciolo NA
## 10 Actara d1 10 1 Peciolo NA
## # ... with 2,090 more rows
Com os dados nesse formato fica incrivelmente fácil fazer gráficos, resumos e testes. Vou abordar esses pontos no futuro em outros posts.
Caso tenha alguma dúvida ou sugestão sobre o post, fique à vontade para fazer um comentário ou me contatar por E-mail.
devtools::session_info()
## - Session info ----------------------------------------------------------
## setting value
## version R version 3.5.3 (2019-03-11)
## os Windows 10 x64
## system x86_64, mingw32
## ui RTerm
## language (EN)
## collate Portuguese_Brazil.1252
## ctype Portuguese_Brazil.1252
## tz America/Sao_Paulo
## date 2019-08-25
##
## - Packages --------------------------------------------------------------
## package * version date lib source
## assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.5.3)
## backports 1.1.4 2019-04-10 [1] CRAN (R 3.5.3)
## blogdown 0.14 2019-07-13 [1] CRAN (R 3.5.3)
## bookdown 0.12 2019-07-11 [1] CRAN (R 3.5.3)
## callr 3.3.1 2019-07-18 [1] CRAN (R 3.5.3)
## cellranger 1.1.0 2016-07-27 [1] CRAN (R 3.5.1)
## cli 1.1.0 2019-03-19 [1] CRAN (R 3.5.3)
## crayon 1.3.4 2017-09-16 [1] CRAN (R 3.5.1)
## curl 4.0 2019-07-22 [1] CRAN (R 3.5.3)
## desc 1.2.0 2018-05-01 [1] CRAN (R 3.5.1)
## devtools 2.1.0 2019-07-06 [1] CRAN (R 3.5.3)
## digest 0.6.20 2019-07-04 [1] CRAN (R 3.5.3)
## dplyr * 0.8.3 2019-07-04 [1] CRAN (R 3.5.3)
## evaluate 0.14 2019-05-28 [1] CRAN (R 3.5.3)
## fansi 0.4.0 2018-10-05 [1] CRAN (R 3.5.1)
## fs 1.3.1 2019-05-06 [1] CRAN (R 3.5.3)
## glue 1.3.1 2019-03-12 [1] CRAN (R 3.5.3)
## highr 0.8 2019-03-20 [1] CRAN (R 3.5.3)
## htmltools 0.3.6 2017-04-28 [1] CRAN (R 3.5.1)
## httr * 1.4.1 2019-08-05 [1] CRAN (R 3.5.3)
## knitr 1.24 2019-08-08 [1] CRAN (R 3.5.3)
## magrittr 1.5 2014-11-22 [1] CRAN (R 3.5.1)
## memoise 1.1.0 2017-04-21 [1] CRAN (R 3.5.1)
## pacman * 0.5.1 2019-03-11 [1] CRAN (R 3.5.3)
## pillar 1.4.2 2019-06-29 [1] CRAN (R 3.5.3)
## pkgbuild 1.0.4 2019-08-05 [1] CRAN (R 3.5.3)
## pkgconfig 2.0.2 2018-08-16 [1] CRAN (R 3.5.1)
## pkgload 1.0.2 2018-10-29 [1] CRAN (R 3.5.1)
## prettyunits 1.0.2 2015-07-13 [1] CRAN (R 3.5.1)
## processx 3.4.1 2019-07-18 [1] CRAN (R 3.5.3)
## ps 1.3.0 2018-12-21 [1] CRAN (R 3.5.2)
## purrr 0.3.2 2019-03-15 [1] CRAN (R 3.5.3)
## R6 2.4.0 2019-02-14 [1] CRAN (R 3.5.2)
## Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.5.3)
## readxl * 1.3.1 2019-03-13 [1] CRAN (R 3.5.3)
## remotes 2.1.0 2019-06-24 [1] CRAN (R 3.5.3)
## rlang 0.4.0 2019-06-25 [1] CRAN (R 3.5.3)
## rmarkdown 1.14 2019-07-12 [1] CRAN (R 3.5.3)
## rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.5.1)
## sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.5.2)
## stringi 1.4.3 2019-03-12 [1] CRAN (R 3.5.3)
## stringr 1.4.0 2019-02-10 [1] CRAN (R 3.5.2)
## testthat 2.2.1 2019-07-25 [1] CRAN (R 3.5.3)
## tibble 2.1.3 2019-06-06 [1] CRAN (R 3.5.3)
## tidyr * 0.8.3 2019-03-01 [1] CRAN (R 3.5.3)
## tidyselect 0.2.5 2018-10-11 [1] CRAN (R 3.5.1)
## usethis 1.5.1 2019-07-04 [1] CRAN (R 3.5.3)
## utf8 1.1.4 2018-05-24 [1] CRAN (R 3.5.1)
## vctrs 0.2.0 2019-07-05 [1] CRAN (R 3.5.3)
## withr 2.1.2 2018-03-15 [1] CRAN (R 3.5.1)
## xfun 0.8 2019-06-25 [1] CRAN (R 3.5.3)
## yaml 2.2.0 2018-07-25 [1] CRAN (R 3.5.1)
## zeallot 0.1.0 2018-01-28 [1] CRAN (R 3.5.2)
##
## [1] C:/Users/Italo/Documents/R/win-library/3.5
## [2] C:/Program Files/R/R-3.5.3/library
Referências
Cegatta, Italo Ramos, and Cristian Villegas. 2013. “Eficiência de dois inseticidas sistêmicos no controle de Leptocybe invasa em mudas de Eucalyptus camaldulensis.” Revista Instituto Florestal 25 (2). iflorestal.sp.gov.br/files/2014/05/RIF25-2{\_}215-221.pdf.
Grolemund, Garrett, and Hadley Wickham. 2016. R for Data Science. O’Reilly Media. http://r4ds.had.co.nz/.
Wickham, Hadley. 2014. “Tidy data.” The Journal of Statistical Software 59 (10). http://www.jstatsoft.org/v59/i10/.