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.frames.data.frames.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"))
tidyversetidyverse.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.
tidyversetibbledata.frame é a estrutura nativa (primitiva) para representar tabelas de dados.tibble é uma reimplementação da estrutura com melhorias.
tibble.readrreadr tem recursos para importação de dados retangulares na forma de texto pleno.data.table.read_*().write_*().parse_*.tidyrtidy (tabular).tidy:
dplyrdplyr é 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().ggplot2ggplot2 - Elegant Graphics for Data Analysis.ggplot2 Essentials.purrrpurrr fornece um conjunto completo e consistente para programação funcional.apply.map() para cada tipo de input/output.stringrstringi.forcatstidyverselubridate e hmstidyverse.magrittrx %>% 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()
tidyverselibrary(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.frameUma 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.framedf_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.