31 de julho de 2019
Tempo gasto nas atividades de Data Science. Fonte: https://www.forbes.com/sites/gilpress/2016/03/23/data-preparation-most-time-consuming-least-enjoyable-data-science-task-survey-says.
Quão enfadonhas são as atividades em Data Science. Fonte: https://www.forbes.com/sites/gilpress/2016/03/23/data-preparation-most-time-consuming-least-enjoyable-data-science-task-survey-says.
R for Data Science, a principal referência sobre o emprego da linguagem R em ciência de dados.
tidyverse
= {tibble
, readr
, tidyr
, dplyr
, ggplot2
, stringr
, forcats
, purrr
}.tidyverse
+ {lubridate
, rvest
, xml2
, httr
, etc}.data.frame
.base
, reshape
, reshape2
, etc.tibble
, readr
, dplyr
, tidyr
.ggplot2
, purrr
, stringr
, forcats
.
Sintaxe do data.table
. Para uma visão geral, visite a wiki do projeto: https://github.com/Rdatatable/data.table/wiki.
library(data.table) iris_dt <- as.data.table(iris) iris_dt[, list(SPmean = mean(Sepal.Length), PLmean = mean(Petal.Length)), by = Species]
data.frame
s.data.frame
s.RSQLite
, RH2
, RMySQL
and RPostgreSQL
.library(sqldf) sqldf(paste("SELECT Species,", "AVG(`Sepal.Length`) AS SLmean,", "AVG(`Petal.Length`) AS PLmean", "FROM iris", "GROUP BY Species"))
tidyverse
tidyverse
.tidyverse
contémlibrary(tidyverse) ls("package:tidyverse")
## [1] "tidyverse_conflicts" "tidyverse_deps" "tidyverse_logo" ## [4] "tidyverse_packages" "tidyverse_update"
tidyverse_packages()
## [1] "broom" "cli" "crayon" "dplyr" "dbplyr" ## [6] "forcats" "ggplot2" "haven" "hms" "httr" ## [11] "jsonlite" "lubridate" "magrittr" "modelr" "purrr" ## [16] "readr" "readxl\n(>=" "reprex" "rlang" "rstudioapi" ## [21] "rvest" "stringr" "tibble" "tidyr" "xml2" ## [26] "tidyverse"
tidyverse
Pacotes que fazer parte do tidyverse
.
Mas em uma realidade pararela.
tidyverse
tibble
data.frame
é a estrutura nativa (primitiva) para representar tabelas de dados.tibble
é uma reimplementação da estrutura com melhorias.
tibble
.readr
readr
tem recursos para importação de dados retangulares na forma de texto pleno.data.table
.read_*()
.write_*()
.parse_*
.tidyr
tidy
(tabular).tidy
:
dplyr
dplyr
é a gramática para manipulação de dados.mutate()
, select()
, filter()
, arrange()
, summarise()
, slice()
, rename()
, etc._at()
, _if()
, _all()
, etc.group_by()
e ungroup()
.inner_join()
, full_join()
, left_join()
e right_join()
.ggplot2
ggplot2
- Elegant Graphics for Data Analysis.ggplot2
Essentials.purrr
purrr
fornece um conjunto completo e consistente para programação funcional.apply
.map()
para cada tipo de input/output.stringr
stringi
.forcats
tidyverse
lubridate
e hms
tidyverse
.magrittr
x %>% f
é o mesmo que f(x)
.x %>% f(y)
é o mesmo que f(x, y)
.x %>% f %>% g %>% h
é o mesmo que h(g(f(x)))
.tidyverse
# Do CRAN (recomendado). install.packages("tidyverse") # Do GitHub. # install.packages("devtools") devtools::install_github("hadley/tidyverse") # Atualizar caso já tenha instalado. tidyverse_update()
tidyverse
library(tidyverse) u <- sessionInfo() names(u$otherPkgs)
## [1] "forcats" "stringr" "dplyr" "purrr" "readr" ## [6] "tidyr" "tibble" "ggplot2" "tidyverse" "sqldf" ## [11] "RSQLite" "gsubfn" "proto" "data.table" "rmarkdown" ## [16] "knitr"
readr
começam com read_
.ls("package:readr") %>% str_subset("^read_")
[1] "forcats" "stringr" "dplyr" "purrr" "readr" "tidyr" [7] "tibble" "ggplot2" "tidyverse"
# Endereço web do arquivo, mas poderia ser local. url <- "http://leg.ufpr.br/~walmes/data/euro_football_players.txt" # Importa a tabela de dados. tb <- read_tsv(file = url, comment = "#") head(tb, n = 6)
class()
retorna a classe do objeto.str()
exibe a estrutura de um objeto.attributes()
retorna atributos.methods()
exibe os métodos de uma classe.attributes(tb) attr(tb, "spec") <- NULL
class(tb) methods(class = "tbl_df") str(tb)
data.frame
Uma tabela com dados fictícios.
data.frame
# Cria um tibble data.frame a partir de vetores. df1 <- tibble(matricula = c(256, 487, 965, 125, 458, 874, 963), nome = c("João", "Vanessa", "Tiago", "Luana", "Gisele", "Pedro", "André"), curso = c("Mat", "Mat", "Est", "Est", "Est", "Mat", "Est"), prova1 = c(80, 75, 95, 70, 45, 55, 30), prova2 = c(90, 75, 80, 85, 50, 75, NA), prova3 = c(80, 75, 75, 50, NA, 90, 30), faltas = c(4, 4, 0, 8, 16, 0, 20)) df2 <- tibble(matricula = c(505, 658, 713), nome = c("Bia", "Carlos", "Cris"), curso = c("Eng", "Eng", "Eng"), prova1 = c(65, 75, 75), prova2 = c(85, 80, 90), faltas = c(0, 0, 2))
data.frame
df_extra <- tribble( ~mat, ~nome, ~idade, ~bolsista, 256, 'João' , 18, "S", 965, 'Tiago' , 18, "N", 285, 'Tiago' , 22, "N", 125, 'Luana' , 21, "S", 874, 'Pedro' , 19, "N", 321, 'Mia' , 18, "N", 669, 'Luana' , 19, "S", 967, 'André' , 20, "N", )
Ordenação dos registros de uma tabela.
df1 %>% arrange(matricula)
df1 %>% arrange(curso, desc(prova1))
desc()
: ordenação de descente da variável.
names(df1) colnames(df1) rownames(df1)
dim(df1) nrow(df1) ncol(df1)
df1[, c("nome")] df1[, c("nome", "prova1", "prova2", "prova3")] df1 %>% select(c("nome", "prova1", "prova2", "prova3")) df1 %>% select(nome, prova1, prova2, prova3) df1 %>% select(-nome, -faltas) df1 %>% select(prova1:prova3)
df1[, 1:3] df1[, c(1, 4)] df1[, c(-1, -4)] df1 %>% select(1:3) df1 %>% select(1, 4) df1 %>% select(-1, -4)
df1[, seq(1, ncol(df1), by = 2)] df1[, c(1:3, 5:8)] v <- c("prova1", "prova2", "prova3") df1 %>% select(-v) df1 %>% select_if(is.numeric) df1 %>% select(matches("^prova")) df1 %>% select(matches("\\d$")) df1 %>% select(matches("^.{6}$"))
df1[1, ] df1[3:5, ] df1[-(3:5), ] df1[c(3:4, 1:2), ] tail(df1, n = 2) head(df1, n = 2) df1 %>% slice(1) df1 %>% slice(3:5) df1 %>% slice(-(3:5)) df1 %>% slice(c(3:4, 1:2))
No tibble
e data.frame
não é recomendado ter nome para as linhas. Veja explicação em https://tibble.tidyverse.org/reference/rownames.html.
i <- sample(c(TRUE, FALSE), size = nrow(df1), prob = c(0.4, 0.6), replace = TRUE) df1[i, ] df1[df1$prova1 < 50, ] # Amostra aleatória das linhas. df1 %>% sample_n(size = 3, replace = FALSE) df1 %>% sample_frac(size = 0.5, replace = FALSE)
df1[2, "nome"]
Filtro dos registros de uma tabela.
df1[df1$curso == "Est", ] df1[df1$faltas == 0, ] df1[df1$faltas != 0, ] df1[df1$faltas %in% c("Aline", "Vanessa"), ] df1 %>% filter(curso == "Est") df1 %>% filter(faltas == 0) df1 %>% filter(faltas != 0) df1 %>% filter(faltas %in% c("Aline", "Vanessa"))
Formas de renomear as colunas de uma tabela.
# Renomeia nomes de colunas (variáveis). df1 %>% rename("mat." = "matricula", "fl" = "faltas")
names(df1) <- names(df1) %>% str_to_upper() names(df1) <- names(df1) %>% str_sub(start = 1, stop = 3)
As operações podem modificar a tabela com a:
As operações de criação/transformação podem ser:
int
\(\rightarrow\) str
.As transformações podem ser:
Criação e deleção de variáveis em uma tabela.
df1$media <- with(df1, (prova1 + prova2 + prova3/3)) df1$media <- df1 %>% select(prova1:prova3) %>% apply(MARGIN = 1, mean)
df1 %>% mutate_if(is.numeric, sqrt) df1 %>% mutate_if(is.numeric, log) df1 %>% mutate_if(is.character, str_to_upper)
# Intervalos para corte e rótulos. inter <- c(0, 4, 7, Inf) condi <- c("reprovado", "exame", "aprovado") # Cria a variável que é a condição. df1[["condicao"]] <- cut(df1[["media"]], breaks = inter, labels = condi, right = FALSE, include.lowest = TRUE)
df1 %>% mutate_if(is.character, as.factor) df1 %>% mutate_if(is.numeric, as.integer)
df1$prova2 %>% is.na() df1$prova3 %>% negate(is.na)() df1$prova3 %>% is.na() %>% `!`() df1$prova2 %>% replace_na(replace = 0) df1 %>% replace_na(replace = list(prova2 = 0, prova3 = 0, faltas = 60))
df1$media <- NULL df1$condicao <- NULL
Modificação da disposição com empilhamento.
Modificação da disposição com desempilhamento.
# Gather = amontoar. u <- df1 %>% gather(key = "exame", value = "nota", prova1:prova3) # Spread = esparramar. v <- u %>% spread(key = "exame", value = "nota")
Cálculo de medidas resumo.
with(df1, c(sum(prova1), mean(prova1), max(prova1), min(prova1), median(prova1), sd(prova1), var(prova1), length(prova1))) df1 %>% summarise(sum(prova1), mean(prova1), max(prova1), min(prova1), median(prova1), sd(prova1), var(prova1), length(prova1)) %>% t() quantile(df1$prova1, probs = c(0.25, 0.75)) table(df1$prova1)
df1 %>% summarise(CV = 100 * sd(prova1)/mean(prova1)) CV <- function(x, ...) 100 * sd(x, ...)/mean(x, ...) df1 %>% summarise_if(is.numeric, CV, na.rm = TRUE)
df1 %>% summarise_at(vars(prova1:prova3, faltas), c("mean", "max", "min", "CV"), na.rm = TRUE)
Agregação de uma tabela.
Agregação de uma tabela.
Agregação de uma tabela.
df1 %>% group_by(curso) %>% summarise_at(vars(prova1:prova3, faltas), c("mean", "sd"), na.rm = TRUE) df1 %>% select(curso, prova1:prova3, faltas) %>% gather(key = "variavel", value = "valor", -curso) %>% group_by(curso, variavel) %>% summarise_at("valor", c("mean", "sd"), na.rm = TRUE)
u <- df1 %>% group_by(curso) class(u) methods(class = "grouped_df") n_groups(u) group_vars(u) group_size(u) group_indices(u)
NA
são criadas para os índices que não foram especificados.Concatenação de duas tabelas.
bind_rows(df1[1:3, c(1, 3, 5)], df1[5:7, c(1, 3, 5, 4)], df1[4, c(1, 5, 4)]) bind_cols(df1[, c(1:3)], df1[, c(6:7)])
Tipos de junções de tabelas ilustrado com diagramas de Veen.
Junções de tabelas do tipo inclusivas.
inner_join(df1, df_extra, by = c("matricula" = "mat", "nome")) full_join(df1, df_extra, by = c("matricula" = "mat", "nome")) left_join(df1, df_extra, by = c("matricula" = "mat", "nome")) right_join(df1, df_extra, by = c("matricula" = "mat", "nome"))
url <- "http://leg.ufpr.br/~walmes/data/jogadores-brasileirao-2018.txt" bra <- read_tsv(url) attr(bra, "spec") <- NULL str(bra)
TEUTONICO, D. ggplot2 essentials. Packt Publishing, 2015.
WICKHAM, H. ggplot2: Elegant graphics for data analysis. Springer International Publishing, 2016.
WILKINSON, L.; WILLS, D.; ROPE, D.; NORTON, A.; DUBBS, R. The grammar of graphics. Springer New York, 2013.