Taller Spotify

library(readr)
Warning: package 'readr' was built under R version 4.4.3
spotify <- read_csv("C:/Users/OMAR DANIEL MEDINA V/Downloads/data.csv")
Rows: 3441197 Columns: 7
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (4): Track Name, Artist, URL, Region
dbl  (2): Position, Streams
date (1): Date

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
names(spotify)
[1] "Position"   "Track Name" "Artist"     "Streams"    "URL"       
[6] "Date"       "Region"    
library(janitor)
Warning: package 'janitor' was built under R version 4.4.3

Adjuntando el paquete: 'janitor'
The following objects are masked from 'package:stats':

    chisq.test, fisher.test
spotify <- spotify |> clean_names()
names(spotify)
[1] "position"   "track_name" "artist"     "streams"    "url"       
[6] "date"       "region"    
# Ver primeros registros
head(spotify)
# A tibble: 6 × 7
  position track_name                 artist     streams url   date       region
     <dbl> <chr>                      <chr>        <dbl> <chr> <date>     <chr> 
1        1 Reggaetón Lento (Bailemos) CNCO         19272 http… 2017-01-01 ec    
2        2 Chantaje                   Shakira      19270 http… 2017-01-01 ec    
3        3 Otra Vez (feat. J Balvin)  Zion & Le…   15761 http… 2017-01-01 ec    
4        4 Vente Pa' Ca               Ricky Mar…   14954 http… 2017-01-01 ec    
5        5 Safari                     J Balvin     14269 http… 2017-01-01 ec    
6        6 La Bicicleta               Carlos Vi…   12843 http… 2017-01-01 ec    
library(tidyverse)
Warning: package 'tidyverse' was built under R version 4.4.3
Warning: package 'ggplot2' was built under R version 4.4.3
Warning: package 'dplyr' was built under R version 4.4.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ purrr     1.0.2
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
glimpse(spotify)
Rows: 3,441,197
Columns: 7
$ position   <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
$ track_name <chr> "Reggaetón Lento (Bailemos)", "Chantaje", "Otra Vez (feat. …
$ artist     <chr> "CNCO", "Shakira", "Zion & Lennox", "Ricky Martin", "J Balv…
$ streams    <dbl> 19272, 19270, 15761, 14954, 14269, 12843, 10986, 10653, 980…
$ url        <chr> "https://open.spotify.com/track/3AEZUABDXNtecAOSC1qTfo", "h…
$ date       <date> 2017-01-01, 2017-01-01, 2017-01-01, 2017-01-01, 2017-01-01…
$ region     <chr> "ec", "ec", "ec", "ec", "ec", "ec", "ec", "ec", "ec", "ec",…
summary(spotify)
    position       track_name           artist             streams        
 Min.   :  1.00   Length:3441197     Length:3441197     Min.   :    1001  
 1st Qu.: 45.00   Class :character   Class :character   1st Qu.:    3322  
 Median : 92.00   Mode  :character   Mode  :character   Median :    9227  
 Mean   : 94.64                                         Mean   :   51892  
 3rd Qu.:143.00                                         3rd Qu.:   29658  
 Max.   :200.00                                         Max.   :11381520  
     url                 date               region         
 Length:3441197     Min.   :2017-01-01   Length:3441197    
 Class :character   1st Qu.:2017-04-05   Class :character  
 Mode  :character   Median :2017-07-10   Mode  :character  
                    Mean   :2017-07-08                     
                    3rd Qu.:2017-10-10                     
                    Max.   :2018-01-09                     

Descripción general del conjunto de datos

El conjunto de datos cargado contiene información sobre las canciones más escuchadas en Spotify a nivel mundial, registradas diariamente por región. En total, se cuentan con 3.441.197 registros y 7 columnas, cada una representando una característica relevante del ranking diario.

Las variables presentes son:

  • Position: puesto de la canción en el top diario (1 a 200).

  • Track Name: nombre de la canción.

  • Artist: nombre del artista o grupo.

  • Streams: número de reproducciones que tuvo la canción ese día.

  • URL: enlace directo a la canción en Spotify.

  • Date: fecha del registro

  • Region: país o región donde se registró la posición.

anyNA(spotify) 
[1] TRUE
sum(is.na(spotify))
[1] 1322
colSums(is.na(spotify))  
  position track_name     artist    streams        url       date     region 
         0        657        657          0          8          0          0 
# Total de datos en el dataset
total_datos <- prod(dim(spotify))

# Total de NAs
total_na <- sum(is.na(spotify))

# Porcentaje de NAs
porcentaje_na <- (total_na / total_datos) * 100
porcentaje_na
[1] 0.005488124

Como se puede observar, se detectaron un total de 1.322 valores faltantes, lo que representa aproximadamente 0.0055% del total de los datos. La mayoría de estos valores estaban concentrados en las columnas Track Name y Artist, que son esenciales para el análisis, como el porcentaje es menor al 5% de datos faltantes se decidió eliminar las filas incompletas.

Ademas se decidio elimar la columna “URL” ya que es una columna irrelevante para el analisis estadistico.

# Eliminar filas con NA en 'Track Name' o 'Artist'
spotify_clean <- spotify |> 
  filter(!is.na(track_name), !is.na(artist))

# Eliminar la columna URL
spotify_clean <- spotify_clean |> 
  select(-url)
# Verificamos que quedó sin NA
sum(is.na(spotify_clean))
[1] 0

Top 10 canciones mas escuchadas (por suma de streams)

library(dplyr)

top_canciones <- spotify_clean |>
  group_by(track_name, artist) |>
  summarise(total_streams = sum(streams, na.rm = TRUE)) |>
  arrange(desc(total_streams)) |>
  slice_head(n = 10)
`summarise()` has grouped output by 'track_name'. You can override using the
`.groups` argument.
top_canciones
# A tibble: 19,907 × 3
# Groups:   track_name [18,597]
   track_name                                    artist         total_streams
   <chr>                                         <chr>                  <dbl>
 1 "\"All That Is or Ever Was or Ever Will Be\"" Alan Silvestri          7311
 2 "\"Read All About It, Pt. III\""              Emeli Sandé            57025
 3 "#99"                                         JVG                    31826
 4 "#Askip"                                      Black M               296862
 5 "#Biziz - feat. Lil Bege"                     Reynmen               403591
 6 "#CTZK"                                       Sir Mich              669563
 7 "#Elämänpeli (feat. Touko)"                   Mr. Elämänpeli        405771
 8 "#HEY!"                                       Pase Libre            109035
 9 "#JM"                                         Broederliefde        6756985
10 "#JesuispasséchezSo EP 11"                    Sofiane               174907
# ℹ 19,897 more rows

Análisis de canciones más escuchadas

Se analizaron las canciones con mayor número acumulado de reproducciones a lo largo del periodo registrado. Los resultados muestran una gran variedad de títulos, incluyendo canciones en inglés, español y otros idiomas.
Los temas más populares acumulan decenas de millones de streams, lo que evidencia un consumo musical altamente diversificado y global. La presencia de canciones con colaboraciones internacionales y de diferentes géneros resalta la naturaleza híbrida de las preferencias musicales actuales.

Top 10 artistas más escuchados (por suma de streams)

top_artistas <- spotify_clean |>
  group_by(artist) |>
  summarise(total_streams = sum(streams, na.rm = TRUE)) |>
  arrange(desc(total_streams)) |>
  slice_head(n = 10)

top_artistas
# A tibble: 10 × 2
   artist           total_streams
   <chr>                    <dbl>
 1 Ed Sheeran          8913973976
 2 Drake               4523630992
 3 The Chainsmokers    4292590087
 4 Post Malone         3700404149
 5 Kendrick Lamar      3570665303
 6 Luis Fonsi          3555514919
 7 J Balvin            2494735971
 8 Calvin Harris       2397708371
 9 Imagine Dragons     2322921399
10 DJ Khaled           2236224259

Análisis de canciones más escuchadas

Se analizaron las canciones con mayor número acumulado de reproducciones a lo largo del periodo registrado. Los resultados muestran una gran variedad de títulos, incluyendo canciones en inglés, español y otros idiomas.
Los temas más populares acumulan decenas de millones de streams, lo que evidencia un consumo musical altamente diversificado y global. La presencia de canciones con colaboraciones internacionales y de diferentes géneros resalta la naturaleza híbrida de las preferencias musicales actuales.

library(ggplot2)

# Gráfico de barras para los 10 artistas con más streams
ggplot(top_artistas, aes(x = reorder(artist, total_streams), y = total_streams)) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(
    title = "Top 10 artistas más escuchados en Spotify",
    x = "Artista",
    y = "Total de streams"
  ) +
  scale_y_continuous(labels = scales::comma) +
  theme_minimal()

spotify_tracks <- read_csv("C:/Users/OMAR DANIEL MEDINA V/Downloads/archive (3)/dataset.csv")
New names:
Rows: 114000 Columns: 21
── Column specification
──────────────────────────────────────────────────────── Delimiter: "," chr
(5): track_id, artists, album_name, track_name, track_genre dbl (15): ...1,
popularity, duration_ms, danceability, energy, key, loudness... lgl (1):
explicit
ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
Specify the column types or set `show_col_types = FALSE` to quiet this message.
• `` -> `...1`
# Renombrar columna 'artists' a 'artist' en el dataset de duración
spotify_tracks <- spotify_tracks |> 
  rename(artist = artists)
spotify_combined <- inner_join(
  spotify_clean |> mutate(across(c(track_name, artist), tolower)),
  spotify_tracks |> mutate(across(c(track_name, artist), tolower)),
  by = c("track_name", "artist"),
   relationship = "many-to-many"
)
spotify_combined
# A tibble: 2,024,707 × 25
   position track_name           artist streams date       region  ...1 track_id
      <dbl> <chr>                <chr>    <dbl> <date>     <chr>  <dbl> <chr>   
 1        1 reggaetón lento (ba… cnco     19272 2017-01-01 ec     88807 3AEZUAB…
 2        1 reggaetón lento (ba… cnco     19272 2017-01-01 ec     89709 3AEZUAB…
 3        9 traicionera          sebas…    9807 2017-01-01 ec     88319 0b5L58B…
 4        9 traicionera          sebas…    9807 2017-01-01 ec     88336 2lSmevO…
 5        9 traicionera          sebas…    9807 2017-01-01 ec     88338 4d5Q6A9…
 6        9 traicionera          sebas…    9807 2017-01-01 ec     88339 4E8u2Hu…
 7        9 traicionera          sebas…    9807 2017-01-01 ec     88341 3Iu7Mw7…
 8        9 traicionera          sebas…    9807 2017-01-01 ec     89321 0b5L58B…
 9        9 traicionera          sebas…    9807 2017-01-01 ec     89332 4d5Q6A9…
10        9 traicionera          sebas…    9807 2017-01-01 ec     89334 2lSmevO…
# ℹ 2,024,697 more rows
# ℹ 17 more variables: album_name <chr>, popularity <dbl>, duration_ms <dbl>,
#   explicit <lgl>, danceability <dbl>, energy <dbl>, key <dbl>,
#   loudness <dbl>, mode <dbl>, speechiness <dbl>, acousticness <dbl>,
#   instrumentalness <dbl>, liveness <dbl>, valence <dbl>, tempo <dbl>,
#   time_signature <dbl>, track_genre <chr>
# Convertimos duración de milisegundos a minutos
spotify_combined <- spotify_combined |>
  mutate(duration_min = duration_ms / 60000)

# Calculamos la duración promedio
duracion_promedio <- spotify_combined |>
  summarise(duracion_media = mean(duration_min, na.rm = TRUE))

duracion_promedio
# A tibble: 1 × 1
  duracion_media
           <dbl>
1           3.52

Para analizar la duración promedio de las canciones, se integró la base original con un dataset adicional que incluye la variable “duration_ms”.

Luego de convertir esta medida a minutos y considerando todas las apariciones posibles de las canciones (por país y fecha), se obtuvo una duración promedio de aproximadamente 3minutos con 52 segs.

Este resultado proporciona una idea general de la extensión habitual de las canciones más populares en Spotify.

# Top 10 canciones más largas
canciones_largas <- spotify_combined |>
  arrange(desc(duration_min)) |>
  distinct(track_name, artist, .keep_all = TRUE) |> 
  slice_head(n = 10) |>
  mutate(etiqueta = paste(track_name, "-", artist))

# Gráfico
library(ggplot2)

ggplot(canciones_largas, aes(x = reorder(etiqueta, duration_min), y = duration_min)) +
  geom_col(fill = "purple") +
  coord_flip() +
  labs(
    title = "Top 10 canciones más largas en el dataset",
    x = "Canción - Artista",
    y = "Duración (minutos)"
  ) +
  theme_minimal()

Visualización de canciones más largas

El gráfico muestra las 10 canciones con mayor duración del conjunto de datos, destacando clásicos como “November Rain” de Guns N’ Roses y “Purple Rain” de Prince, que superan los 7 minutos.

Canciones más escuchadas por cantidad de apariciones en el top

# Canciones más veces en el top
canciones_populares <- spotify_clean |>
  count(track_name, artist, sort = TRUE) |>
  slice_head(n = 10) |>
  mutate(etiqueta = paste(track_name, "-", artist))

# Gráfico
ggplot(canciones_populares, aes(x = reorder(etiqueta, n), y = n)) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(
    title = "Canciones con más apariciones en el Top 200",
    x = "Canción - Artista",
    y = "Número de apariciones"
  ) +
  theme_minimal()

Momentos del día con más streams

library(lubridate)

spotify_clean <- spotify_clean |>
  mutate(dia_semana = wday(date, label = TRUE, abbr = TRUE))

# Total de streams por día
streams_por_dia <- spotify_clean |>
  group_by(dia_semana) |>
  summarise(total_streams = sum(streams, na.rm = TRUE))

# Gráfico
ggplot(streams_por_dia, aes(x = dia_semana, y = total_streams)) +
  geom_col(fill = "darkgreen") +
  labs(
    title = "Streams totales por día de la semana",
    x = "Día",
    y = "Total de streams"
  ) +
  theme_minimal()

El análisis por día de la semana mostró que viernes y sábado son los días con mayor cantidad de streams, lo cual sugiere un aumento en la actividad musical hacia el fin de semana. Aunque el consumo se mantiene alto toda la semana, estos dos días destacan por una mayor interacción de los usuarios con la plataforma.

Conclusion:

El análisis exploratorio permitió descubrir patrones clave sobre la música y el comportamiento de los usuarios en Spotify:

  • Ed Sheeran lidera como el artista más escuchado, con más de 89 mil millones de streams. Le siguen Drake, The Chainsmokers y J Balvin, este último destacando como el único artista latino en el top global.

  • Las canciones con más apariciones en el Top 200 reflejan popularidad sostenida más allá del volumen de reproducciones en un solo día.

  • La duración promedio de las canciones en el dataset fue de 3 minutos con 52 segundos, aunque algunas canciones populares, como “November Rain”, superan los 7 minutos, demostrando que la duración no limita el alcance.

  • El consumo musical aumenta notablemente los viernes y sábados, lo que sugiere que los fines de semana son momentos clave para el lanzamiento de música y campañas promocionales.

Como recomendación, se recomendaria lanzar música viernes o sabado para aprovechar los picos de audiencia y tambien considerar realizar canciones tanto cortas como largas en un rango de 3-7 mins.