-
Notifications
You must be signed in to change notification settings - Fork 2
/
Aula 3 - Manipulando quase qualquer base.Rmd
558 lines (429 loc) · 21.8 KB
/
Aula 3 - Manipulando quase qualquer base.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
---
title: "Aula 4 - Manipulando quase qualquer base"
output: html_document
date: "2023-01-29"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Entendendo datasets Wide e Long
Vamos carregar o tidyverse, já que ele contém os principais pacotes que veremos nessa aula, a saber, tidyr, tibble, dplyr e ggplot
```{r}
library(tidyverse)
```
Para compreender o que são datasets long e wide vamos usar os datasets do pacote {tidyr}. Um dataset pode apresentar e organizar dados de multiplas maneiras. Vejamos o dataset abaixo.
O dataset abaixo é chamado de dataset *tidy*, ou organizado.
```{r}
tidyr::table1
```
Já os datasets abaixo está no formato wide. Observem que o dataset table4a mede a informações de cases, e o dataset table4b mede as informações de population. Datasets wide são conhecidos por distribuirem suas informações horizontalmente. Nesse caso temos as informações de casos e de população medidas por ano em colunas.
```{r}
tidyr::table4a
```
```{r}
tidyr::table4b
```
Vejam agora o dataset table2. Ele é um dataset long, onde temos variáveis empilhadas em colunas. A coluna type mede o tipo de variável, nesse caso temos as variáveis cases e population, que no dataset table1 tem suas próprias colunas, empilhadas na coluna type, e os seus valores empilhados na coluna count. Outro característica de datasets long é que eles tem menos colunas e mais linhas que datasets tidy.
```{r}
tidyr::table2
```
Já o dataset table1 é chamado de tidy, ou organizado já que: 1. Cada variável tem sua própria coluna; 2. Cada observação tem sua própria linha; 3. Cada valor está em sua própria celula.
E como transformar um dataset para um formato tidy? Uma das possibilidades e a mais indicada é usando o pivoting. Voltemos a tablea4a.
```{r}
tidyr::table4a
```
Como podemos tranformar esses dados em tidy data, ou dados organizados? A resposta é usando as funções de pivoting. Seja de pivot_longer() que transforma os dados em formato long, ou seja usando a pivot_wider que transforma os dados em formato wide.
```{r}
tidyr::table4a %>% # dataset em formato wide
tidyr::pivot_longer( #Função que transforma os dados em formato long
c(`1999`, `2000`), #Indicamos as colunas que serão empilhadas
names_to = "year", #Indicamos a coluna que receberá valor de classificação
values_to = "cases" #Indicamos a coluna que receberá os valores
)
```
Sempre que quisermos organizar um dataset em um formato long, usaremos a função tidyr:: pivot_longer.
```{r}
tidyr::table4b %>% #dataset em formato wide
tidyr::pivot_longer( #Função que transforma os dados em formato long
c(`1999`, `2000`), #Indicamos as colunas que serão empilhadas
names_to = "year", #Indicamos a coluna que receberá valor de classificação
values_to = "population"#Indicamos a coluna que receberá os valores
)
```
Um outro exemplo de datasets que não estão em formato tidy é o dataset table2. Nesse caso não temos uma variável para cada coluna, já que a coluna type mede o nome da variável e a coluna count o valor observado da variável.
```{r}
tidyr::table2
```
Para transformar esse dataset no formato tidy usamos a função tidyr:: pivot_longer().
```{r}
tidyr::table2 %>% #dataset n formato long
tidyr::pivot_wider( # função que transforma os dados no formato wide
names_from = type, # coluna que empilha o nome das variáveis
values_from = count # coluna que empilha o valor observado das variáveis
)
```
### Revisão
Importe o dataset dados_b3_2010_2022.csv; Remova a 1° coluna; Transforme o dataset para o formato tidy;
```{r}
dados_b3_2010_2022.csv <- readr::read_csv("https://raw.githubusercontent.com/BaruqueRodrigues/Curso-de-R/master/dados/dados_b3_2010_2022.csv")
```
```{r}
dados_b3_2010_2022.csv %>%
select(-1) %>%
tidyr::pivot_wider(names_from = ticker,
values_from = ret_adjusted_prices)
```
Transforme o dataset abaixo para o formato tidy()
```{r}
people <- tribble(
~name, ~names, ~values,
#-----------------|--------|------
"Phillip Woods", "age", 45,
"Phillip Woods", "height", 186,
"Phillip Woods", "age", 50,
"Jessica Cordero", "age", 37,
"Jessica Cordero", "height", 156
)
```
```{r}
people %>%
tidyr::pivot_wider(names_from = names,
values_from = values)
```
O dataset acima contém colunas com valores listados. Guarde essa informação, em breve veremos como lidar com esses dados.
## Separando e Juntando dados
Alguns datasets tem particularidades,onde os valores das colunas ficam aninhandos a função tidyr::separate()
```{r}
tidyr::table3
```
Veja a coluna rate da table3. Ela contém os valores de cases e population, entretanto essa coluna contém 2 variáveis diferentes, e para transformarmos esses dados em formato tidy precisamos separar essas colunas.
```{r}
tidyr::table3 %>% # dataset com uma coluna que precisa ser separado
tidyr::separate( # função que irá separar a coluna
rate, # coluna que será separada
sep = "/", # argumento que deve ser separado
into = c("cases", "population") # nome das colunas que serão separadas
)
```
Podemos usar a função separate de diversar formas, de maneira quase ilimitada, como o caso abaixo que separamos a coluna year. no segundo digito
```{r}
tidyr::table3 %>% #dataset com uma coluna que precisa ser separado
tidyr::separate(# função que irá separar a coluna
year, # coluna que será separada
into = c("century", "year"), # nome das colunas que serão separadas
sep = 2 # argumento que deve ser separado
)
```
Caso tenhamos que juntar valores que estão separados em colunas diferente podemos usar a função tidyr::unite() que funciona no inverso da função separate(). Observem o dataset abaixo. ele tem a coluna century e year, entretanto essas medidas são pouco usais, geralmente temos essas duas unidades juntas.
```{r}
tidyr::table5
```
Para juntar os dados utilizaremos a função tidyr::unite()
```{r}
table5 %>% # dataset que terá colunas ajuntadas
unite( # função que juntará as colunas
ano_completo, # nova coluna
century, year, #colunas que serão juntas
sep = "" #separador
)
```
\### Revisão
Importe o dataset pedidos. Remova a primeira linha e transforme ele em um formato tidy onde a descrição por pedido seja separado em multiplos itens e o dataset tenha um formato long.
```{r}
pedidos <- readr::read_csv(
"https://raw.githubusercontent.com/BaruqueRodrigues/Curso-de-R/master/dados/pedidos.csv")
```
A resolução
```{r}
pedidos %>%
select(-1) %>% # removo a primeira coluna
separate(descricao_por_pedido,
into = c("item_1", #separo a coluna em 5 itens
"item_2",
"item_3",
"item_4",
"item_5"),
sep = ","#indico que o separador é uma virgula
) %>%
#Transformo os dados em um formato long
pivot_longer(c(item_1:item_5),
names_to = "item_pedido",
values_to = "desc_pedido")
```
### Lidando com missing data
Existem 3 funções poderosas que podemos usar para lidar com dados ausentes são elas drop_na() que remove os casos com o valor NA; fill() que preenche valores NA com os valores númericos mais próximos ; replace_na() que substitui os valores NA por valores determinados pelo operador.
Vamos usar o dataset pedidos usado na revisão para exemplificar o uso de algumas dessas funções.
```{r}
pedidos_final <- pedidos %>%
select(-1) %>%
separate(descricao_por_pedido,
into = c("item_1",
"item_2",
"item_3",
"item_4",
"item_5"),
sep = ",") %>%
pivot_longer(c(item_1:item_5),
names_to = "item_pedido",
values_to = "desc_pedido")
pedidos_final
```
A função drop_na() lida com dados ausentes removendo eles do dataset
```{r}
pedidos_final %>%
drop_na()
```
A função fill() vai preencher os valores ausentes com um valor da coluna usando o valor mais próximo do dado ausente. Entretanto só funciona com dados numéricos
```{r}
sales <- tibble::tribble(
~quarter, ~year, ~sales,
"Q1", 2000, 66013,
"Q2", NA, 69182,
"Q3", NA, 53175,
"Q4", NA, 21001,
"Q1", 2001, 46036,
"Q2", NA, 58842,
"Q3", NA, 44568,
"Q4", NA, 50197,
"Q1", 2002, 39113,
"Q2", NA, 41668,
"Q3", NA, 30144,
"Q4", NA, 52897,
"Q1", 2004, 32129,
"Q2", NA, 67686,
"Q3", NA, 31768,
"Q4", NA, 49094
)
sales
```
```{r}
sales %>%
fill(year)
```
A função replace_na() vai substituir os dados ausentes por valores especificados.
```{r}
pedidos_final %>%
replace_na(# função que vai substituir NA pelo valor desejado
list( # usamos a função list pois podemos inserir várias colunas
desc_pedido = "item_ausente" #indicando o substituto por coluna
)
)
```
\## Transformando vetores de texto em datasets
Muitas vezes recebemos dados em formato de lista, ou formato textual e precisamos transforma-los para um formato de dataset. Uma das formas mais simples e robustas de fazer essa transformação é usando a função tibble::enframe(). Exemplificaremos usando os dados abaixo.
```{r}
dados_lista <- list(times = c("flamengo", "fluminense", "vasco", "botafogo"),
titulos_liberta = c(2, "virgem das americas", 1, "bairro"),
copas_br = c(3, 1, 1, "bairro"),
brasileiros = c(8,4,4,1))
```
```{r}
dados_lista
```
Utilizando a função enframe forçamos a lista em um formato de dataset. Entretanto os dados não estão no formato tidy, e temos valores em formato de list na coluna value.
```{r}
dados_lista %>%
enframe()
```
O primeiro passo para lidar com esses dados é transformar os dados em formato tidy, usando a função tidyr::pivot_wider.
```{r}
dados_lista %>% #lista
enframe() %>% #função que transforma os dados em formato dataset
pivot_wider( #função que transforma os dados em formato wide
names_from = name,
values_from = value)
```
Agora temos um dataset em formato tidy, entretanto ainda temos os valores em lista. Para lidar com esses tipos de dados usamos as funções da família unnest(), onde a função unnest_longer() tira os dados em formato de lista empilhando os valores em linha, e a função unnest_wider tira os dados de formato de lista espalhando em multiplas colunas.
```{r}
dados_lista %>%
enframe() %>%
pivot_wider(names_from = name,
values_from = value) %>%
unnest_longer(c(times:brasileiros))
```
### Eninhando Dados
Em alguns casos precisamos eninhar dados, ou seja passar uma série de colunas pra dentro de uma coluna, para isso usamos a função nest().
\
No caso abaixo criaremos uma coluna chamada data que criará uma coluna que vai conter um dataset com todas as informações para uma coluna. Utilizaremos o dataset ggplot2::mpg para exemplificar.
```{r}
mpg %>% glimpse()
```
```{r}
ggplot2::mpg %>%
nest(#função que eninha os dados
data = -model)
```
Cada linha da coluna data contém um dataset filtrado para coluna model. Ou seja temos um dataset que contém 38 datasets filtrados, cada um para um modelo.
A partir de dados eninhados podemos fazer multiplas análises, já que dentro da coluna de um tibble qualquer elemento pode ser guardado.\
\
Podemos guardar modelos de regressão
```{r}
mpg %>%
nest(data = -model) %>%
mutate(lm_model = map(data, ~lm(hwy~cty+cyl, data =.)))
```
Podemos também printar essas multiplas regressões e entender como cada regressão perfoma para o tipo de modelo
```{r, warning=FALSE}
mpg %>%
nest(data =-model) %>%
mutate(lm_model = map(data, ~lm(hwy~cty+cyl, data =.)),
lm_model = map(lm_model, broom::tidy)
) %>%
unnest(lm_model)
```
Observe que agora temos para cada modelo um intercepto, um beta para coluna cty e um beta para a coluna cyl.
Podemos fazer também um gráfico de dispersão para cada modelo.
```{r}
mpg %>%
nest(data =-model) %>%
mutate(grafico = map(data, ~ggplot(data = .,
aes(x = hwy, y = cty))+
geom_point()))
```
Observe que a coluna gráfico contém um objeto chamado gg. Se printarmos a coluna visualizaremos os gráficos
```{r}
mpg %>%
nest(-model) %>%
mutate(grafico = map(data, ~ggplot(data = .,
aes(x = hwy, y = cty))+
geom_point())) %>%
pull(grafico)
```
## Exercícios
Você trabalha em uma empresa de marketing e precisa preparar os dados para uma análise de campanhas publicitárias. Os dados atuais têm cada campanha em uma linha, com informações sobre o canal de publicidade e o número de cliques. Você precisa transformar esses dados em um formato mais amplo, com cada canal de publicidade em uma coluna separada e o número de cliques como valores correspondentes.
```{r}
campanhas <- data.frame(
campanha = paste0("Campanha", 1:20),
canal = sample(c("TV", "Rádio", "Impresso", "Digital"), 20, replace = TRUE),
cliques = sample(100:1000, 20, replace = TRUE)
)
campanhas
```
Você trabalha em uma empresa de pesquisa e precisa preparar os dados para uma análise de opinião dos clientes. Os dados atuais têm cada resposta em uma linha, com informações sobre o cliente, a pergunta e a resposta. Você precisa transformar esses dados em um formato mais longo, com cada pergunta em uma linha separada e as respostas correspondentes como valores.
```{r}
opiniao <- data.frame(
cliente = sample(c("Cliente A", "Cliente B", "Cliente C", "Cliente D"), 20, replace = TRUE),
pergunta = sample(c("Qualidade do Produto", "Atendimento ao Cliente", "Preço"), 20, replace = TRUE),
resposta = sample(1:5, 20, replace = TRUE)
)
opiniao
```
Você trabalha em uma empresa de pesquisa e precisa preparar os dados para uma análise de opinião dos clientes em vários países. Os dados atuais têm cada resposta em uma linha, com informações sobre o cliente, a pergunta, a resposta e o país. Você precisa transformar esses dados em um formato mais amplo, com cada pergunta e país em uma coluna separada e as respostas correspondentes como valores.
```{r}
opiniao_paises <- data.frame(
cliente = sample(c("Cliente A", "Cliente B", "Cliente C", "Cliente D"), 40, replace = TRUE),
pergunta = sample(c("Qualidade do Produto", "Atendimento ao Cliente", "Preço"), 40, replace = TRUE),
resposta = sample(1:5, 40, replace =TRUE),
pais = sample(c("Brasil", "Estados Unidos", "México", "Argentina"), 40, replace = TRUE)
)
opiniao_paises
```
Você está trabalhando com dados de uma pesquisa de mercado sobre preferências de alimentos. Cada linha da tabela de dados contém informações sobre um indivíduo, incluindo sua idade, sexo, estado civil, e suas escolhas de alimentos favoritos. As escolhas de alimentos estão todas em uma única coluna e separadas por vírgulas. Você precisa transformar esses dados em um formato mais longo, com cada escolha de alimento em uma linha separada e as informações pessoais correspondentes como valores.
```{r}
preferencias <- data.frame(
idade = sample(18:65, 50, replace = TRUE),
sexo = sample(c("Masculino", "Feminino"), 50, replace = TRUE),
estado_civil = sample(c("Solteiro", "Casado"), 50, replace = TRUE),
alimentos = replicate(50, paste(sample(c("Pizza", "Hambúrguer", "Sushi", "Salada"), sample(1:3, 1)), collapse = ", "))
)
```
Você está trabalhando com dados de vendas de produtos em diferentes lojas. Cada linha da tabela de dados contém informações sobre um produto vendido, incluindo o nome do produto, a loja em que foi vendido, a data da venda e o número de unidades vendidas. Você precisa transformar esses dados em um formato mais amplo, com cada loja em uma coluna separada e o número de unidades vendidas como valores correspondentes.
```{r}
vendas <- data.frame(
produto = replicate(20, paste(sample(c("Notebook", "Smartphone", "Tablet", "Smartwatch"), 1))),
loja = sample(c("Loja A", "Loja B", "Loja C", "Loja D"), 20, replace = TRUE),
data = sample(seq(as.Date("2022/01/01"), as.Date("2022/01/31"), by = "day"), 20, replace = TRUE),
unidades_vendidas = sample(10:100, 20, replace = TRUE)
)
vendas
```
Você está trabalhando com dados de uma pesquisa de opinião pública sobre as eleições. As informações estão em duas colunas: o nome do candidato e o percentual de votos que ele recebeu em uma determinada pesquisa. Você precisa combinar essas duas informações em uma única coluna.
```{r}
pesquisa_eleitoral <- data.frame(
candidato = sample(c("João", "Maria", "José", "Ana"), 20, replace = TRUE),
votos = sample(10:80, 20, replace = TRUE)
)
pesquisa_eleitoral
```
Você está trabalhando com dados de endereços em uma planilha, onde cada endereço é dividido em várias colunas: rua, número, bairro, cidade e estado. Você precisa combinar essas informações em uma única coluna de endereço completo.
```{r}
enderecos <- data.frame(
rua = sample(c("Rua A", "Rua B", "Rua C"), 10, replace = TRUE),
numero = sample(1:100, 10, replace = TRUE),
bairro = sample(c("Bairro A", "Bairro B", "Bairro C"), 10, replace = TRUE),
cidade = sample(c("Cidade A", "Cidade B", "Cidade C"), 10, replace = TRUE),
estado = sample(c("SP", "RJ", "MG"), 10, replace = TRUE)
)
enderecos
```
Você está trabalhando com dados de uma tabela que contém informações sobre compras feitas em uma loja online. O nome do produto e a quantidade comprada estão em uma única coluna, separados por um hífen. Você precisa separar essas informações em duas colunas.
```{r}
compras_online <- data.frame(
produto_quantidade = replicate(20, paste(sample(c("Notebook", "Smartphone", "Tablet", "Smartwatch"), 1), sample(1:5, 1), sep = " - "))
)
compras_online
```
Você está trabalhando com dados de uma tabela que contém informações sobre o preço de um produto em diferentes lojas em diferentes dias. Há valores faltantes na coluna de preço para algumas datas e lojas. Você precisa preencher esses valores faltantes com o último valor válido da mesma loja.
```{r}
preco <- data.frame(
loja = rep(letters[1:3], each = 5),
data = rep(1:5, times = 3),
preco = sample(c(10, NA), size = 15, replace = TRUE)
)
preco %>%
fill(preco)
```
Você está trabalhando com dados de uma tabela que contém informações sobre a temperatura de diferentes cidades em diferentes dias. Há valores faltantes na coluna de temperatura para alguns dias e cidades. Você precisa substituir esses valores faltantes pelo valor médio da temperatura para a mesma cidade.
```{r}
temperatura <- data.frame(
cidade = rep(c("Rio de Janeiro", "São Paulo", "Belo Horizonte"), each = 5),
data = rep(1:5, times = 3),
temperatura = sample(c(25.1:39.1, NA), size = 15, replace = TRUE)
)
temperatura
```
Você possui uma lista com informações sobre a quantidade de vendas de produtos em diferentes dias. Cada elemento da lista corresponde a um dia e contém um vetor com a quantidade de vendas de cada produto. Você precisa transformar essa lista em um tibble, onde cada linha corresponde a um dia e as colunas correspondem aos produtos.
```{r}
vendas <- list(
dia1 = c(10, 20, 15, 5, 25, 30),
dia2 = c(12, 18, 22, 7, 20, 25),
dia3 = c(18, 15, 20, 10, 30, 35),
dia4 = c(8, 24, 16, 3, 35, 28),
dia5 = c(14, 22, 18, 8, 28, 32)
)
```
Você possui uma lista com informações sobre o tempo que cada funcionário levou para realizar uma tarefa. Cada elemento da lista corresponde a um funcionário e contém um vetor com o tempo que cada um levou para realizar a tarefa em diferentes dias. Você precisa transformar essa lista em um tibble, onde cada linha corresponde a um dia e as colunas correspondem aos funcionários.
```{r}
tempo_tarefa <- list(
func1 = c(60, 45, 50, 40, 55, 75),
func2 = c(55, 65, 70, 75, 80, 90),
func3 = c(70, 80, 60, 55, 70, 75),
func4 = c(50, 60, 75, 90, 100, 85),
func5 = c(80, 75, 65, 50, 40, 60)
)
```
Você possui uma lista com informações sobre o número de alunos presentes em diferentes dias e em diferentes turmas de uma escola. Cada elemento da lista corresponde a um dia e contém um sub-lista com o número de alunos presentes em cada turma naquele dia. Você precisa transformar essa lista em um tibble, onde cada linha corresponde a um dia e as colunas correspondem às turmas.
```{r}
presenca_alunos <- list(
dia1 = list(turma1 = 25, turma2 = 30, turma3 = 22),
dia2 = list(turma1 = 28, turma2 = 31, turma3 = 23),
dia3 = list(turma1 = 30, turma2 = 28, turma3 = 25),
dia4 = list(turma1 = 27, turma2 = 30, turma3 = 21),
dia5 = list(turma1 = 29, turma2 = 27, turma3 = 24)
)
```
Suponha que você tem uma lista de dados que contém informações sobre produtos vendidos em diferentes lojas. Cada elemento da lista contém um data frame com informações sobre os produtos vendidos em uma loja. Você deseja transformar essa lista em um único tibble, onde cada linha corresponde a uma venda, e as colunas correspondem às informações sobre os produtos vendidos (nome, quantidade e preço) e a loja onde a venda ocorreu.
```{r}
dados_produtos <- list(
loja1 <- tibble(
nome = sample(c("Produto A", "Produto B", "Produto C"), 10, replace = TRUE),
quantidade = sample(1:10, 10, replace = TRUE),
preco = runif(10, 10, 100)
),
loja2 <- tibble(
nome = sample(c("Produto B", "Produto C", "Produto D"), 10, replace = TRUE),
quantidade = sample(1:10, 10, replace = TRUE),
preco = runif(10, 10, 100)
)
)
```