A música tem um papel central na cultura de Recife, refletindo a identidade local e regional. Entender as tendências musicais da cidade ao longo de um período específico pode oferecer insights valiosos sobre as preferências da população e como essas preferências mudam ao longo do tempo. Com o uso crescente de plataformas de streaming, como o Spotify, é possível acessar dados detalhados sobre as músicas mais ouvidas na cidade, permitindo uma análise mais precisa das mudanças nas preferências musicais. Este estudo visa investigar quais estilos musicais têm dominado Recife durante os últimos dois anos (2021-2023), como eventos culturais e sociais influenciaram essas preferências e identificar padrões específicos de gosto musical que caracterizam a cidade.
Essa análise tem importância para diversos setores, incluindo a indústria musical, empresas de marketing e organizadores de eventos. Compreender as tendências locais pode ajudar artistas a direcionarem suas produções para o público recifense, enquanto agências de marketing podem criar campanhas mais segmentadas. Além disso, a indústria de eventos pode se beneficiar ao ajustar suas programações conforme as preferências musicais locais.
A abordagem adotada para entender as tendências musicais de Recife será baseada no uso dos dados extraídos do conjunto Brazil Regional Spotify Charts, que fornece informações detalhadas sobre as músicas mais ouvidas na cidade. A metodologia envolverá:
A análise será conduzida utilizando a linguagem de programação R, com as seguintes ferramentas:
A técnica que será adotada para abordar o problema envolve uma combinação de análise de séries temporais e análise geográfica, focando exclusivamente em Recife. A análise de séries temporais será utilizada para identificar como as preferências musicais evoluíram ao longo do tempo. Já a análise geográfica se concentrará nas particularidades da cidade de Recife, destacando como estilos musicais populares em outros locais podem se manifestar de maneira diferente na cidade.
Será aplicada também uma análise qualitativa para entender a relação entre eventos culturais e sociais de Recife (como o Carnaval e festivais locais) e as preferências musicais. Além disso, o uso de técnicas de agrupamento, como K-means, permitirá identificar se há subgrupos dentro da cidade que compartilham características musicais semelhantes.
Essa abordagem será eficaz para identificar tendências locais e entender como fatores culturais específicos influenciam as escolhas musicais da população recifense.
A análise das tendências musicais de Recife traz benefícios específicos para os seguintes potenciais clientes:
Essa análise permitirá uma compreensão mais profunda das preferências musicais dos recifenses e ajudará os setores envolvidos a tomar decisões mais informadas e estratégicas.
Para a realização da análise, os seguintes pacotes R foram utilizados. Eles são carregados antecipadamente para garantir que todos os requisitos necessários sejam atendidos, permitindo que qualquer leitor possa replicar a análise de forma eficaz.
library(dplyr) # Para manipulação e transformação de dados
library(ggplot2) # Para visualização de dados e criação de gráficos
library(lubridate) # Para manipulação de datas e operações com séries temporais
library(tidyr) # Para arrumar e limpar os dados, além de ajudar na transformação de colunas
library(cluster) # Para análise de agrupamento e clustering
library(readr) # Para ler os CSVs
library(purrr) # Para iterar e mapear funções
library(stringr) # Para manipular string
library(knitr) # Para gerar relatórios dinâmicos em R
library(kableExtra) # Para visualizar tabelas
library(reactable) # Para criar tabelas iterativas em R
library(tidytext) # Para manipular textos complexos
library(wordcloud) # Para gerar nuvem de palavras
select(): Seleciona colunas.filter(): Filtra linhas.mutate(): Cria ou modifica colunas.summarize(): Realiza operações de resumo como média,
soma, etc.arrange(): Ordena os dados.geom_point(),
geom_bar(), geom_histogram().ymd(),
mdy(), dmy().spread() e gather(): Transforma dados de
formato “long” para “wide” e vice-versa.separate(): Divide uma coluna em várias.unite(): Junta várias colunas em uma.kmeans() e agnes() para
segmentar dados em clusters.read_csv(): Lê arquivos CSV rapidamente e com
eficiência.map(), map_dbl(), map_df():
Itera funções sobre listas e vetores.str_detect(), str_replace(),
str_split(): Detecta, substitui e divide strings com
expressões regulares.- **Objetivo**: Melhoria da visualização de tabelas.
- **Funções principais**:
- Estiliza tabelas criadas com `kable()`, como adicionar bordas, cores e outros estilos personalizados.
- **Objetivo**: Criação de tabelas interativas em R.
- **Funções principais**:
- Criação de tabelas interativas que permitem ordenação, filtro e busca.
unnest_tokens() – Quebra textos em palavras, frases ou
n-grams.get_sentiments() – Acessa dicionários de sentimentos
como bing, nrc e afinn.bind_tf_idf() – Calcula a frequência termo-inversa
(TF-IDF) para identificar palavras mais relevantes.wordcloud() – Gera uma nuvem de palavras a partir de um
vetor de textos.comparison.cloud() – Cria uma nuvem comparativa entre
dois grupos de palavras.textplot() – Plota palavras em um espaço gráfico com
base em frequência ou outros parâmetros.Os dados utilizados nesta análise foram extraídos do conjunto “Brazil Regional Spotify Charts”, disponível na plataforma Kaggle. O dataset fornece informações detalhadas sobre as músicas mais populares no Brasil em diferentes regiões, incluindo Recife, durante o período de 2021 a 2023, além de funcionalidades musicais sobre cada música, como acústica e danceabilidade.
A base de dados é atualizada regularmente e contém registros semanais das faixas mais ouvidas em diversas cidades brasileiras. Para esta análise, o foco está especificamente na região de Recife, permitindo compreender as tendências musicais locais e como elas evoluíram ao longo do tempo.
Este conjunto de dados oferece uma visão detalhada do consumo regional de música digital no Brasil no Spotify entre 2021 e 2023. Ele inclui características acústicas e todos os gêneros/artistas que foram ouvidos ao menos uma vez durante esses anos. Os dados são fornecidos pela API do Spotify para Desenvolvedores e pelo SpotifyCharts, que são utilizados para coletar as características acústicas e as músicas mais ouvidas nas cidades, respectivamente.
Logo, o conjunto original possui 18 megabits de memória e mais de 14 mil colunas, pois é armazenado dados por região, tal como Recife, assim como dados de artistas, gênero musical e informações de música do Spotify. Entretanto, para essa análise será utilizado apenas a base de Recife e a base de informações musicais do Spotify (track_info_update.csv).
Período de Coleta: Os dados foram coletados ao longo de vários meses de 2021 a 2024, com rankings diários das músicas mais tocadas em diferentes regiões do Brasil.
Número de Variáveis: Os arquivos contêm 7 variáveis principais::
rank: Posição no ranking (1-100)uri: Identificador único do Spotify para cada
faixatrack_name: Nome da músicapeak: Melhor posição já alcançada pela músicaprev: Posição anterior no rankingstreak: Número de semanas consecutivas no chartartist_names: Nome do(s) artista(s)Peculiaridades dos Dados:
Inclusão de Dados: Os dados foram incluídos com base
nos rankings diários do Spotify. Assim, é necessário incluir novas
colunas indicando a semana que foi incluido, o ano e o mês a fim de
facilitar a categorização dos registros e análise dos dados.
Anomalias: Durante o período de análise dos dados,
foi identificada uma anomalia específica em 2023, na qual o rank
5 não apareceu em nenhum dos dias analisados. A ausência do
rank 5 é uma peculiaridade observada que deve ser considerada ao
realizar análises baseadas em rankings diários. Além disso, nos dados
analisados, foi observada uma relação importante entre o
peak (a melhor posição já alcançada por uma música no
ranking) e a posição atual (a posição da música no
ranking em determinado dia).
Remoção de Dados: A coluna artist_names declara
somente o nome do primeiro artista, talvez isso possa prejudicar a
análise sobre dados que possuam mais de 1 artista.
Período de Coleta: Os dados foram coletados ao longo de 2022 e 2023, com informações sobre faixas de músicas extraídas da plataforma Spotify. O período abrange diversos meses e mostra o comportamento das músicas, incluindo características acústicas e atributos musicais.
Número de Variáveis: O dataset contém 18 variáveis principais:
id: Identificador único de cada faixa.artist_names: Nome(s) do(s) artista(s) da música.name: Nome da música.genres: Gêneros musicais associados à música.acousticness: Índice de acústica da música (valor entre
0 e 1).danceability: Índice de dança da música (valor entre 0
e 1).duration_ms: Duração da música em milissegundos.energy: Índice de energia da música (valor entre 0 e
1).instrumentalness: Índice de ausência de vocais (valor
entre 0 e 1).key: A tonalidade da música (0-11 correspondendo a
notas musicais).liveness: Indicador de performance ao vivo (valor entre
0 e 1).loudness: Nível geral de volume da música em decibéis
(dB).mode: Modo musical (1 para maior, 0 para menor).speechiness: Índice de presença de fala na música
(valor entre 0 e 1).tempo: A velocidade média da música em batidas por
minuto (BPM).time_signature: A assinatura de tempo da música.valence: Índice de positividade da música (valor entre
0 e 1).artists_ids: Identificadores únicos dos artistas no
Spotify.Peculiaridades dos Dados:
Valores Ausentes: Alguns valores podem estar
ausentes (representados como NA ou valores numéricos
indefinidos) devido a falhas na coleta ou lacunas nas informações do
Spotify. Esses dados podem ser tratados por meio de técnicas de
imputação ou exclusão.
Exclusão de Registros: A base apresenta cerca de registros, entretanto a maior parte desses registros não serão aproveitados para a análise de dados com foco no Recife.
Após a importação, foi necessário realizar um processo de limpeza de dados para garantir que as análises fossem precisas e eficazes. A limpeza é um passo crucial, pois os dados brutos frequentemente contêm problemas como valores ausentes, erros de formatação ou dados inconsistentes, que podem prejudicar os resultados da análise.
O dataset possui 119 arquivos com dados semanais de músicas no top 100 do Spotify, é necessário realizar uma filtragem de dados por ano a fim de classificá-los individualmente.
## [1] "/Users/jml/Documents/PROJETO_FINAL_CPAD/archive/regional/Recife/Apr 1 - 7, 2022.csv"
## [2] "/Users/jml/Documents/PROJETO_FINAL_CPAD/archive/regional/Recife/Apr 14 - 20, 2023.csv"
## [3] "/Users/jml/Documents/PROJETO_FINAL_CPAD/archive/regional/Recife/Apr 15 - 21, 2022.csv"
## [4] "/Users/jml/Documents/PROJETO_FINAL_CPAD/archive/regional/Recife/Apr 21 - 27, 2023.csv"
## [5] "/Users/jml/Documents/PROJETO_FINAL_CPAD/archive/regional/Recife/Apr 22 - 28, 2022.csv"
## [6] "/Users/jml/Documents/PROJETO_FINAL_CPAD/archive/regional/Recife/Apr 28 - May 4, 2023.csv"
add_csv_files_to_df <- function(arquivo) {
df <- read_csv(arquivo, show_col_types = FALSE)
return(df)
}
spotify_df <- purrr::map_df(csv_files, add_csv_files_to_df)
reactable(spotify_df[1:5, ], sortable = TRUE, style = list(fontSize = "10px"))
##### Função para ler cada CSV e extrair o ano, semana e mês do nome do arquivo
month_counter = list()
read_and_add_year <- function(arquivo) {
# Extração do ano (4 dígitos)
year <- as.integer(str_extract(basename(arquivo), "\\d{4}"))
# Extração do mês (primeiros 3 caracteres)
months <- str_extract_all(basename(arquivo), "[A-Z][a-z]{2}")[[1]]
# Trata o caso de transição de mês
month <- if (length(months) == 2) {
paste(months, collapse = " - ") # Ex: "Sep - Oct"
} else if (length(months) == 1) {
months[1] # Ex: "Sep"
} else {
month <- NA
}
# Extração da semana (captura qualquer padrão numérico entre hifens)
pattern <- "(?i)\\b([A-Za-z]{3})(?:\\s\\d{1,2})?\\s*-\\s*([A-Za-z]{3})?\\s*(\\d{1,2})\\b"
week <- str_extract(basename(arquivo), pattern)
# Removendo os meses de transição e aplicando str_squish para remover espaços extras
week <- str_remove_all(week, "[A-Za-z]{3}") # Remove os meses
week <- str_squish(week) # Remove quaisquer espaços extras restantes
df <- read_csv(arquivo, show_col_types = FALSE) %>%
mutate(year = year, month = month, week = week)
return(df)
}
spotify_ds <- purrr::map_df(csv_files, read_and_add_year)
reactable(spotify_ds[1:5, ], sortable = TRUE, style = list(fontSize = "10px"))
glimpse(spotify_ds)
## Rows: 11,882
## Columns: 10
## $ rank <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
## $ uri <chr> "spotify:track:3sd2p4kE7xQmFH3lPnFl6h", "spotify:track:3I…
## $ track_name <chr> "sentaDONA (Remix) s2", "Envolver", "DANÇARINA", "No Ouvi…
## $ peak <dbl> 1, 1, 1, 4, 1, 1, 2, 8, 9, 7, 8, 3, 7, 4, 2, 12, 8, 18, 6…
## $ prev <chr> "2", "1", "3", "69", "4", "5", "6", "30", "—", "10", "13"…
## $ streak <dbl> 3, 12, 8, 2, 9, 16, 10, 4, 1, 12, 18, 12, 8, 11, 21, 9, 8…
## $ artist_names <chr> "Davi Kneip", "Anitta", "PEDRO SAMPAIO", "Felipe Amorim",…
## $ year <int> 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 202…
## $ month <chr> "Apr", "Apr", "Apr", "Apr", "Apr", "Apr", "Apr", "Apr", "…
## $ week <chr> "1 - 7", "1 - 7", "1 - 7", "1 - 7", "1 - 7", "1 - 7", "1 …
spotify_ds_sorted <- spotify_ds %>%
mutate(
# Criar uma coluna 'month_num' para facilitar a ordenação dos meses
month_num = match(month, c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
) %>%
arrange(desc(year), month_num) %>%
select(-month_num)
reactable(spotify_ds_sorted[1:5, ], sortable = TRUE, style = list(fontSize = "10px"))
tracks_info_update <- read.csv("~/Documents/PROJETO_FINAL_CPAD/archive/tracks_info-update.csv")
Nesse dataset há muitas duplicatas, visto que o spotify separa suas músicas por álbuns, então 4 álbuns podem conter a mesma músicas e elas serem contabilizadas pela plataforma como 4 músicas distintas. Entretanto, para a nossa análise as informações acerca de uma música devem ser centralizadas em um único registro.
Por exemplo, a música AMEIANOITE de Pablo Vittar e Glória Groover está duplicada no tracks_info_update e ambos id’s estão no dataset spotify_ds_sorted.
# Renomeando coluna para ser similas ao outro dataset
tracks_info_update <- tracks_info_update %>% rename("track_name" = "name")
reactable(tracks_info_update[tracks_info_update$track_name == "AMEIANOITE", ], sortable = TRUE, style = list(fontSize = "10px"))
# Contabilizar a quantidade de duplicatas para cada nome de música
duplicatas <- tracks_info_update %>%
group_by(track_name, artist_names) %>%
tally() %>%
filter(n > 1)
reactable(head(duplicatas), sortable = TRUE, style = list(fontSize = "10px"))
Cerca de 671 músicas no dataset track_info_update estão duplicados, o que pode dificultar análises e geração de gráficos, logo temos de deletá-los utilizando distinct.
track_info_unique <- tracks_info_update %>%
distinct(artist_names, track_name , .keep_all = TRUE)
# Contabilizar a quantidade de duplicatas para cada nome de música
duplicatas <- track_info_unique %>%
group_by(track_name, artist_names) %>%
tally() %>%
filter(n > 1)
Cerca de 0 músicas no dataset track_info_update estão duplicados, agora é necessário substituir os id’s das duplicatas pelo único id. (spotify_ds_sorted).
track_info_unique <- track_info_unique %>% # Criando uma nova coluna para registrar o primeiro nome do artista
mutate(first_artist = str_split(artist_names, ",") %>%
lapply(function(x) x[1]) %>%
unlist())
# Renomear 'id' em 'spotify_ds_sorted' e 'track_info_unique' para evitar conflito
spotify_ds_sorted <- spotify_ds_sorted %>%
rename(id_spotify = uri)
track_info_unique <- track_info_unique %>%
rename(id_track_info = id)
Ajustar os meses em valores numéricos:
month_mapping <- c("Jan" = "01", "Feb" = "02", "Mar" = "03", "Apr" = "04",
"May" = "05", "Jun" = "06", "Jul" = "07", "Aug" = "08",
"Sep" = "09", "Oct" = "10", "Nov" = "11", "Dec" = "12")
# Converter o mês abreviado para numérico
spotify_ds_sorted <- spotify_ds_sorted %>%
mutate(year = as.numeric(year),
month = month_mapping[month])
# Função para atualizar os IDs
update_ids <- function(spotify_df, info_df) {
for (i in seq_len(nrow(spotify_df))) {
# Localiza o id_track_info correspondente no track_info_unique
new_id <- info_df$id_track_info[
info_df$track_name == spotify_df$track_name[i] &
info_df$first_artist == spotify_df$artist_names[i]
]
# Se encontrar um id válido, substitui
if (length(new_id) == 1) {
spotify_df$id_spotify[i] <- new_id
}
}
return(spotify_df)
}
# Executa a função
spotify_ds_sorted <- update_ids(spotify_ds_sorted, track_info_unique)
Agora podemos validar baseado no exemplo anterior se funcionara.
reactable(spotify_ds_sorted[spotify_ds_sorted$track_name == "AMEIANOITE", c("id_spotify", "track_name", "artist_names")], sortable = TRUE, style = list(fontSize = "10px"))
Como podemos observar, todos os ids estão iguais.
track_info_na <- colSums(is.na(spotify_ds_sorted[, colnames(spotify_ds_sorted)]))
track_info_na
## rank id_spotify track_name peak prev streak
## 0 0 0 0 0 0
## artist_names year month week
## 0 0 2295 0
track_info_na <- colSums(is.na(track_info_unique[, colnames(track_info_unique)]))
track_info_na
## X id_track_info artist_names track_name
## 0 0 0 0
## genres acousticness danceability duration_ms
## 0 0 0 0
## energy instrumentalness key liveness
## 0 0 0 0
## loudness mode speechiness tempo
## 0 0 0 0
## time_signature valence artists_ids first_artist
## 0 0 0 0
Após a análise, podemos observar que todas as colunas estão preenchidas de ambos datasets estão preenchidos. E com isso, concluímos a limpeza do dados para análise.
Após a etapa de limpeza e preparação dos conjuntos de dados, apresentamos uma visão geral consolidada dos dados que serão utilizados para as análises subsequentes. A limpeza envolveu a remoção de dados inconsistentes, tratamento de valores ausentes, normalização de variáveis e eliminação de outliers, de modo a garantir que os dados estejam prontos para análise confiável.
Nesta seção, mostramos uma amostra representativa dos dados limpos, com o objetivo de fornecer uma visão clara de sua estrutura, variáveis e valores principais. Para isso, optamos por exibir as primeiras linhas ou uma amostra aleatória do conjunto de dados, permitindo que você avalie rapidamente as principais características do dataset sem sobrecarregar com um número excessivo de informações.
A seguir, apresentamos as primeiras linhas ou uma amostra aleatória de ambos os conjuntos de dados, contendo apenas as variáveis essenciais para análise.
data_summary_2 <- data.frame(
Variável = c("rank", "uri", "track_name", "peak", "prev", "streak",
"artist_names", "year", "month", "week"),
Tipo = c("Numérico", "Texto", "Texto", "Numérico", "Numérico", "Numérico",
"Texto", "Numérico", "Numérico", "Texto"),
Descrição = c("Posição no ranking (1-100)",
"Identificador único do Spotify para cada faixa",
"Nome da música",
"Melhor posição já alcançada pela música",
"Posição anterior no ranking",
"Número de semanas consecutivas no chart",
"Nome(s) do(s) artista(s)",
"Ano do Top 100",
"Mês do Top 100",
"Semana do Top 100")
)
kable(data_summary_2, caption = "Resumo das Variáveis: Conjunto 1") %>%
kable_styling("striped", full_width = F) %>%
column_spec(1, bold = T, color = "white", background = "steelblue") %>%
column_spec(2, bold = T, color = "white", background = "darkorange") %>%
column_spec(3, width = "30em")
| Variável | Tipo | Descrição |
|---|---|---|
| rank | Numérico | Posição no ranking (1-100) |
| uri | Texto | Identificador único do Spotify para cada faixa |
| track_name | Texto | Nome da música |
| peak | Numérico | Melhor posição já alcançada pela música |
| prev | Numérico | Posição anterior no ranking |
| streak | Numérico | Número de semanas consecutivas no chart |
| artist_names | Texto | Nome(s) do(s) artista(s) |
| year | Numérico | Ano do Top 100 |
| month | Numérico | Mês do Top 100 |
| week | Texto | Semana do Top 100 |
Um total de 119 arquivos .CSV foram juntados em um único dataset para centralizar e facilitar a análise dos dados. Antes, o dataset possuia 11882 registros e 7 colunas, sendo as colunas: rank, uri, track_name, peak, prev, streak, artist_names.
# Exibindo as primeiras 20 linhas do conjunto de dados Spotify limpo
reactable(spotify_ds_sorted[1:20, ], style = list(fontSize = "10px"), showSortIcon = TRUE)
A estrutura dos dados continua a seguir o mesmo padrão, suas colunas
atualmente são: rank, id_spotify, track_name, peak, prev, streak,
artist_names, year, month, week. As recentemente adicionadas foram:
week (semana), month (mês) e year
(ano), com a finalidade de categorizar os dados de forma temporal.
Atualmente o dataset possui 11882 registros e 10 colunas, sendo as colunas: rank, id_spotify, track_name, peak, prev, streak, artist_names, year, month, week.
data_summary <- data.frame(
Variável = c("id", "artist_names", "name", "genres", "acousticness", "danceability",
"duration_ms", "energy", "instrumentalness", "key", "liveness",
"loudness", "mode", "speechiness", "tempo", "time_signature",
"valence", "artists_ids", "first_artist"),
Tipo = c("Numérico", "Texto", "Texto", "Texto", "Numérico", "Numérico",
"Numérico", "Numérico", "Numérico", "Numérico", "Numérico",
"Numérico", "Categórico", "Numérico", "Numérico", "Numérico",
"Numérico", "Numérico", "Texto"),
Descrição = c("Identificador único de cada faixa",
"Nome(s) do(s) artista(s) da música",
"Nome da música",
"Gêneros musicais associados à música",
"Índice de acústica da música (valor entre 0 e 1)",
"Índice de dança da música (valor entre 0 e 1)",
"Duração da música em milissegundos",
"Índice de energia da música (valor entre 0 e 1)",
"Índice de ausência de vocais (valor entre 0 e 1)",
"A tonalidade da música (0-11 correspondendo a notas musicais)",
"Indicador de performance ao vivo (valor entre 0 e 1)",
"Nível geral de volume da música em decibéis (dB)",
"Modo musical (1 para maior, 0 para menor)",
"Índice de presença de fala na música (valor entre 0 e 1)",
"Velocidade média da música em batidas por minuto (BPM)",
"Assinatura de tempo da música",
"Índice de positividade da música (valor entre 0 e 1)",
"Identificadores únicos dos artistas no Spotify",
"Identificador do primeiro artista")
)
# Exibindo a tabela
kable(data_summary, caption = "Resumo das Variáveis: Conjunto 2")%>%
kable_styling("striped", full_width = F) %>%
column_spec(1, bold = T, color = "white", background = "steelblue") %>%
column_spec(2, bold = T, color = "white", background = "darkorange") %>%
column_spec(3, width = "30em")
| Variável | Tipo | Descrição |
|---|---|---|
| id | Numérico | Identificador único de cada faixa |
| artist_names | Texto | Nome(s) do(s) artista(s) da música |
| name | Texto | Nome da música |
| genres | Texto | Gêneros musicais associados à música |
| acousticness | Numérico | Índice de acústica da música (valor entre 0 e 1) |
| danceability | Numérico | Índice de dança da música (valor entre 0 e 1) |
| duration_ms | Numérico | Duração da música em milissegundos |
| energy | Numérico | Índice de energia da música (valor entre 0 e 1) |
| instrumentalness | Numérico | Índice de ausência de vocais (valor entre 0 e 1) |
| key | Numérico | A tonalidade da música (0-11 correspondendo a notas musicais) |
| liveness | Numérico | Indicador de performance ao vivo (valor entre 0 e 1) |
| loudness | Numérico | Nível geral de volume da música em decibéis (dB) |
| mode | Categórico | Modo musical (1 para maior, 0 para menor) |
| speechiness | Numérico | Índice de presença de fala na música (valor entre 0 e 1) |
| tempo | Numérico | Velocidade média da música em batidas por minuto (BPM) |
| time_signature | Numérico | Assinatura de tempo da música |
| valence | Numérico | Índice de positividade da música (valor entre 0 e 1) |
| artists_ids | Numérico | Identificadores únicos dos artistas no Spotify |
| first_artist | Texto | Identificador do primeiro artista |
O dataset contém variáveis que caracterizam tanto a parte musical quanto a análise temporal e de popularidade de cada faixa. Variáveis como acousticness, danceability, energy, entre outras, fornecem informações detalhadas sobre as qualidades físicas e emocionais das músicas. id e artists_ids são chaves únicas para identificar as músicas e os artistas, respectivamente. Antes, o dataset possuia 5190 registros e 19 colunas, sendo as colunas: X, id, artist_names, track_name, genres, acousticness, danceability, duration_ms, energy, instrumentalness, key, liveness, loudness, mode, speechiness, tempo, time_signature, valence, artists_ids.
# Exibindo as primeiras 20 linhas do conjunto de dados Spotify limpo
reactable(track_info_unique[1:20, ], style = list(fontSize = "10px"), showSortIcon = TRUE)
Depois de exclusão de duplicatas e padronização de id’s entre ambos datasets, o dataset agora possui 4401 registros e 20 colunas, sendo as colunas: X, id_track_info, artist_names, track_name, genres, acousticness, danceability, duration_ms, energy, instrumentalness, key, liveness, loudness, mode, speechiness, tempo, time_signature, valence, artists_ids, first_artist. O número de colunas foi alterada pois o dataset armazena o nome de mais de um artista por música, caso seja música autoral conjunta, que não é o caso do dataset do spotify, que armazena apenas o nome do primeiro artista. Logo, foi incluído a coluna first_artist, para sinalizar o primeiro artista e localizá-los no dataset do spotify de forma efetiva.
Os conjuntos de dados limpos contém informações cruciais para analisar as tendências musicais em Recife entre 2021 e 2023, com foco na popularidade das músicas, os estilos predominantes e as variações ao longo do tempo.
data_summary_interest <- data.frame(
Variável = c("rank", "id_spotify", "track_name", "peak", "prev", "streak",
"artist_names", "year", "month", "week", "genres", "acousticness",
"danceability", "duration_ms", "energy", "instrumentalness", "key",
"liveness", "loudness", "mode", "speechiness", "tempo", "time_signature",
"valence"),
Tipo = c("Numérico", "Texto", "Texto", "Numérico", "Numérico", "Numérico",
"Texto", "Numérico", "Numérico", "Numérico", "Texto", "Numérico",
"Numérico", "Numérico", "Numérico", "Numérico", "Numérico", "Numérico",
"Numérico", "Numérico", "Numérico", "Numérico", "Numérico", "Numérico"),
Descrição = c("Posição no ranking (1-100)",
"Identificador único do Spotify para cada faixa",
"Nome da música",
"Melhor posição já alcançada pela música",
"Posição anterior no ranking",
"Número de semanas consecutivas no chart",
"Nome(s) do(s) artista(s)",
"Ano do Top 100",
"Mês do Top 100",
"Semana do do Top 100",
"Gêneros musicais associados à música",
"Índice de acústica da música (0-1)",
"Índice de dança da música (0-1)",
"Duração da música em milissegundos",
"Índice de energia da música (0-1)",
"Índice de ausência de vocais (0-1)",
"Tonalidade da música (0-11, notas musicais)",
"Indicador de performance ao vivo (0-1)",
"Nível geral de volume da música (dB)",
"Modo musical (1 para maior, 0 para menor)",
"Índice de presença de fala na música (0-1)",
"Velocidade média da música em BPM",
"Assinatura de tempo da música (4/4, etc.)",
"Índice de positividade da música (0-1)")
)
kable(data_summary_interest, caption = "Resumo das Variáveis de Interesse no Conjunto de Dados") %>%
kable_styling("striped", full_width = F) %>%
column_spec(1, bold = T, color = "white", background = "steelblue") %>%
column_spec(2, bold = T, color = "white", background = "darkorange") %>%
column_spec(3, width = "30em")
| Variável | Tipo | Descrição |
|---|---|---|
| rank | Numérico | Posição no ranking (1-100) |
| id_spotify | Texto | Identificador único do Spotify para cada faixa |
| track_name | Texto | Nome da música |
| peak | Numérico | Melhor posição já alcançada pela música |
| prev | Numérico | Posição anterior no ranking |
| streak | Numérico | Número de semanas consecutivas no chart |
| artist_names | Texto | Nome(s) do(s) artista(s) |
| year | Numérico | Ano do Top 100 |
| month | Numérico | Mês do Top 100 |
| week | Numérico | Semana do do Top 100 |
| genres | Texto | Gêneros musicais associados à música |
| acousticness | Numérico | Índice de acústica da música (0-1) |
| danceability | Numérico | Índice de dança da música (0-1) |
| duration_ms | Numérico | Duração da música em milissegundos |
| energy | Numérico | Índice de energia da música (0-1) |
| instrumentalness | Numérico | Índice de ausência de vocais (0-1) |
| key | Numérico | Tonalidade da música (0-11, notas musicais) |
| liveness | Numérico | Indicador de performance ao vivo (0-1) |
| loudness | Numérico | Nível geral de volume da música (dB) |
| mode | Numérico | Modo musical (1 para maior, 0 para menor) |
| speechiness | Numérico | Índice de presença de fala na música (0-1) |
| tempo | Numérico | Velocidade média da música em BPM |
| time_signature | Numérico | Assinatura de tempo da música (4/4, etc.) |
| valence | Numérico | Índice de positividade da música (0-1) |
A análise exploratória de dados (AED), também conhecida como exploratory data analysis (EDA), é uma etapa crucial no processo de análise de dados. Ela tem como objetivo entender as características e padrões dos dados de forma preliminar antes de realizar análises mais complexas ou de aplicar modelos preditivos. A AED ajuda a identificar tendências, relações entre variáveis, anomalias e distribuições dos dados, fornecendo insights valiosos que orientam as próximas etapas da análise.
A análise temporal é uma abordagem que foca na exploração, modelagem e interpretação de dados ao longo do tempo. Essa análise é particularmente importante quando os dados possuem uma componente temporal, ou seja, são coletados em diferentes períodos, como horas, dias, meses ou anos. Em contextos como análise de tendências de gêneros musicais, a análise temporal pode ajudar a identificar padrões sazonais, mudanças ao longo do tempo, e até mesmo prever comportamentos futuros com base em dados históricos.
combined_data <- merge(spotify_ds_sorted, track_info_unique, by.x = "id_spotify", by.y = "id_track_info", all.x = TRUE)
# Assumindo que a coluna de gêneros na planilha track_info_unique seja 'genres'
genres_text <- tolower(combined_data$genres) # Substitua 'genres' pelo nome correto, se necessário
# Separar os gêneros em caso de múltiplos gêneros por música
genres_list <- unlist(strsplit(genres_text, split = ","))
# Criar um data frame de frequência de gêneros
genres_freq <- as.data.frame(table(genres_list))
# Renomeando as colunas para algo mais amigável
colnames(genres_freq) <- c("genre", "frequency")
# Garantir que year_month é criado corretamente a partir de year e month
combined_data <- combined_data %>%
mutate(year_month = as.Date(paste(year, month, "01", sep = "-")))
# Separar os gêneros em múltiplas linhas
genre_trends <- combined_data %>%
separate_rows(genres, sep = ",") %>%
mutate(genres = trimws(genres)) %>% # Remover espaços em branco
filter(!is.na(genres) & genres != "") %>% # Remover NAs e valores vazios
group_by(year_month, genres) %>%
summarise(count = n(), .groups = "drop")
# Ordenando os gêneros pela frequência
genres_freq <- genres_freq %>%
arrange(desc(frequency))
# Remover linhas com NA em 'year_month' ou 'genres'
genre_trends_clean <- genre_trends %>%
filter(!is.na(year_month) & !is.na(genres)) # Remove linhas com NA
# Extrair o ano de year_month
genre_trends_annual <- genre_trends_clean %>%
mutate(year = format(year_month, "%Y")) %>% # Extrair ano de year_month
group_by(year, genres) %>% # Agrupar por ano e gênero
summarise(count = sum(count), .groups = "drop") # Somar as ocorrências por ano
# Identificar os 3 gêneros mais populares por ano (em vez de no total)
top_genres_yearly <- genre_trends_annual %>%
group_by(year) %>%
top_n(3, count) %>%
pull(genres) %>%
unique()
# Filtrar os gêneros mais populares
genre_trends_filtered <- genre_trends_annual %>%
filter(genres %in% top_genres_yearly)
# Gerar o gráfico anual
ggplot(genre_trends_filtered, aes(x = year, y = count, fill = genres)) +
geom_bar(stat = "identity", position = "dodge") + # "dodge" para separar as barras dos gêneros
labs(title = "Tendências Anuais de Gêneros Musicais em Recife",
x = "Ano",
y = "Frequência",
fill = "Gêneros") +
theme_minimal() +
theme(legend.position = "top")
## Error : The fig.showtext code chunk option must be TRUE
O gráfico apresenta as “Tendências Anuais de Gêneros Musicais em Recife”
durante os anos de 2022 e 2023 (desconsiderando 2021 e 2024 conforme
instruído). Analisando os dados de 2022 e 2023, podemos extrair as
seguintes informações:
library(dplyr)
library(ggplot2)
library(gridExtra)
# Filtrar dados para 2021
genre_trends_2021 <- genre_trends %>%
filter(format(year_month, "%Y") == "2021") %>%
filter(!is.na(genres))
genre_counts_2021 <- genre_trends_2021 %>%
group_by(genres) %>%
summarise(count = sum(count), .groups = "drop") %>%
arrange(desc(count))
top_10_genres_2021 <- genre_counts_2021 %>% slice_head(n = 10)
# Gráfico para 2021
plot_2021 <- ggplot(top_10_genres_2021, aes(x = reorder(genres, count), y = count, fill = genres)) +
geom_bar(stat = "identity") +
coord_flip() +
labs( title="2021",
x = "Gênero",
y = "Frequência",
fill = "Gêneros") +
theme_minimal() +
theme(legend.position = "none")
# Filtrar dados para 2022
genre_trends_2022 <- genre_trends %>%
filter(format(year_month, "%Y") == "2022") %>%
filter(!is.na(genres))
genre_counts_2022 <- genre_trends_2022 %>%
group_by(genres) %>%
summarise(count = sum(count), .groups = "drop") %>%
arrange(desc(count))
top_10_genres_2022 <- genre_counts_2022 %>% slice_head(n = 10)
# Gráfico para 2022
plot_2022 <- ggplot(top_10_genres_2022, aes(x = reorder(genres, count), y = count, fill = genres)) +
geom_bar(stat = "identity") +
coord_flip() +
labs( title = "2022",
x = "Gênero",
y = "Frequência",
fill = "Gêneros") +
theme_minimal() +
theme(legend.position = "none")
# Filtrar dados para 2023
genre_trends_2023 <- genre_trends %>%
filter(format(year_month, "%Y") == "2023") %>%
filter(!is.na(genres))
genre_counts_2023 <- genre_trends_2023 %>%
group_by(genres) %>%
summarise(count = sum(count), .groups = "drop") %>%
arrange(desc(count))
top_10_genres_2023 <- genre_counts_2023 %>% slice_head(n = 10)
# Gráfico para 2023
plot_2023 <- ggplot(top_10_genres_2023, aes(x = reorder(genres, count), y = count, fill = genres)) +
geom_bar(stat = "identity") +
coord_flip() +
labs(title="2023",
x = "Gênero",
y = "Frequência",
fill = "Gêneros") +
theme_minimal() +
theme(legend.position = "none")
# Filtrar dados para 2024
genre_trends_2024 <- genre_trends %>%
filter(format(year_month, "%Y") == "2024") %>%
filter(!is.na(genres))
genre_counts_2024 <- genre_trends_2024 %>%
group_by(genres) %>%
summarise(count = sum(count), .groups = "drop") %>%
arrange(desc(count))
top_10_genres_2024 <- genre_counts_2024 %>% slice_head(n = 10)
# Gráfico para 2024
plot_2024 <- ggplot(top_10_genres_2024, aes(x = reorder(genres, count), y = count, fill = genres)) +
geom_bar(stat = "identity") +
coord_flip() +
labs( title = "2024",
x = "Gênero",
y = "Frequência",
fill = "Gêneros") +
theme_minimal() +
theme(legend.position = "none")
# Organizar os gráficos em uma matriz (2x2)
grid.arrange(plot_2021, plot_2022, plot_2023, plot_2024, nrow = 2, ncol = 2)
## Error : The fig.showtext code chunk option must be TRUE
O gráfico mostra a evolução da frequência de diferentes gêneros musicais
brasileiros ao longo dos anos de 2021 a 2024. Vamos analisar cada ano:
1. 2021:
Tendências observadas:
Arrocha e forró demonstram consistência como os gêneros mais frequentes em todos os anos. O trap brasileiro mostra crescimento gradual, refletindo sua popularização. Alguns gêneros como piseiro e sertanejo pop perderam relevância ao longo do tempo. O ecossistema do funk (carioca, trap funk, funk jr) mantém presença, mas com variações. A escala do eixo de frequência parece mudar em 2024, o que dificulta a comparação direta com anos anteriores.
Esta análise sugere uma evolução dinâmica do cenário musical brasileiro, com alguns gêneros mantendo consistência e outros emergindo ou perdendo força ao longo do período analisado.
# Separar os gêneros em múltiplas linhas
# Separando os gêneros e removendo espaços extras
# 1. Limpar e organizar os dados
# Garantir que não há NA ou valores vazios em 'genres'
spotify_combined_clean <- combined_data %>%
filter(!is.na(genres) & genres != "")
# Separar os gêneros em múltiplas linhas
spotify_combined_separated <- spotify_combined_clean %>%
separate_rows(genres, sep = ",") %>%
mutate(genres = trimws(genres))
# 2. Calcular a média de acústica por gênero
genre_acoustic_data <- spotify_combined_separated %>%
group_by(genres) %>%
summarise(avg_acousticness = mean(acousticness, na.rm = TRUE), .groups = "drop")
# 3. Calcular a frequência de cada gênero
genre_frequency <- spotify_combined_separated %>%
group_by(genres) %>%
summarise(total_count = n(), .groups = "drop")
# 4. Combinar as informações
genre_acoustic_freq <- genre_acoustic_data %>%
left_join(genre_frequency, by = "genres")
# 5. Selecionar os 10 gêneros mais frequentes
top_10_genres <- genre_acoustic_freq %>%
arrange(desc(total_count)) %>%
slice_head(n = 10)
# 6. Gerar o gráfico de dispersão
ggplot(top_10_genres, aes(x = avg_acousticness, y = total_count, label = genres, color = genres)) +
geom_point(size = 4) +
geom_text(vjust = -0.8, hjust = 0.5) +
labs(
title = "Relação entre Acústica e Frequência dos Gêneros",
x = "Média de Acústica",
y = "Frequência",
color = "Gêneros"
) +
theme_minimal() +
theme(legend.position = "none")
## Error : The fig.showtext code chunk option must be TRUE
O eixo horizontal (x) representa a “Média de Acústica”, com valores variando aproximadamente de 0,325 a 0,400. Isso provavelmente indica o quanto cada gênero utiliza elementos acústicos (não-eletrônicos) em sua composição.
O eixo vertical (y) representa a “Frequência”, variando de cerca de 1000 a 5000 Hz. Isso parece indicar a média de frequências predominantes em cada gênero musical. Os gêneros musicais estão distribuídos da seguinte forma:
Em resumo, o gráfico sugere que gêneros mais escutados no Recife, como arrocha e forró, tendem a ter frequências mais altas e maior componente acústico, enquanto gêneros como pop nacional e rochadeira tendem a ter frequências mais baixas e menor componente acústico. Há também gêneros que ocupam posições intermediárias nessas duas variáveis.
artist_freq <- spotify_ds_sorted %>%
group_by(artist_names) %>%
summarise(n = n(), .groups = "drop") %>%
arrange(desc(n))
top_artists <- artist_freq %>% head(25)
wordcloud(words = top_artists$artist_names,
freq = artist_freq$n,
min.freq = 1,
scale = c(3, 0.5),
colors = brewer.pal(8, "Dark2"),
rot.per = 0.2, # Ajuste o grau de rotação das palavras
random.order = FALSE) # Garante que as palavras mais frequentes ficam mais visíveis
## Error : The fig.showtext code chunk option must be TRUE
A nuvem de palavras representa os 25 artistas mais escutados nos últimos 4 anos, como principais: João Gomes, Nattan, Mari Fernandez e Felipe Amorim. O interessante é o estilo musical desses cantores é o Forró, seja o Pisero (vertente do Forró) ou Forró eletrônico, que mistura batidas animadas.
# Carregar as bibliotecas necessárias
library(dplyr)
library(ggplot2)
# 1. Limpar e organizar os dados
# Garantir que não há NA ou valores vazios em 'artist_names'
spotify_artists_clean <- combined_data %>%
filter(!is.na(artist_names.x) & artist_names.x != "")
# Separar os artistas em múltiplas linhas
spotify_artists_separated <- spotify_artists_clean %>%
separate_rows(artist_names.x, sep = ",") %>%
mutate(artist_names.x = trimws(artist_names.x))
# 2. Calcular a média de acústica por artista
artist_acoustic_data <- spotify_artists_separated %>%
group_by(artist_names.x) %>%
summarise(avg_acousticness = mean(acousticness, na.rm = TRUE), .groups = "drop")
# 3. Calcular a frequência de cada artista
artist_frequency <- spotify_artists_separated %>%
group_by(artist_names.x) %>%
summarise(total_count = n(), .groups = "drop")
# 4. Combinar as informações
artist_acoustic_freq <- artist_acoustic_data %>%
left_join(artist_frequency, by = "artist_names.x")
# 5. Selecionar os 10 artistas mais frequentes
top_10_artists <- artist_acoustic_freq %>%
arrange(desc(total_count)) %>%
slice_head(n = 10)
# 6. Gerar o gráfico de dispersão
ggplot(top_10_artists, aes(x = avg_acousticness, y = total_count, label = artist_names.x, color = artist_names.x)) +
geom_point(size = 4) +
geom_text(vjust = -0.8, hjust = 0.5) +
labs(
title = "Relação entre Acústica e Frequência dos Artistas",
x = "Média de Acústica",
y = "Frequência",
color = "Artistas"
) +
theme_minimal() +
theme(legend.position = "none")
## Error : The fig.showtext code chunk option must be TRUE
A partir desses gráficos, podemos extrair diversos insights valiosos sobre o cenário musical brasileiro atual:
Aspectos culturais e sociais:
A persistência de gêneros regionais (forró, arrocha) em um mundo globalizado demonstra a resistência e adaptabilidade da cultura musical brasileira A ascensão do trap brasileiro reflete como movimentos globais são abraçados e adaptados ao contexto local
# 1. Limpar e organizar os dados
# Garantir que não há NA ou valores vazios em 'artist_names'
spotify_artists_clean <- combined_data %>%
filter(!is.na(artist_names.x) & artist_names.x != "")
# Separar os artistas em múltiplas linhas
spotify_artists_separated <- spotify_artists_clean %>%
separate_rows(artist_names.x, sep = ",") %>%
mutate(artist_names.x = trimws(artist_names.x))
# 2. Calcular a média de acústica e danceabilidade por artista
artist_acoustic_data <- spotify_artists_separated %>%
group_by(artist_names.x) %>%
summarise(
avg_acousticness = mean(acousticness, na.rm = TRUE),
avg_danceability = mean(danceability, na.rm = TRUE),
.groups = "drop"
)
# 3. Calcular a frequência de cada artista
artist_frequency <- spotify_artists_separated %>%
group_by(artist_names.x) %>%
summarise(total_count = n(), .groups = "drop")
# 4. Combinar as informações
artist_acoustic_freq <- artist_acoustic_data %>%
left_join(artist_frequency, by = "artist_names.x")
# 5. Selecionar os 10 artistas mais frequentes
top_10_artists <- artist_acoustic_freq %>%
arrange(desc(total_count)) %>%
slice_head(n = 10)
# 6. Gerar o gráfico de dispersão com danceabilidade
ggplot(top_10_artists, aes(x = avg_danceability, y = total_count, label = artist_names.x, color = artist_names.x)) +
geom_point(size = 4) +
geom_text(vjust = -0.8, hjust = 0.5) +
labs(
title = "Relação entre Danceabilidade e Frequência dos Artistas",
x = "Média de Danceabilidade",
y = "Frequência",
color = "Artistas"
) +
theme_minimal() +
theme(legend.position = "none")
## Error : The fig.showtext code chunk option must be TRUE
O gráfico apresenta a “Relação entre Danceabilidade e Frequência dos Artistas” brasileiros. Vou interpretá-lo: - O eixo horizontal (x) representa a “Média de Danceabilidade”, com valores variando aproximadamente de 0,6 a 0,85, indicando o potencial dançante das músicas de cada artista. - O eixo vertical (y) representa a “Frequência”, variando de cerca de 200 a 700 Hz, mostrando as frequências médias predominantes nas músicas de cada artista. Analisando a distribuição dos artistas:
Este gráfico revela padrões interessantes sobre como diferentes artistas brasileiros equilibram aspectos de frequência vocal/instrumental e potencial dançante em suas músicas, oferecendo uma perspectiva quantitativa sobre elementos que afetam a resposta física (dança) aos diferentes estilos musicais.
Baseado nos dados analisados, as tendências musicais na região do Recife são músicas animadas, “dançantes” e de gêneros típicos ou vertentes do Arrocha, Forró e Sertanejo. Novos gêneros musicais ascendentes como Trap Brasileiro e Trap Funk também são tendências para os próximos anos.
Músicas tendem a se conectar com a realidade das pessoas através de suas letras e instrumentos, o forró, por exemplo, se popularizou através das letras de Luiz Gonzaga, que falava da realidade do Sertão nordestino, resiliência, costumes, frustrações e momentos de felicidade. Esse tipo de música gera uma identificação pessoal e simpatia, o que ocasiona em maior aderência ao estilo musical visto a cultura típica do Nordeste Pernambucano.