A manipulação de dados é, na maioria das vezes, realizado com data frames, sendo o pacote dplyr um dos pacotes mais utilizados para esta finalidade. Ele disponibiliza diversas funções que são equivalentes às funções básicas do R, mas como melhorias que nos poupam tempo e deixam o código muito mais fácil de interpretar.
Apesar de não ter uma função diretamente para importação de dados, possui compatibilidade com a maioria dos recursos de importação de dados que retornam o formato data.frame, podendo estar na memória RAM ou não.
Pacote dplyr.
filter - seleciona observações por seus valores (filter());
arrange - reordena as linhas (arrange());
select - seleciona variáveis por seus nomes (select());
mutate - cria novas variáveis com funções de variáveis existes (mutate());
summarize - reúne muitos valores em um único resumo (summarize()).
Juntas, todas estas funções facilitam o encadeamento de vários passos simples para alcançar um resultado complexo.
library(tidyverse)
## -- Attaching packages ------------------------------------------------ tidyverse 1.2.1 --
## v ggplot2 3.2.0 v purrr 0.3.2
## v tibble 2.1.3 v dplyr 0.8.3
## v tidyr 0.8.3 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.4.0
## -- Conflicts --------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
data(iris)
head(iris,10)
tail(iris)
summary(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
dados <- as_tibble(iris)
dados
class(dados)
## [1] "tbl_df" "tbl" "data.frame"
# Vamos filtar todas as flores da espécie setosa que tenham o tamanho da sépala entre 4.0 e 5.2.
iris[iris$Species == "setosa" & iris$Sepal.Length > 4.5 & iris$Sepal.Length < 5.0, ]
# ou da forma:
filter(dados,Species == "setosa" & Sepal.Length > 4.5 & Sepal.Length < 5.0)
soma<-function(x) {x+5}
div<- function(x) {x/5}
x<- 1:10
div(soma(x))
## [1] 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
# ou da forma
x %>% soma() %>% div()
## [1] 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0
A grande vantagem do pipe não é só enxergar quais funções são aplicadas primeiro, mas sim nos ajudar a programar pipelines (encanamento em inglês) de tratamentos de dados.
iris %>% filter(Sepal.Width == 3)
dados %>%
filter(Species == "setosa" & Sepal.Length > 4.5 & Sepal.Length < 5.0)
A seleção de linhas a partir das posições das mesmas pode ser feita com a função slice().
dados %>%
slice(c(1, 3, 5))
slice(dados,n())
A seleção de valores distintos é feita com a função distinct(). Esta função é semelhante à função unique().
dados1<-dados%>%
distinct(Species,Petal.Length)
head(dados1)
A seleção de amostras pode ser feita com as funções sample_n() e sample_f().
amostra<-dados %>%
sample_n(5)
print(amostra)
## # A tibble: 5 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.6 2.9 3.6 1.3 versicolor
## 2 5.4 3.4 1.5 0.4 setosa
## 3 6.2 2.9 4.3 1.3 versicolor
## 4 7.9 3.8 6.4 2 virginica
## 5 6.7 3.3 5.7 2.5 virginica
dados2 <- iris[iris$Species == "setosa" &
iris$Sepal.Length > 4.8 &
iris$Sepal.Length < 5.1,
c("Sepal.Length", "Petal.Length")]
dados3<-dados2[order(dados2$Petal.Length), ]
print(dados3)
## Sepal.Length Petal.Length
## 36 5.0 1.2
## 41 5.0 1.3
## 2 4.9 1.4
## 5 5.0 1.4
## 38 4.9 1.4
## 50 5.0 1.4
## 8 5.0 1.5
## 10 4.9 1.5
## 35 4.9 1.5
## 26 5.0 1.6
## 27 5.0 1.6
## 44 5.0 1.6
Ou da forma:
dados %>%
filter(Species == "setosa" & Sepal.Length > 4.8 & Sepal.Length < 5.1) %>%
select(Sepal.Length, Petal.Length) %>%
arrange(Petal.Length)
A função select pode ser utilizada para selecionar colunas de um data frame. Para selecionar colunas que comecem com s e terminem com h:
dados4 <- select(dados, starts_with('s'), ends_with('h'))
head(dados4)
dados5 <- dados %>% mutate(Dim = Sepal.Length/Petal.Length)
print(dados5)
## # A tibble: 150 x 6
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species Dim
## <dbl> <dbl> <dbl> <dbl> <fct> <dbl>
## 1 5.1 3.5 1.4 0.2 setosa 3.64
## 2 4.9 3 1.4 0.2 setosa 3.5
## 3 4.7 3.2 1.3 0.2 setosa 3.62
## 4 4.6 3.1 1.5 0.2 setosa 3.07
## 5 5 3.6 1.4 0.2 setosa 3.57
## 6 5.4 3.9 1.7 0.4 setosa 3.18
## 7 4.6 3.4 1.4 0.3 setosa 3.29
## 8 5 3.4 1.5 0.2 setosa 3.33
## 9 4.4 2.9 1.4 0.2 setosa 3.14
## 10 4.9 3.1 1.5 0.1 setosa 3.27
## # ... with 140 more rows
dados5 <- dados5 %>% mutate(Dim = (Dim - mean(Dim)) / sd(Dim))
head(dados5)
dados6 <- dados5 %>% select(-Dim)
head(dados6)
A função summarise permite-nos resumir dados. Também é possível resumir dados em função de vários fatores com o group_by.
summarise(dados, total = sum(Sepal.Length))
summarise(dados, média = mean(Sepal.Length))
Utilizando o dataset flights do pacote nycflights13 ou então no link: https://raw.githubusercontent.com/ismayc/pnwflights14/master/data/flights.csv responda as questões que seguem:
Nota: “|” denota “ou”; “&” denota “e”.
O pacote dplyr dispõe também de um conjunto de funções que possibilitam realizar o merging de dois data frames, de forma semelhante à função merge(). Estas funções são:
Em muitas situações durante uma análise de dados, é comum trabalhar com mais de uma tabela, sendo assim pode ser necessário usar ferramentas para as combinar em uma tabela em uma única.
O dplyr oferece várias funções para realizar a junção de duas tabelas, que são a familía x_join(). Todas seguem a mesma sintaxe: x_join(x, y, by), em que x e y são os dois dataframes a serem juntados e by é um vetor de caracteres especificando a coluna que será usada como chave.
library(tidyverse)
library(dplyr)
vendedor <- tibble(id = c("A12", "A13", "A14", "A15"),
regiao = c("Sul", "Sudeste", "Oeste", "Norte"),
experiencia = c(5, 2, 12, 8))
vendas = tibble(id = c("A13", "A14", "A12", "A11"),
vendas = c(1200, 2500, 350, 1000))
left_join(vendedor, vendas)
## Joining, by = "id"
left_join(vendedor, vendas, by = "id")
A função left_join(x, y): retorna todas as observações em x, independentemente se existem correspondentes (de acordo com as especificações em by) ou não.
inner_join(vendedor, vendas)
## Joining, by = "id"
# ou da forma
vendedor %>% left_join(vendas)
## Joining, by = "id"
A função inner_join(x, y): retornar apenas observações que correspondem tanto em x como em y. Note como o vendedor A15 não consta no dataframe final, pois ele não está presente no dataframe y.
inner_join(vendedor, vendas)
## Joining, by = "id"
vendedor %>% inner_join(vendas)
## Joining, by = "id"
A função full_join(x, y) é mais completa e retorna todas as observações presentes em x e y.
full_join(vendedor, vendas, by = "id")
vendedor %>% full_join(vendas)
## Joining, by = "id"
# Outras funções
right_join(vendedor, vendas, by = "id")
semi_join(vendedor,vendas)
## Joining, by = "id"
anti_join(vendedor,vendas)
## Joining, by = "id"
nest_join(vendedor,vendas)
## Joining, by = "id"
Agora veja as seguintes funções para operações com conjuntos:
df1<-tibble(x = c(1:10), y = c("a","b","c","a","b","c","a","b","c","d"))
df1
df2<-tibble(x = c(5:14), y = c("a","a","a","a","a","a","a","a","a","a"))
df2
intersect(df1,df2)
union(df1,df2)
setdiff(df1,df2)# retorna observações em x, mas não em y.
Pacote tidyr.
O paconte tidyr é outro pacote do tidyverse focado no manuseio de dados. Seu objetivo é transformar datasets no formato tidy.
Colocar os dados no formado tidyr (dados arrumados) que possibilita de maneira fácil realizar inúmeras operações mais facilmente dentro do tidyverse.
Há três regras inter-relacionadas que tornam um conjunto de dados no formato tidy:
Regras tidy.
Esse inter-relacionamento leva a um conjunto ainda mais simples de instruções práticas que são:
Nota: dplyr,ggplot2 e todos os pacotes do tidyverse são projetados para trabalhar com dados ‘arrumados’.
library(ggplot2)
library(tidyr)
data(economics)
head(economics)
glimpse(economics)
## Observations: 574
## Variables: 6
## $ date <date> 1967-07-01, 1967-08-01, 1967-09-01, 1967-10-01, 1967...
## $ pce <dbl> 506.7, 509.8, 515.6, 512.2, 517.4, 525.1, 530.9, 533....
## $ pop <dbl> 198712, 198911, 199113, 199311, 199498, 199657, 19980...
## $ psavert <dbl> 12.6, 12.6, 11.9, 12.9, 12.8, 11.8, 11.7, 12.3, 11.7,...
## $ uempmed <dbl> 4.5, 4.7, 4.6, 4.9, 4.7, 4.8, 5.1, 4.5, 4.1, 4.6, 4.4...
## $ unemploy <dbl> 2944, 2945, 2958, 3143, 3066, 3018, 2878, 3001, 2877,...
dados1<- economics %>% gather(indicador, valor, -date)
head(dados1)
dados2<- economics %>% gather(indicador, valor, -date,-pop)
head(dados2)
A função gather “empilha” o banco de dados.
Com isso, o dataset passou do formato wide (menos linhas e mais colunas) em um formato long (mais linhas e menos colunas).
Em algumas situações, porém, será necessário fazer o contrário: transformar o dataset de long para wide. Para isso, usa-se a função spread():
data(economics_long)
head(economics_long)
tail(economics_long)
economics_long %>%
select(-value01) %>%
spread(variable, value, fill = NA)
library(tidyverse)
library(tidyr)
library(readxl)
homic <- read_excel("homicidios_uf.xls")
head(homic)
glimpse(homic)
## Observations: 27
## Variables: 13
## $ Sigla <chr> "AC", "AL", "AM", "AP", "BA", "CE", "DF", "ES", "GO", "...
## $ Codigo <chr> "12", "27", "13", "16", "29", "23", "53", "32", "52", "...
## $ Estado <chr> "Acre", "Alagoas", "Amazonas", "Amapá", "Bahia", "Ceará...
## $ `2000` <dbl> 108, 724, 559, 155, 1223, 1229, 770, 1449, 1008, 344, 2...
## $ `2001` <dbl> 122, 836, 478, 184, 1573, 1298, 773, 1472, 1087, 536, 2...
## $ `2002` <dbl> 151, 989, 512, 181, 1735, 1443, 744, 1639, 1275, 576, 2...
## $ `2003` <dbl> 135, 1041, 561, 190, 2155, 1560, 856, 1640, 1259, 762, ...
## $ `2004` <dbl> 115, 1034, 523, 173, 2255, 1538, 815, 1630, 1427, 696, ...
## $ `2005` <dbl> 125, 1211, 598, 196, 2823, 1692, 745, 1600, 1398, 903, ...
## $ `2006` <dbl> 155, 1617, 697, 203, 3276, 1793, 769, 1774, 1409, 925, ...
## $ `2007` <dbl> 133, 1839, 711, 171, 3608, 1936, 815, 1885, 1426, 1091,...
## $ `2008` <dbl> 133, 1887, 827, 211, 4750, 2031, 873, 1948, 1754, 1243,...
## $ `2009` <dbl> 149, 1868, 916, 191, 5345, 2166, 1003, 1969, 1784, 1391...
# Reune as variáveis de ano espalhadas pela base 'homic'
homic <- gather(homic, Ano, Homicidios, -Sigla, -Codigo,-Estado)
head(homic)
# ou da forma:
homic <- read_excel("homicidios_uf.xls")
homic <- gather(data = homic, key = Data, value = Homicidios, -Sigla, -Codigo, -Estado)
head(homic)
homic <- spread(homic, Data, Homicidios)
head(homic)
A função separate() separa uma coluna em várias outras ao dividir sempre que um caractere separador aparece.
A função unite() é o inverso de separete(), isto é, combina várias colunas em uma única.
z<-tibble(k=c("a,b,c","d,e,f","h,j")) %>%
separate(k,c("um","dois","três"))
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 1 rows [3].
df <- tibble(x = c("a",1,2,3), y = c("b", 1,3,5))
w<- df %>% unite("z", x:y, remove = FALSE)
head(w)
w %>% separate(z, c("x", "y"))