-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtema8.qmd
102 lines (69 loc) · 3.84 KB
/
tema8.qmd
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
---
title: "Reformatear tablas"
---
```{r}
#| echo: false
#| warning: false
library(data.table)
library(magrittr)
library(ggplot2)
data = fread("data/universal_top_spotify_songs.csv.gz")
```
Las funciones para cambiar las tablas de formato son `melt` y `dcast`. Estas funciones están optimizadas para funcionar con grandes cantidades de datos guardados en memoria (10GB).
## Larga a ancha
Actualmente tenemos una tabla larga. Vamos a convertirla en una tabla en la que las columnas sean los 73 paises y las canciones las filas. Los valores van a ser el numero de veces en las que cada canción ha aparecido en el listado de las 50 canciones más populares (`data`) en el último año. Adicionalmente vamos a mantener la columna de la fecha del listado (snapshot_date) pero la vamos a modificar de modo que nos quedemos con el mes y el año.
Larga a ancha:
```
dcast(data, formula, fun.aggregate = NULL, sep = "_",
..., margins = NULL, subset = NULL, fill = NULL,
drop = TRUE, value.var = guess(data),
verbose = getOption("datatable.verbose"))
```
![](img/dcast.png)
```{r}
# Vamos a utilizar la tabla de canciones del top50 en 73 paises
# Queremos crear una tabla de conteos de cada cancion por pais por mes en el que se hizo el listado top 50
freq_song_long <- data[country != "",.(.N), by = .(name,country,month_yr = format(snapshot_date,"%Y-%m"))]
freq_song_long
freq_song_wide <- dcast(freq_song_long, month_yr+name~country, value.var = "N", fill = 0)
freq_song_wide[,1:9]
```
La función dcast también nos permite agregar valores de acuerdo a una función mientras cambiamos el formato de las tablas. Esto es útil cuando nuestra fórmula no puede identificar de manera única cada fila. Por ejemplo, si quiseramos comparar la popularidad promedio de cada canción entre el 2023 y el 2024 podemos hacer lo siguiente:
```{r}
dcast(data[country != ""], country + name ~ format(snapshot_date,"%Y"), value.var = "popularity", fun.aggregate = function(x){round(mean(x, na.rm = T),digits = 1)})
```
Ahora imagina que te gustaría pasar de ancha a larga utilizando dos columnas. Por ejemplo, para compara la popularidad y el ranking promedio por año. Podemos indicar múltiples columnas en `value.var`
```{r}
pop_rank_per_year <- dcast(data[country != ""], country + name ~ format(snapshot_date,"%Y"), value.var = c("daily_rank", "popularity"), sep = ".", fun.aggregate = function(x){round(mean(x, na.rm = T),digits = 1)})
pop_rank_per_year
```
## Ancha a larga
Ancha a larga:
```
melt(data, id.vars, measure.vars,
variable.name = "variable", value.name = "value",
..., na.rm = FALSE, variable.factor = TRUE,
value.factor = FALSE,
verbose = getOption("datatable.verbose"))
```
![](img/merge.png)
```{r}
freq_song_long2 <- melt(freq_song_wide, id.vars = c("month_yr","name"), variable.name = "country", value.name = "N")
freq_song_long2
```
De manera similar a `dcast`, podemos reformatear una tabla para conservar más de una columna en la tabla en formato largo. Por ejemplo, si tenemos la tabla generada anteriormente con el ranking promedio diario por año y la popularidad promedio por año, y quisiéramos una tabla que separara las medidas de popularidad en una columna y el ranking promedio en otra, podemos hacerlo de la siguiente manera:
```{r}
## Forma 1
colA = paste0("daily_rank.", 2023:2024)
colB = paste0("popularity.", 2023:2024)
pop_rank_year_long <- pop_rank_per_year %>%
melt(., measure = list(colA, colB), value.name = c("daily_rank", "popularity"), variable.name = "year")
pop_rank_year_long[,year := ifelse(year == 1, 2023,2024)]
pop_rank_year_long
## Forma 2
pop_rank_per_year %>%
melt(., measure = patterns("^daily_rank.", "^popularity."), value.name = c("daily_rank", "popularity"), variable.name = "year")
# Forma 3
pop_rank_per_year %>%
melt(., measure.vars = measure(var=as.factor, year=as.integer, sep="."), value.name = "mean")
```