install.packages("tidyverse")
library(tidyverse)5 Aprendendo a manipular dados
Dentro do R, existem inúmeras formas de se importar um conjunto de dados. Os dados podem ter os mais diversos formatos (extensões):
csv, comma separated values;xlsx, formato do Excel (ao baixar a planilha);rds1, formato nativo doR;parquet;- muito mais!
1 É a forma mais recomendada, ao meu ver, de salvar objetos dentro do R. Um diferencial do .rds é que ele mantém a estrutura do objeto: ou seja, os atributos permanecem os mesmos.
5.1 Importando os pacotes no R
Como vimos, a primeira coisa a se fazer dentro de um script no R é fazer a importação dos pacotes (ou bibliotecas).
Um pacote é uma “caixa de ferramentas” extra que você instala no R para ganhar novas funcionalidades. Ele reúne códigos, dados e documentação em um único lugar. O termo biblioteca (library) refere-se ao local (a pasta no seu computador) onde esses pacotes ficam guardados.
Geralmente, precisamos, primeiramente, instalar um pacote com a função install.packages e então “carregá-lo” para nosso ambiente, com a função library. Carregar um pacote significa, basicamente, dizer ao R que queremos utilizar um conjunto de ferramentas na nossa sessão. Dito isso:
- Sempre instala-se um pacote novo. Este processo só é feito uma vez, ou seja, utiliza-se a função
install.packagesapenas quando ainda não possuímos o pacote em nossa máquina. - Após a primeira instalação, só é necessário instalar um pacote novamente caso ele tenha sido atualizado (lembra que a comunidade é ativa?). Caso não seja o caso, só é necessário “carregar” nosso pacote para a sessão.
Você pode ter notado que não utilizei as aspas (““) com a função library. Isso é opcional, você pode ou não utilizá-las.
O pacote pacman permite que você faça, ao mesmo tempo, a instalação e o carregamento do pacote, com a função p_load. Ao invés de fazer, por exemplo:
install.packages("tidyverse")
library(tidyverse)você pode fazer apenas:
p_load(tidyverse)Isso é particularmente útil quando você precisa importar muitos pacotes!
Caso você se esqueça de importar algum pacote, não se preocupe! É possível utilizar uma função de um pacote específico (desde que você tenha ele baixado no seu computador) sem precisar utilizar o library(nome_do_pacote) no começo do seu script. Ao especificar o nome do pacote e utilizar ::, como demonstrado na Figura 5.1, é possível acessar a função desejada:
Agora, basta carregamos os pacaotes de interesse
pacman::p_load(
tidyverse, # pacotão com vários pacotes core
rio, # pacote que facilita a leitura de qualquer formato
readxl, # pacote para ler no formato .xlsx
janitor # pacote para limpeza de dados
)O script de nossa aula está disponível aqui!
6 Ambientação e importação de pacotes
Feito isso, precisamos importar o conjunto de dados a serem trabalhados no encontro de hoje. Inicialmente, vamos trabalhar com um banco de dados de personagens de starwars. Esse banco está “embutido” no pacote dplyr. São bases de dados para fins didáticos!
dados <- dplyr::starwars7 Estatística descritiva e manipulação de dados
7.1 Utilizando o R Base
Feita a importação dos dados, podemos visualizá-los com a função head().
head(dados)# A tibble: 6 × 14
name height mass hair_color skin_color eye_color birth_year sex gender
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
1 Luke Sky… 172 77 blond fair blue 19 male mascu…
2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
4 Darth Va… 202 136 none white yellow 41.9 male mascu…
5 Leia Org… 150 49 brown light brown 19 fema… femin…
6 Owen Lars 178 120 brown, gr… light blue 52 male mascu…
# ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
# vehicles <list>, starships <list>
É possível, também, especificar quantas linhas queremos ver. Por exemplo, as 3 primeiras linhas:
head(dados, 3)# A tibble: 3 × 14
name height mass hair_color skin_color eye_color birth_year sex gender
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
1 Luke Sky… 172 77 blond fair blue 19 male mascu…
2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
# ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
# vehicles <list>, starships <list>
Se eu quiser saber quais são as últimas linhas do meu banco de dados, posso usar a função tail():
tail(dados)# A tibble: 6 × 14
name height mass hair_color skin_color eye_color birth_year sex gender
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
1 Tion Med… 206 80 none grey black NA male mascu…
2 Finn NA NA black dark dark NA male mascu…
3 Rey NA NA brown light hazel NA fema… femin…
4 Poe Dame… NA NA brown light brown NA male mascu…
5 BB8 NA NA none none black NA none mascu…
6 Captain … NA NA none none unknown NA fema… femin…
# ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
# vehicles <list>, starships <list>
Para acessar alguma coluna dentro do meu objeto dados, basta usar o $. Com o $, posso usar a função mean() para saber a média de alguma variável de interesse:
mean(dados$height)[1] NA
Recebemos uma resposta estranha: NA. Existem 03 classes especiais de objetos:: NA, NULL e NaN. NULL significa que eu estou tentando acessar um elemento que não existe, logo, ele é nulo. NaN significa “Not a Number”, que é autoexplicativo2. Já o NA significa “Not Available”, ou seja, não está disponível. O NA geralmente acontece quando fazemos medidas descritivas, como a média, e o nosso conjunto de dados tem algum valor faltante. Para contornar esse problema, usamos a seguinte opção dentro da função mean:
2 Se eu tento dividir 0 por 0, por exemplo, o resultado é NaN.
mean(dados$height, na.rm = TRUE)[1] 174.6049
na.rm significa, basicamente, “na remove”. Ou seja, remover os valores ausentes. Assim, consigo ver a média da altura dos personagens de Star Wars.
Também posso analisar o desvio padrão da altura dos personagens. O desvio padrão é uma medida de dispersão que mostra, em média, quanto os valores se distanciam da média de uma variável.
sd(dados$height, na.rm = TRUE)[1] 34.77416
7.2 Operadores lógicos
| Operador | Operação |
|---|---|
! |
Negação (não) |
& |
E (avalia elemento a elemento) |
| |
Ou (avalia elemento a elemento) |
< |
Menor |
<= |
Menor ou igual |
> |
Maior |
>= |
Maior ou igual |
!= |
Diferente |
&& |
E (avalia apenas o 1º elemento) |
|| |
Ou (avalia apenas o 1º elemento) |
Operadores lógicos no R são símbolos usados para fazer comparações e testar condições, retornando valores TRUE ou FALSE. É muito comum utilizarmos eles em filtros. Às vezes, queremos filtrar resultados dado uma condição específica. Veremos isso mais à frente.
7.3 Encadeando funções com o operador pipe |>
René Magritte tem uma pintura icônica, que inspirou um pacote no R. O pacote é chamado de {magrittr} e ele basicamente nos apresenta um conceito fantástico: o operador pipe. Basicamente, o pipe pega o lado esquerdo do seu código e alimenta o lado direito, encadeando as funções que você for utilizar.

Esse conceito ficará mais claro adiante, mas é importante saber da existência dele. Sempre que virmos um |> no nosso código, leremos ele como um “e então”. Pode ser que o pipe apareça para você como %>%, mas isso não faz muita diferença agora. O atalho para o operador pipe é CTRL + SHIFT + M.
7.4 Conhecendo o pacote {dplyr}
O {dplyr} é um dos principais pacotes do {tidyverse}, e é nele que passaremos a maior parte do tempo. Isso porque, quando trabalhamos com dados, a maior parte da energia que gastamos é em “limpar” os dados. O {dplyr} tem alguns “verbos” que são os mais utilizados. Vamos conhecê-los.
Se quiser, por exemplo, verificar a média da altura dos personagens de Star Wars por sexo, podemos fazer da seguinte forma:
dados |>
group_by(sex) |>
summarise(media_altura = mean(height, na.rm = TRUE))# A tibble: 5 × 2
sex media_altura
<chr> <dbl>
1 female 172.
2 hermaphroditic 175
3 male 179.
4 none 131.
5 <NA> 175
Lemos essa operação da seguinte forma: “pegue o objeto dados, e então agrupe-o por sexo, e então calcule a média para cada subgrupo, omitindo os valores ausentes”.
Sem o operador |>, teríamos de escrever o código da seguinte forma:
summarise(group_by(dados, sex), mean(height, na.rm = TRUE))# A tibble: 5 × 2
sex `mean(height, na.rm = TRUE)`
<chr> <dbl>
1 female 172.
2 hermaphroditic 175
3 male 179.
4 none 131.
5 <NA> 175
Concordamos que o |> é uma mão na roda, né?
Ainda, é possível filtrar informações de interesse primeiro. Por exemplo, se eu quero filtrar a altura de personagens cujo gênero é “masculine”, basta inserirmos a função filter().
dados |>
filter(gender == "masculine") |>
group_by(sex) |>
summarise(media_altura = mean(height, na.rm = TRUE))# A tibble: 3 × 2
sex media_altura
<chr> <dbl>
1 hermaphroditic 175
2 male 179.
3 none 140
Lemos essa operação da seguinte forma: “pegue o objeto dados, e então filtre as ocorrências cuja variável gender seja igual a”masculine”, e então agrupe-o por sexo, e então calcule a média para cada subgrupo, omitindo os valores ausentes”.
Se precisarmos de mais medidas para além da média da altura, podemos adicionar várias funções conforme precisarmos:
tabela_descritiva <- dados |>
group_by(sex) |>
summarise(media_altura = mean(height, na.rm = TRUE),
variancia_altura = var(height, na.rm = TRUE),
desvio_altura = sd(height, na.rm = TRUE),
n_obs = n()) # número de observações
tabela_descritiva# A tibble: 5 × 5
sex media_altura variancia_altura desvio_altura n_obs
<chr> <dbl> <dbl> <dbl> <int>
1 female 172. 253. 15.9 16
2 hermaphroditic 175 NA NA 1
3 male 179. 1297. 36.0 60
4 none 131. 2416. 49.1 6
5 <NA> 175 153. 12.4 4
A função var() me dá a variância da altura e a função n() me retorna o número de observações. Na nossa tabela descritiva, vimos que temos um grupo com apenas 01 indivíduo. Se quisermos, por exemplo, analisar os sexos que tem mais de um indivíduo, podemos filtrar:
tabela_descritiva2 <- tabela_descritiva |>
filter(n_obs > 1)
tabela_descritiva2# A tibble: 4 × 5
sex media_altura variancia_altura desvio_altura n_obs
<chr> <dbl> <dbl> <dbl> <int>
1 female 172. 253. 15.9 16
2 male 179. 1297. 36.0 60
3 none 131. 2416. 49.1 6
4 <NA> 175 153. 12.4 4
7.4.1 Filtrando NAs
É um pouco cansativo ficar utilizando o argumento na.rm = TRUE o tempo todo para filtrar os NAs a cada operação. Antes de eliminarmos quaisquer valores ausentes, é preciso conhecer nosso banco de dados para tomar esta decisão. Isso porque, como alguns cientistas sociais dizem, um não dado também é dado! Muitos valores ausentes podem indicar, por exemplo, como as pessoas estão registrando (no caso, deixando de registrar) as ocorrências. Muitos NAs pode ser sinal de mal preenchimento de informações.
Voltando para nosso conjunto de dados, vamos ver quantas linhas temos na coluna sex que são NA:
dados |>
filter(is.na(sex))# A tibble: 4 × 14
name height mass hair_color skin_color eye_color birth_year sex gender
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
1 Jek Tono… 180 110 brown fair blue NA <NA> <NA>
2 Gregar T… 185 85 black dark brown NA <NA> <NA>
3 Cordé 157 NA brown light brown NA <NA> <NA>
4 Sly Moore 178 48 none pale white NA <NA> <NA>
# ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
# vehicles <list>, starships <list>
São apenas 04 linhas. Podemos ignorálas. Refazendo a análise da primeira tabela descritiva:
dados |>
filter(!is.na(sex)) |>
group_by(sex) |>
summarise(media_altura = mean(height, na.rm = TRUE),
variancia_altura = var(height, na.rm = TRUE),
desvio_altura = sd(height, na.rm = TRUE),
n_obs = n()) |>
filter(n_obs > 1)# A tibble: 3 × 5
sex media_altura variancia_altura desvio_altura n_obs
<chr> <dbl> <dbl> <dbl> <int>
1 female 172. 253. 15.9 16
2 male 179. 1297. 36.0 60
3 none 131. 2416. 49.1 6
E se quisermos adicionar outra variável ao nosso grupo?
dados |>
filter(!is.na(sex)) |>
group_by(sex, eye_color) |>
summarise(media_altura = mean(height, na.rm = TRUE),
variancia_altura = var(height, na.rm = TRUE),
desvio_altura = sd(height, na.rm = TRUE),
n_obs = n()) |>
filter(n_obs > 1)`summarise()` has grouped output by 'sex'. You can override using the `.groups`
argument.
# A tibble: 12 × 6
# Groups: sex [3]
sex eye_color media_altura variancia_altura desvio_altura n_obs
<chr> <chr> <dbl> <dbl> <dbl> <int>
1 female black 196. 612. 24.7 2
2 female blue 167 118. 10.9 6
3 female brown 166. 209. 14.5 4
4 female hazel 178 NA NA 2
5 male black 182 1197 34.6 7
6 male blue 190 429. 20.7 12
7 male brown 167. 1657. 40.7 15
8 male orange 181. 1306. 36.1 7
9 male red 190. 0.5 0.707 2
10 male unknown 136 6498 80.6 2
11 male yellow 180. 2196. 46.9 9
12 none red 131 3571 59.8 3
Para essa primeira parte, está suficiente. Conhecemos as funções filter(), group_by() e summarise() do pacote {dplyr}.
8 Usando o dataset Gasoline
Primeiro, precisamos instalar o pacote plm.
install.packages("plm")Agora, vamos carregar os dados que estão dentro do pacote:
data(Gasoline, package = "plm")Este conjunto de dados nos dá informações sobre consumo de gasolina para 18 países, entre 1960 e 1978. As variáveis são:
| Variável | Descrição |
|---|---|
| country | Fator com 18 níveis (países) |
| year | Ano |
| lgaspcar | Logaritmo do consumo de gasolina por carro |
| lincomep | Logaritmo da renda real per capita |
| lrpmg | Logaritmo do preço real da gasolina |
| lcarpcap | Logaritmo do estoque de carros per capita |
Quando carregamos este conjunto de dados, ele pertence à uma classe chamada data.frame. O R possui uma classe diferente e especial para conjunto de dados, que apresenta um melhor “print” no console, chamada tibble. Para convertemos este conjunto de dados (no formato data.frame) para tibble, executamos a seguinte operação:
gasoline <- as_tibble(Gasoline)O tibble no
Ré uma versão moderna e aprimorada dodata.frametradicional, projetada para facilitar a manipulação e visualização de dados dentro do ecossistema Tidyverse. Ele é conhecido por não alterar tipos de dados automaticamente, imprimir apenas as primeiras 10 linhas e colunas ajustadas à tela, tornando a exploração de conjuntos de dados grandes mais eficiente e organizada.
Adicionalmente, quero deixar todas os países da coluna country com letras minúsculas. Para isso:
gasoline <- gasoline |>
mutate(country = tolower(country))E se eu quiser filtrar os dados somente para o ano de 1972? Muito simples com a função filter(), sem utilizar o |>.
filter(gasoline, year == 1972)# A tibble: 18 × 6
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1972 4.13 -5.98 -0.596 -8.54
2 belgium 1972 3.91 -5.71 -0.311 -8.36
3 canada 1972 4.89 -5.44 -1.10 -7.99
4 denmark 1972 4.08 -5.65 -0.499 -8.33
5 france 1972 3.85 -5.70 -0.408 -8.22
6 germany 1972 3.93 -5.72 -0.718 -8.24
7 greece 1972 4.80 -6.35 -0.120 -10.3
8 ireland 1972 4.27 -6.31 -0.424 -8.82
9 italy 1972 3.63 -6.21 -0.215 -8.38
10 japan 1972 4.22 -5.93 -0.521 -9.05
11 netherla 1972 3.92 -5.79 -0.319 -8.38
12 norway 1972 4.08 -5.66 -0.260 -8.51
13 spain 1972 3.89 -5.46 0.537 -9.27
14 sweden 1972 3.98 -7.74 -2.77 -8.10
15 switzerl 1972 4.26 -5.81 -0.940 -8.30
16 turkey 1972 5.58 -7.08 -0.546 -12.2
17 u.k. 1972 3.99 -5.97 -0.528 -8.36
18 u.s.a. 1972 4.85 -5.35 -1.33 -7.68
Mas, é bom nos acostumarmos com o operador pipe, portanto:
gasoline |>
filter(year == 1972)# A tibble: 18 × 6
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1972 4.13 -5.98 -0.596 -8.54
2 belgium 1972 3.91 -5.71 -0.311 -8.36
3 canada 1972 4.89 -5.44 -1.10 -7.99
4 denmark 1972 4.08 -5.65 -0.499 -8.33
5 france 1972 3.85 -5.70 -0.408 -8.22
6 germany 1972 3.93 -5.72 -0.718 -8.24
7 greece 1972 4.80 -6.35 -0.120 -10.3
8 ireland 1972 4.27 -6.31 -0.424 -8.82
9 italy 1972 3.63 -6.21 -0.215 -8.38
10 japan 1972 4.22 -5.93 -0.521 -9.05
11 netherla 1972 3.92 -5.79 -0.319 -8.38
12 norway 1972 4.08 -5.66 -0.260 -8.51
13 spain 1972 3.89 -5.46 0.537 -9.27
14 sweden 1972 3.98 -7.74 -2.77 -8.10
15 switzerl 1972 4.26 -5.81 -0.940 -8.30
16 turkey 1972 5.58 -7.08 -0.546 -12.2
17 u.k. 1972 3.99 -5.97 -0.528 -8.36
18 u.s.a. 1972 4.85 -5.35 -1.33 -7.68
Também é possível filtrar mais de uma condição. Para isso, podemos usar o operador %in%:
gasoline %>%
filter(year %in% seq(1969, 1973)) # sequência de anos entre 1969 a 1973# A tibble: 90 × 6
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1969 4.05 -6.15 -0.559 -8.79
2 austria 1970 4.08 -6.08 -0.597 -8.73
3 austria 1971 4.11 -6.04 -0.654 -8.64
4 austria 1972 4.13 -5.98 -0.596 -8.54
5 austria 1973 4.20 -5.90 -0.594 -8.49
6 belgium 1969 3.85 -5.86 -0.355 -8.52
7 belgium 1970 3.87 -5.80 -0.378 -8.45
8 belgium 1971 3.87 -5.76 -0.399 -8.41
9 belgium 1972 3.91 -5.71 -0.311 -8.36
10 belgium 1973 3.90 -5.64 -0.373 -8.31
# ℹ 80 more rows
Ou
gasoline %>%
filter(year %in% 1969:1973) # sem a função seq()# A tibble: 90 × 6
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1969 4.05 -6.15 -0.559 -8.79
2 austria 1970 4.08 -6.08 -0.597 -8.73
3 austria 1971 4.11 -6.04 -0.654 -8.64
4 austria 1972 4.13 -5.98 -0.596 -8.54
5 austria 1973 4.20 -5.90 -0.594 -8.49
6 belgium 1969 3.85 -5.86 -0.355 -8.52
7 belgium 1970 3.87 -5.80 -0.378 -8.45
8 belgium 1971 3.87 -5.76 -0.399 -8.41
9 belgium 1972 3.91 -5.71 -0.311 -8.36
10 belgium 1973 3.90 -5.64 -0.373 -8.31
# ℹ 80 more rows
Ainda, é possível utilizar a função auxiliadora3 between():
3 Como o nome sugere, funções auxiliadores ajudam as funções principais. É importante notar que é possível usar funções dentro de funções.
gasoline %>%
filter(between(year, 1969, 1973))# A tibble: 90 × 6
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1969 4.05 -6.15 -0.559 -8.79
2 austria 1970 4.08 -6.08 -0.597 -8.73
3 austria 1971 4.11 -6.04 -0.654 -8.64
4 austria 1972 4.13 -5.98 -0.596 -8.54
5 austria 1973 4.20 -5.90 -0.594 -8.49
6 belgium 1969 3.85 -5.86 -0.355 -8.52
7 belgium 1970 3.87 -5.80 -0.378 -8.45
8 belgium 1971 3.87 -5.76 -0.399 -8.41
9 belgium 1972 3.91 -5.71 -0.311 -8.36
10 belgium 1973 3.90 -5.64 -0.373 -8.31
# ℹ 80 more rows
Também é possível selecionar anos não consecutivos:
gasoline %>%
filter(year %in% c(1969, 1973, 1977))# A tibble: 54 × 6
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1969 4.05 -6.15 -0.559 -8.79
2 austria 1973 4.20 -5.90 -0.594 -8.49
3 austria 1977 3.93 -5.83 -0.422 -8.25
4 belgium 1969 3.85 -5.86 -0.355 -8.52
5 belgium 1973 3.90 -5.64 -0.373 -8.31
6 belgium 1977 3.85 -5.56 -0.432 -8.14
7 canada 1969 4.86 -5.56 -1.04 -8.10
8 canada 1973 4.90 -5.41 -1.13 -7.94
9 canada 1977 4.81 -5.34 -1.07 -7.77
10 denmark 1969 4.17 -5.72 -0.407 -8.47
# ℹ 44 more rows
8.1 Usando a função select()
Enquanto a função filter() é utilizada para manter ou descartar as linhas do nosso conjunto de dados, a função select() nos permite selecionar colunas inteiras.
Para manter colunas, podemos utilizar:
gasoline %>%
select(country, year, lrpmg)# A tibble: 342 × 3
country year lrpmg
<chr> <int> <dbl>
1 austria 1960 -0.335
2 austria 1961 -0.351
3 austria 1962 -0.380
4 austria 1963 -0.414
5 austria 1964 -0.445
6 austria 1965 -0.497
7 austria 1966 -0.467
8 austria 1967 -0.506
9 austria 1968 -0.522
10 austria 1969 -0.559
# ℹ 332 more rows
Para descartálas, utilizamos:
gasoline %>%
select(-country, -year, -lrpmg)# A tibble: 342 × 3
lgaspcar lincomep lcarpcap
<dbl> <dbl> <dbl>
1 4.17 -6.47 -9.77
2 4.10 -6.43 -9.61
3 4.07 -6.41 -9.46
4 4.06 -6.37 -9.34
5 4.04 -6.32 -9.24
6 4.03 -6.29 -9.12
7 4.05 -6.25 -9.02
8 4.05 -6.23 -8.93
9 4.05 -6.21 -8.85
10 4.05 -6.15 -8.79
# ℹ 332 more rows
Ainda, é possível renomeá-las diretamente com a função select():
gasoline %>%
select(country, date = year, lrpmg)# A tibble: 342 × 3
country date lrpmg
<chr> <int> <dbl>
1 austria 1960 -0.335
2 austria 1961 -0.351
3 austria 1962 -0.380
4 austria 1963 -0.414
5 austria 1964 -0.445
6 austria 1965 -0.497
7 austria 1966 -0.467
8 austria 1967 -0.506
9 austria 1968 -0.522
10 austria 1969 -0.559
# ℹ 332 more rows
A função rename() faz exatamente a mesma coisa. Entretanto, ele não faz nenhum tipo de seleção, apenas renomea a coluna de interesse.
gasoline %>%
rename(date = year)# A tibble: 342 × 6
country date lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1960 4.17 -6.47 -0.335 -9.77
2 austria 1961 4.10 -6.43 -0.351 -9.61
3 austria 1962 4.07 -6.41 -0.380 -9.46
4 austria 1963 4.06 -6.37 -0.414 -9.34
5 austria 1964 4.04 -6.32 -0.445 -9.24
6 austria 1965 4.03 -6.29 -0.497 -9.12
7 austria 1966 4.05 -6.25 -0.467 -9.02
8 austria 1967 4.05 -6.23 -0.506 -8.93
9 austria 1968 4.05 -6.21 -0.522 -8.85
10 austria 1969 4.05 -6.15 -0.559 -8.79
# ℹ 332 more rows
É possível utilizar a função select() para reordenar as colunas. Eu quero, por exemplo, que minhas três primeiras colunas do conjunto de dados sejam year, country e lrpmg, nesta ordem:
gasoline %>%
select(year, country, lrpmg, everything())# A tibble: 342 × 6
year country lrpmg lgaspcar lincomep lcarpcap
<int> <chr> <dbl> <dbl> <dbl> <dbl>
1 1960 austria -0.335 4.17 -6.47 -9.77
2 1961 austria -0.351 4.10 -6.43 -9.61
3 1962 austria -0.380 4.07 -6.41 -9.46
4 1963 austria -0.414 4.06 -6.37 -9.34
5 1964 austria -0.445 4.04 -6.32 -9.24
6 1965 austria -0.497 4.03 -6.29 -9.12
7 1966 austria -0.467 4.05 -6.25 -9.02
8 1967 austria -0.506 4.05 -6.23 -8.93
9 1968 austria -0.522 4.05 -6.21 -8.85
10 1969 austria -0.559 4.05 -6.15 -8.79
# ℹ 332 more rows
A função everything() é uma função auxiliadora, como notamos. Ainda, existem outras funções, como por exemplo starts_with e ends_with. Se eu quiser, por exemplo, selecionar apenas as colunas cujo nome começam com “l”?
gasoline %>%
select(starts_with("l"))# A tibble: 342 × 4
lgaspcar lincomep lrpmg lcarpcap
<dbl> <dbl> <dbl> <dbl>
1 4.17 -6.47 -0.335 -9.77
2 4.10 -6.43 -0.351 -9.61
3 4.07 -6.41 -0.380 -9.46
4 4.06 -6.37 -0.414 -9.34
5 4.04 -6.32 -0.445 -9.24
6 4.03 -6.29 -0.497 -9.12
7 4.05 -6.25 -0.467 -9.02
8 4.05 -6.23 -0.506 -8.93
9 4.05 -6.21 -0.522 -8.85
10 4.05 -6.15 -0.559 -8.79
# ℹ 332 more rows
ends_with funciona de maneira similar, dá para pegar a ideia. Outra função auxiliadora interessante é a contains():
gasoline %>%
select(country, year, contains("car"))# A tibble: 342 × 4
country year lgaspcar lcarpcap
<chr> <int> <dbl> <dbl>
1 austria 1960 4.17 -9.77
2 austria 1961 4.10 -9.61
3 austria 1962 4.07 -9.46
4 austria 1963 4.06 -9.34
5 austria 1964 4.04 -9.24
6 austria 1965 4.03 -9.12
7 austria 1966 4.05 -9.02
8 austria 1967 4.05 -8.93
9 austria 1968 4.05 -8.85
10 austria 1969 4.05 -8.79
# ℹ 332 more rows
É possível encontrar uma lista de funções auxiliadoras na documentação do pacote. A documentação é uma espécie de manual, onde os desenvolvedores dos pacotes apresentam as principais funções, argumentos e exemplos de uso. Basta pesquisar por nome do pacote + R no Google que você acha as informações oficiais com bastante facilidade. A documentação do pacote {dplyr} é facilmente encontrada. ]
Outro verbo/função similar ao select() é o pull(). Como o nome sugere, ele puxa as informações de uma coluna específica. Comparativamente:
gasoline %>%
select(lrpmg)# A tibble: 342 × 1
lrpmg
<dbl>
1 -0.335
2 -0.351
3 -0.380
4 -0.414
5 -0.445
6 -0.497
7 -0.467
8 -0.506
9 -0.522
10 -0.559
# ℹ 332 more rows
gasoline %>%
pull(lrpmg) %>%
head() # usando o head() porque temos muitos elementos neste conjunto de daods[1] -0.3345476 -0.3513276 -0.3795177 -0.4142514 -0.4453354 -0.4970607
8.2 Agrupando informações com group_by()
A função group_by() facilita a computação de estatísticas descritivas por grupos. Agrupando os dados por país:
gasoline %>%
group_by(country)# A tibble: 342 × 6
# Groups: country [18]
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1960 4.17 -6.47 -0.335 -9.77
2 austria 1961 4.10 -6.43 -0.351 -9.61
3 austria 1962 4.07 -6.41 -0.380 -9.46
4 austria 1963 4.06 -6.37 -0.414 -9.34
5 austria 1964 4.04 -6.32 -0.445 -9.24
6 austria 1965 4.03 -6.29 -0.497 -9.12
7 austria 1966 4.05 -6.25 -0.467 -9.02
8 austria 1967 4.05 -6.23 -0.506 -8.93
9 austria 1968 4.05 -6.21 -0.522 -8.85
10 austria 1969 4.05 -6.15 -0.559 -8.79
# ℹ 332 more rows
Não parece que mudou muita coisa, mas, se observamos a segunda linha do output, veremos que:
## # Groups: country [18]Isso significa que toda análise levará estes grupos em conta. Como vimos anteriormente com o starwars, é possível agrupar por mais de uma variável:
gasoline %>%
group_by(country, year)# A tibble: 342 × 6
# Groups: country, year [342]
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1960 4.17 -6.47 -0.335 -9.77
2 austria 1961 4.10 -6.43 -0.351 -9.61
3 austria 1962 4.07 -6.41 -0.380 -9.46
4 austria 1963 4.06 -6.37 -0.414 -9.34
5 austria 1964 4.04 -6.32 -0.445 -9.24
6 austria 1965 4.03 -6.29 -0.497 -9.12
7 austria 1966 4.05 -6.25 -0.467 -9.02
8 austria 1967 4.05 -6.23 -0.506 -8.93
9 austria 1968 4.05 -6.21 -0.522 -8.85
10 austria 1969 4.05 -6.15 -0.559 -8.79
# ℹ 332 more rows
E também é possível desagrupar, com a função ungroup(). Basicamente, o group_by “marca” a tabela para que os cálculos sejam feitos por grupo, e o ungroup() volta para que você trabalhe com a tabela como um todo.
gasoline %>%
group_by(country, year) %>%
ungroup()# A tibble: 342 × 6
country year lgaspcar lincomep lrpmg lcarpcap
<chr> <int> <dbl> <dbl> <dbl> <dbl>
1 austria 1960 4.17 -6.47 -0.335 -9.77
2 austria 1961 4.10 -6.43 -0.351 -9.61
3 austria 1962 4.07 -6.41 -0.380 -9.46
4 austria 1963 4.06 -6.37 -0.414 -9.34
5 austria 1964 4.04 -6.32 -0.445 -9.24
6 austria 1965 4.03 -6.29 -0.497 -9.12
7 austria 1966 4.05 -6.25 -0.467 -9.02
8 austria 1967 4.05 -6.23 -0.506 -8.93
9 austria 1968 4.05 -6.21 -0.522 -8.85
10 austria 1969 4.05 -6.15 -0.559 -8.79
# ℹ 332 more rows
8.3 Resumir estatísticas com summarise()
Passado o básico, vamos avançar. Se eu quero computar o consume médio de gasolina por cada país, para todo o período, fazemos:
gasoline %>%
group_by(country) %>%
summarise(mean(lgaspcar))# A tibble: 18 × 2
country `mean(lgaspcar)`
<chr> <dbl>
1 austria 4.06
2 belgium 3.92
3 canada 4.86
4 denmark 4.19
5 france 3.82
6 germany 3.89
7 greece 4.88
8 ireland 4.23
9 italy 3.73
10 japan 4.70
11 netherla 4.08
12 norway 4.11
13 spain 4.06
14 sweden 4.01
15 switzerl 4.24
16 turkey 5.77
17 u.k. 3.98
18 u.s.a. 4.82
Como vimos com o starwars, é possível renomear o nome da coluna da média que apareceu anteriormente. Para isso:
gasoline %>%
group_by(country) %>%
summarise(mean_gaspcar = mean(lgaspcar))# A tibble: 18 × 2
country mean_gaspcar
<chr> <dbl>
1 austria 4.06
2 belgium 3.92
3 canada 4.86
4 denmark 4.19
5 france 3.82
6 germany 3.89
7 greece 4.88
8 ireland 4.23
9 italy 3.73
10 japan 4.70
11 netherla 4.08
12 norway 4.11
13 spain 4.06
14 sweden 4.01
15 switzerl 4.24
16 turkey 5.77
17 u.k. 3.98
18 u.s.a. 4.82
Além disso, podemos filtrar as ocorrências para um país de interesse:
gasoline %>%
group_by(country) %>%
summarise(mean_gaspcar = mean(lgaspcar)) %>%
filter(country == "france")# A tibble: 1 × 2
country mean_gaspcar
<chr> <dbl>
1 france 3.82
Com a função summarise(), posso computar várias estatísticas de uma vez:
gasoline %>%
group_by(country) %>%
summarise(mean_gaspcar = mean(lgaspcar),
sd_gaspcar = sd(lgaspcar),
max_gaspcar = max(lgaspcar),
min_gaspcar = min(lgaspcar))# A tibble: 18 × 5
country mean_gaspcar sd_gaspcar max_gaspcar min_gaspcar
<chr> <dbl> <dbl> <dbl> <dbl>
1 austria 4.06 0.0693 4.20 3.92
2 belgium 3.92 0.103 4.16 3.82
3 canada 4.86 0.0262 4.90 4.81
4 denmark 4.19 0.158 4.50 4.00
5 france 3.82 0.0499 3.91 3.75
6 germany 3.89 0.0239 3.93 3.85
7 greece 4.88 0.255 5.38 4.48
8 ireland 4.23 0.0437 4.33 4.16
9 italy 3.73 0.220 4.05 3.38
10 japan 4.70 0.684 6.00 3.95
11 netherla 4.08 0.286 4.65 3.71
12 norway 4.11 0.123 4.44 3.96
13 spain 4.06 0.317 4.75 3.62
14 sweden 4.01 0.0364 4.07 3.91
15 switzerl 4.24 0.102 4.44 4.05
16 turkey 5.77 0.329 6.16 5.14
17 u.k. 3.98 0.0479 4.10 3.91
18 u.s.a. 4.82 0.0219 4.86 4.79
E se quisermos “salvar” essas operações, basta atribuir a um objeto4:
4 Lembrando que o sinal de atribuição mais apropriado é o <-. Para fazê-lo, o atalho é ALT - (alt menos)
desc_gasoline <- gasoline %>%
group_by(country) %>%
summarise(mean_gaspcar = mean(lgaspcar),
sd_gaspcar = sd(lgaspcar),
max_gaspcar = max(lgaspcar),
min_gaspcar = min(lgaspcar))Questão: qual país tem o maior consumo médio de gasolina?
desc_gasoline %>%
filter(max(mean_gaspcar) == mean_gaspcar)# A tibble: 1 × 5
country mean_gaspcar sd_gaspcar max_gaspcar min_gaspcar
<chr> <dbl> <dbl> <dbl> <dbl>
1 turkey 5.77 0.329 6.16 5.14
A função max(mean_gaspcar) calcula o maior valor da média de consumo de gasolina. Depois, fazemos uma comparação lógica para verificar se o valor naquela linha é igual ao valor máximo da coluna. Eu, particularmente, acho assim mais complicado de entender. Alternativametne, podemos usar:
desc_gasoline %>%
slice_max(mean_gaspcar) # mais direto e reto!# A tibble: 1 × 5
country mean_gaspcar sd_gaspcar max_gaspcar min_gaspcar
<chr> <dbl> <dbl> <dbl> <dbl>
1 turkey 5.77 0.329 6.16 5.14
Ou, também:
desc_gasoline %>%
slice(which.max(mean_gaspcar))# A tibble: 1 × 5
country mean_gaspcar sd_gaspcar max_gaspcar min_gaspcar
<chr> <dbl> <dbl> <dbl> <dbl>
1 turkey 5.77 0.329 6.16 5.14
A Túrquia tem o maior consumo médio de gasolina. E o valor mínimo?
desc_gasoline %>%
slice_min(mean_gaspcar) # mais direto e reto!# A tibble: 1 × 5
country mean_gaspcar sd_gaspcar max_gaspcar min_gaspcar
<chr> <dbl> <dbl> <dbl> <dbl>
1 italy 3.73 0.220 4.05 3.38
8.4 Adicionando colunas com o mutate() e transmute()
A função mutate() adiciona ou transforma uma coluna num conjunto de dados. Por exemplo:
gasoline %>%
group_by(country) %>%
mutate(n())# A tibble: 342 × 7
# Groups: country [18]
country year lgaspcar lincomep lrpmg lcarpcap `n()`
<chr> <int> <dbl> <dbl> <dbl> <dbl> <int>
1 austria 1960 4.17 -6.47 -0.335 -9.77 19
2 austria 1961 4.10 -6.43 -0.351 -9.61 19
3 austria 1962 4.07 -6.41 -0.380 -9.46 19
4 austria 1963 4.06 -6.37 -0.414 -9.34 19
5 austria 1964 4.04 -6.32 -0.445 -9.24 19
6 austria 1965 4.03 -6.29 -0.497 -9.12 19
7 austria 1966 4.05 -6.25 -0.467 -9.02 19
8 austria 1967 4.05 -6.23 -0.506 -8.93 19
9 austria 1968 4.05 -6.21 -0.522 -8.85 19
10 austria 1969 4.05 -6.15 -0.559 -8.79 19
# ℹ 332 more rows
Também é possível renomear a variável dentro da função mutate():
gasoline %>%
group_by(country) %>%
mutate(count = n())# A tibble: 342 × 7
# Groups: country [18]
country year lgaspcar lincomep lrpmg lcarpcap count
<chr> <int> <dbl> <dbl> <dbl> <dbl> <int>
1 austria 1960 4.17 -6.47 -0.335 -9.77 19
2 austria 1961 4.10 -6.43 -0.351 -9.61 19
3 austria 1962 4.07 -6.41 -0.380 -9.46 19
4 austria 1963 4.06 -6.37 -0.414 -9.34 19
5 austria 1964 4.04 -6.32 -0.445 -9.24 19
6 austria 1965 4.03 -6.29 -0.497 -9.12 19
7 austria 1966 4.05 -6.25 -0.467 -9.02 19
8 austria 1967 4.05 -6.23 -0.506 -8.93 19
9 austria 1968 4.05 -6.21 -0.522 -8.85 19
10 austria 1969 4.05 -6.15 -0.559 -8.79 19
# ℹ 332 more rows
Ainda, é possível fazer qualquer outra operação:
gasoline |>
group_by(country) |>
mutate(consumo_renda = lgaspcar / lincomep)# A tibble: 342 × 7
# Groups: country [18]
country year lgaspcar lincomep lrpmg lcarpcap consumo_renda
<chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
1 austria 1960 4.17 -6.47 -0.335 -9.77 -0.645
2 austria 1961 4.10 -6.43 -0.351 -9.61 -0.638
3 austria 1962 4.07 -6.41 -0.380 -9.46 -0.636
4 austria 1963 4.06 -6.37 -0.414 -9.34 -0.637
5 austria 1964 4.04 -6.32 -0.445 -9.24 -0.639
6 austria 1965 4.03 -6.29 -0.497 -9.12 -0.641
7 austria 1966 4.05 -6.25 -0.467 -9.02 -0.647
8 austria 1967 4.05 -6.23 -0.506 -8.93 -0.650
9 austria 1968 4.05 -6.21 -0.522 -8.85 -0.652
10 austria 1969 4.05 -6.15 -0.559 -8.79 -0.658
# ℹ 332 more rows
A função transmute() opera da mesma forma que o mutate, mas retorna apenas a variável criada:
gasoline |>
group_by(country) |>
transmute(consumo_renda = lgaspcar / lincomep)# A tibble: 342 × 2
# Groups: country [18]
country consumo_renda
<chr> <dbl>
1 austria -0.645
2 austria -0.638
3 austria -0.636
4 austria -0.637
5 austria -0.639
6 austria -0.641
7 austria -0.647
8 austria -0.650
9 austria -0.652
10 austria -0.658
# ℹ 332 more rows
Exemplo gráfico:
library(dplyr)
library(ggplot2)
gasoline %>%
ggplot(aes(x = year, y = lgaspcar, color = country, group = country)) +
geom_line() +
labs(
title = "Consumo de Gasolina por Carro (log) ao longo do tempo",
x = "Ano",
y = "Log do consumo de gasolina por carro",
color = "País"
) +
theme_classic() +
theme(
legend.position = "right",
legend.title = element_text(face = "bold"),
panel.grid.minor = element_blank()
)