Introduction

Billboard is a popular company that specializes in music. They critique songs and albums and put on a renowned music awards show. Many artists and fans use Billboard to discuss music and those conversations create buzz around popular and new artists. Every year, Billboard creates top charts ranking the best artists, songs, and albums of the year. I hypothesize that there are key similarities between the top albums. This report will analyze the top albums of 2019 according to Billboard to see what similarities and differences there are.

I began by going to Billboards website and looking at the top albums of 2019. The number 3 album was “A Star is Born (Soundtrack)” by Lady Gaga and Bradley Cooper. I decided not to include it because the other top albums did not have an added element of a movie to make it more popular, recognized, and played more. Therefore, the number eleven album by Luke Combs was bumped up to replace it. I then went through and analyzed each album individually.

Billie Eilish: “WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?”

The number one album is Billie Eilish’s “WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?”. It released in March 2019 and is considered Electropop. To begin, I pulled the album from the genius package.

library(genius)
billie <-genius_album(artist = "Billie Eilish", album = "WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?")
## Joining, by = c("track_title", "track_n", "track_url")
library(tidytext)
library(textdata)
library(tidyverse)
## ── Attaching packages ───────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.2.1     ✓ purrr   0.3.3
## ✓ tibble  2.1.3     ✓ dplyr   0.8.4
## ✓ tidyr   1.0.2     ✓ stringr 1.4.0
## ✓ readr   1.3.1     ✓ forcats 0.4.0
## ── Conflicts ──────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

Then each word was separated and stop words were filtered out. I did not take out any additional stop words because I wanted the analysis to reflect the whole album as much as possible.

billie %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> billie_words
## Joining, by = "word"
billie_words
## # A tibble: 422 x 2
##    word      n
##    <chr> <int>
##  1 da       41
##  2 wanna    31
##  3 hmm      24
##  4 bad      19
##  5 guy      17
##  6 love     14
##  7 feel     13
##  8 ooh      12
##  9 gonna    10
## 10 lie      10
## # … with 412 more rows

I created a word cloud showing every word in the album.

library(wordcloud2)
wordcloud2(billie_words)
Sentiment & Valence

An afinn sentiment was taken to conduct a numeric value of every possible word in the album.

billie %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> billie_afinn
## Joining, by = "word"
## Joining, by = "word"
billie_afinn
## # A tibble: 86 x 3
##    word        n value
##    <chr>   <int> <dbl>
##  1 bad        19    -3
##  2 love       14     3
##  3 strange     9    -1
##  4 lonely      6    -2
##  5 pretty      6     1
##  6 scared      6    -2
##  7 care        5     2
##  8 god         5     1
##  9 hell        5    -4
## 10 save        4     2
## # … with 76 more rows

Then I calculated the average score of the afinn numeric values.

mean(billie_afinn$value)
## [1] -0.7325581

Next, a bing sentiment was created to put each possible word into a positive or negative category.

billie %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> billie_bing
## Joining, by = "word"
## Joining, by = "word"
billie_bing
## # A tibble: 90 x 3
##    word        n sentiment
##    <chr>   <int> <chr>    
##  1 bad        19 negative 
##  2 love       14 positive 
##  3 lie        10 negative 
##  4 strange     9 negative 
##  5 fall        6 negative 
##  6 lonely      6 negative 
##  7 pretty      6 positive 
##  8 scared      6 negative 
##  9 hell        5 negative 
## 10 break       4 negative 
## # … with 80 more rows

I then made a bar chart of each word with a bing sentiment that was used more than two times.

billie %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>2) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

Valence analyzes the positivity and negativity in music. A valence density graph was made to show the overall sentiment of the album.

library(devtools)
## Loading required package: usethis
library(spotifyr)
## 
## Attaching package: 'spotifyr'
## The following object is masked from 'package:tidytext':
## 
##     tidy
library(tidyverse)
library(knitr)
library(ggridges)
Sys.setenv(SPOTIFY_CLIENT_ID = '9c7c1caa99da4c86be844eb9f6ca96ac')
Sys.setenv(SPOTIFY_CLIENT_SECRET = '565805005f754c77ad8823c71452deaa')

access_token <- get_spotify_access_token()

eilish <- get_artist_audio_features('Billie Eilish')

eilish %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.116

Danceability

Using the same formula I used to analyze valence, I substituted in danceability to see how danceable the album is.

eilish %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.155

Energy

Then I substituted in energy to see how energetic the album is.

eilish %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0802

Key

Finally, I looked at the key signatures used in this album and arranged them from most used to least.

eilish %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

This process was then repeated for the remaining top ten albums.

Ariana Grande: “Thank U, Next”

The number two album was Ariana Grande’s “Thank U, Next”. It released in February 2019 and is considered to be Pop and R&B.

ariana <-genius_album(artist = "Ariana Grande", album = "Thank U, Next")
## Joining, by = c("track_title", "track_n", "track_url")
ariana %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> ariana_words
## Joining, by = "word"
ariana_words
## # A tibble: 428 x 2
##    word           n
##    <chr>      <int>
##  1 yeah         194
##  2 eh            42
##  3 love          41
##  4 i'ma          37
##  5 girlfriend    31
##  6 imagine       30
##  7 forget        27
##  8 space         24
##  9 bad           19
## 10 time          19
## # … with 418 more rows
wordcloud2(ariana_words)
Sentiment & Valence
ariana %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> ariana_afinn
## Joining, by = "word"
## Joining, by = "word"
ariana_afinn
## # A tibble: 82 x 3
##    word       n value
##    <chr>  <int> <dbl>
##  1 yeah     194     1
##  2 love      41     3
##  3 forget    27    -1
##  4 bad       19    -3
##  5 smile     17     2
##  6 fake      16    -3
##  7 leave     13    -1
##  8 woo       13     3
##  9 shit      11    -4
## 10 ruin      10    -2
## # … with 72 more rows
mean(ariana_afinn$value)
## [1] -0.5
ariana %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> ariana_bing
## Joining, by = "word"
## Joining, by = "word"
ariana_bing
## # A tibble: 83 x 3
##    word        n sentiment
##    <chr>   <int> <chr>    
##  1 love       41 positive 
##  2 bad        19 negative 
##  3 smile      17 positive 
##  4 fake       16 negative 
##  5 woo        13 positive 
##  6 shit       11 negative 
##  7 ruin       10 negative 
##  8 falling     8 negative 
##  9 needy       8 negative 
## 10 pain        8 negative 
## # … with 73 more rows
ariana %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

grande <- get_artist_audio_features('Ariana Grande')

grande %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("thank u, next")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.051

Danceability
grande %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("thank u, next")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0404

Energy
grande %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("thank u, next")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0652

Key
grande %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Taylor Swift: “Lover”

The number four album was Taylor Swift’s “Lover”. It released in August 2019 and is considered Pop.

taylor <-genius_album(artist = "Taylor Swift", album = "Lover")
## Joining, by = c("track_title", "track_n", "track_url")
taylor %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> taylor_words
## Joining, by = "word"
taylor_words
## # A tibble: 759 x 2
##    word         n
##    <chr>    <int>
##  1 ooh         69
##  2 love        44
##  3 wanna       42
##  4 daylight    40
##  5 ah          29
##  6 baby        29
##  7 yeah        25
##  8 street      23
##  9 walk        19
## 10 home        18
## # … with 749 more rows
wordcloud2(taylor_words)
Sentiment & Valence
taylor %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> taylor_afinn
## Joining, by = "word"
## Joining, by = "word"
taylor_afinn
## # A tibble: 139 x 3
##    word        n value
##    <chr>   <int> <dbl>
##  1 love       44     3
##  2 yeah       25     1
##  3 bad        17    -3
##  4 bless      15     2
##  5 hate       12    -3
##  6 fun        10     4
##  7 nice       10     3
##  8 fight       9    -1
##  9 promise     9     1
## 10 calm        8     2
## # … with 129 more rows
mean(taylor_afinn$value)
## [1] -0.4172662
taylor %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> taylor_bing
## Joining, by = "word"
## Joining, by = "word"
taylor_bing
## # A tibble: 154 x 3
##    word        n sentiment
##    <chr>   <int> <chr>    
##  1 love       44 positive 
##  2 bad        17 negative 
##  3 bless      15 positive 
##  4 darling    15 positive 
##  5 hate       12 negative 
##  6 lose       12 negative 
##  7 fancy      10 positive 
##  8 fun        10 positive 
##  9 nice       10 positive 
## 10 promise     9 positive 
## # … with 144 more rows
taylor %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

swift <- get_artist_audio_features('Taylor Swift')

swift %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Lover")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0751

Danceability
swift %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Lover")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0742

Energy
swift %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Lover")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.102

Key
swift %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Post Malone: “beerbongs & bentleys”

The number five album was Post Malone’s “beerbongs & bentleys”. It released in April 2018 and is considered Contemporary R&B and Hip Hop/Rap.

post <-genius_album(artist = "Post Malone", album = "beerbongs-bentleys")
## Joining, by = c("track_title", "track_n", "track_url")
post %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> post_words
## Joining, by = "word"
post_words
## # A tibble: 932 x 2
##    word        n
##    <chr>   <int>
##  1 yeah      143
##  2 oo        134
##  3 ooh        71
##  4 ayy        60
##  5 baby       50
##  6 night      44
##  7 fault      38
##  8 spoil      29
##  9 life       27
## 10 bitches    26
## # … with 922 more rows
wordcloud2(post_words)
Sentiment & Valence
post %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> post_afinn
## Joining, by = "word"
## Joining, by = "word"
post_afinn
## # A tibble: 106 x 3
##    word        n value
##    <chr>   <int> <dbl>
##  1 yeah      143     1
##  2 bitches    26    -5
##  3 damn       20    -4
##  4 top        19     2
##  5 drop       17    -1
##  6 bitch      16    -5
##  7 shit       16    -4
##  8 fuck       15    -4
##  9 love       13     3
## 10 blame      11    -2
## # … with 96 more rows
mean(post_afinn$value)
## [1] -0.5283019
post %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> post_bing
## Joining, by = "word"
## Joining, by = "word"
post_bing
## # A tibble: 118 x 3
##    word         n sentiment
##    <chr>    <int> <chr>    
##  1 fault       38 negative 
##  2 spoil       29 negative 
##  3 damn        20 negative 
##  4 top         19 positive 
##  5 bitch       16 negative 
##  6 shit        16 negative 
##  7 fuck        15 negative 
##  8 love        13 positive 
##  9 rockstar    13 positive 
## 10 blame       11 negative 
## # … with 108 more rows
post %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

malone <- get_artist_audio_features('Post Malone')

malone %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("beerbongs & bentleys")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.064

Danceability
malone %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("beerbongs & bentleys")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0467

Energy
malone %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("beerbongs & bentleys")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0489

Key
malone %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Drake: “Scorpion”

The number six album was Drake’s “Scorpion”. It released in June 2018 and is considered Hip Hop, R&B, and Pop.

drake <-genius_album(artist = "Drake", album = "Scorpion")
## Joining, by = c("track_title", "track_n", "track_url")
drake %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> drake_words
## Joining, by = "word"
drake_words
## # A tibble: 1,517 x 2
##    word       n
##    <chr>  <int>
##  1 yeah     117
##  2 gotta     67
##  3 shit      65
##  4 ayy       54
##  5 niggas    50
##  6 baby      49
##  7 wanna     36
##  8 time      35
##  9 love      32
## 10 wishin    26
## # … with 1,507 more rows
wordcloud2(drake_words)
Sentiment & Danceability
drake %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> drake_afinn
## Joining, by = "word"
## Joining, by = "word"
drake_afinn
## # A tibble: 191 x 3
##    word       n value
##    <chr>  <int> <dbl>
##  1 yeah     117     1
##  2 shit      65    -4
##  3 niggas    50    -5
##  4 love      32     3
##  5 sick      22    -2
##  6 ass       18    -4
##  7 bad       17    -3
##  8 care      17     2
##  9 cry       16    -1
## 10 woo       15     3
## # … with 181 more rows
mean(drake_afinn$value)
## [1] -0.2879581
drake %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> drake_bing
## Joining, by = "word"
## Joining, by = "word"
drake_bing
## # A tibble: 229 x 3
##    word      n sentiment
##    <chr> <int> <chr>    
##  1 shit     65 negative 
##  2 love     32 positive 
##  3 sick     22 negative 
##  4 dark     18 negative 
##  5 bad      17 negative 
##  6 cry      16 negative 
##  7 whoa     15 positive 
##  8 woo      15 positive 
##  9 fuck     12 negative 
## 10 die      10 negative 
## # … with 219 more rows
drake %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

dr_ake <- get_artist_audio_features('Drake')

dr_ake %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Scorpion")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0769

Danceability
dr_ake %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Scorpion")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0564

Energy
dr_ake %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Scorpion")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0564

Key
dr_ake %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Meek Mill: “Championships”

The number seven album was Meek Mill’s “Championships”. It released in November 2018 and is considered Hip Hop and Trap.

meek <-genius_album(artist = "Meek Mill", album = "Championships")
## Joining, by = c("track_title", "track_n", "track_url")
meek %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> meek_words
## Joining, by = "word"
meek_words
## # A tibble: 1,725 x 2
##    word       n
##    <chr>  <int>
##  1 yeah     109
##  2 niggas    83
##  3 nigga     69
##  4 bitch     56
##  5 ooh       56
##  6 booty     55
##  7 shit      54
##  8 fuck      51
##  9 gon       49
## 10 money     45
## # … with 1,715 more rows
wordcloud2(meek_words)
Sentiment & Valence
meek %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> meek_afinn
## Joining, by = "word"
## Joining, by = "word"
meek_afinn
## # A tibble: 188 x 3
##    word        n value
##    <chr>   <int> <dbl>
##  1 yeah      109     1
##  2 niggas     83    -5
##  3 bitch      56    -5
##  4 shit       54    -4
##  5 fuck       51    -4
##  6 bad        35    -3
##  7 free       35     1
##  8 love       24     3
##  9 pay        23    -1
## 10 bitches    22    -5
## # … with 178 more rows
mean(meek_afinn$value)
## [1] -0.8085106
meek%>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> meek_bing
## Joining, by = "word"
## Joining, by = "word"
meek_bing
## # A tibble: 216 x 3
##    word      n sentiment
##    <chr> <int> <chr>    
##  1 bitch    56 negative 
##  2 shit     54 negative 
##  3 fuck     51 negative 
##  4 bad      35 negative 
##  5 free     35 positive 
##  6 love     24 positive 
##  7 rich     20 positive 
##  8 freak    19 negative 
##  9 nasty    15 negative 
## 10 woo      14 positive 
## # … with 206 more rows
meek %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

mill <- get_artist_audio_features('Meek Mill')

mill %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Championships")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0695

Danceability
mill %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Championships")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0624

Energy
mill %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Championships")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0422

Key
mill %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Travis Scott: “ASTROWORLD”

The number eight album was Travis Scott’s “ASTROWORLD”. It released in August 2018 and is considered Hip Hop/Rap.

travis <-genius_album(artist = "Travis Scott", album = "ASTROWORLD")
## Joining, by = c("track_title", "track_n", "track_url")
travis %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> travis_words
## Joining, by = "word"
travis_words
## # A tibble: 1,185 x 2
##    word      n
##    <chr> <int>
##  1 yeah    219
##  2 hmm      55
##  3 fuck     51
##  4 club     42
##  5 pop      30
##  6 shit     29
##  7 tryna    28
##  8 skrrt    27
##  9 god      26
## 10 ooh      26
## # … with 1,175 more rows
wordcloud2(travis_words)
Sentiment & Valence
travis %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> travis_afinn
## Joining, by = "word"
## Joining, by = "word"
travis_afinn
## # A tibble: 103 x 3
##    word         n value
##    <chr>    <int> <dbl>
##  1 yeah       219     1
##  2 fuck        51    -4
##  3 shit        29    -4
##  4 god         26     1
##  5 bitch       25    -5
##  6 love        23     3
##  7 bad         22    -3
##  8 top         19     2
##  9 stop        15    -1
## 10 straight    15     1
## # … with 93 more rows
mean(travis_afinn$value)
## [1] -0.7087379
travis %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> travis_bing
## Joining, by = "word"
## Joining, by = "word"
travis_bing
## # A tibble: 127 x 3
##    word      n sentiment
##    <chr> <int> <chr>    
##  1 fuck     51 negative 
##  2 shit     29 negative 
##  3 bitch    25 negative 
##  4 love     23 positive 
##  5 bad      22 negative 
##  6 top      19 positive 
##  7 sweet    11 positive 
##  8 crazy     8 negative 
##  9 cold      7 negative 
## 10 peace     7 positive 
## # … with 117 more rows
travis %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

scott <- get_artist_audio_features('Travis Scott')

scott %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("ASTROWORLD")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0973

Danceability
scott %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("ASTROWORLD")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0528

Energy
scott %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("ASTROWORLD")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.052

Key
scott %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Post Malone: “Hollywood’s Bleeding”

The number nine album was Post Malone’s “Hollywood’s Bleeding”. It released in September 2019 and is considered Hip-Hop/Rap.

post2 <-genius_album(artist = "Post Malone", album = "Hollywood's Bleeding")
## Joining, by = c("track_title", "track_n", "track_url")
post2 %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> post2_words
## Joining, by = "word"
post2_words
## # A tibble: 744 x 2
##    word      n
##    <chr> <int>
##  1 yeah    116
##  2 time     56
##  3 die      54
##  4 ooh      48
##  5 lied     39
##  6 shit     34
##  7 til      33
##  8 ayy      27
##  9 feel     27
## 10 gonna    23
## # … with 734 more rows
wordcloud2(post2_words)
Sentiment & Valence
post2 %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> post2_afinn
## Joining, by = "word"
## Joining, by = "word"
post2_afinn
## # A tibble: 120 x 3
##    word        n value
##    <chr>   <int> <dbl>
##  1 yeah      116     1
##  2 die        54    -3
##  3 lied       39    -2
##  4 shit       34    -4
##  5 wow        23     4
##  6 bad        21    -3
##  7 enemies    17    -2
##  8 fuck       17    -4
##  9 bitch      16    -5
## 10 damn       16    -4
## # … with 110 more rows
mean(post2_afinn$value)
## [1] -0.7166667
post2 %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> post2_bing
## Joining, by = "word"
## Joining, by = "word"
post2_bing
## # A tibble: 124 x 3
##    word        n sentiment
##    <chr>   <int> <chr>    
##  1 die        54 negative 
##  2 lied       39 negative 
##  3 shit       34 negative 
##  4 wow        23 positive 
##  5 bad        21 negative 
##  6 enemies    17 negative 
##  7 fuck       17 negative 
##  8 bitch      16 negative 
##  9 damn       16 negative 
## 10 love       16 positive 
## # … with 114 more rows
post2 %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

malone2 <- get_artist_audio_features('Post Malone')

malone2 %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Hollywood's Bleeding")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.071

Danceability
malone2 %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Hollywood's Bleeding")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.053

Energy
malone2 %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Hollywood's Bleeding")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0418

Key
malone2 %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

A Boogie Wit da Hoodie: “Hoodie SZN”

The number ten album was A Boogie Wit da Hoodie’s “Hoodie SZN”. It released in December 2018 and is considered Hip-Hop, Trap, and R&B.

boogie <-genius_album(artist = "A Boogie Wit da Hoodie", album = "Hoodie SZN")
## Joining, by = c("track_title", "track_n", "track_url")
boogie %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> boogie_words
## Joining, by = "word"
boogie_words
## # A tibble: 1,206 x 2
##    word       n
##    <chr>  <int>
##  1 yeah     273
##  2 niggas    77
##  3 nigga     76
##  4 wanna     59
##  5 ooh       56
##  6 shit      55
##  7 fuck      53
##  8 love      50
##  9 nah       49
## 10 uh        43
## # … with 1,196 more rows
wordcloud2(boogie_words)
Sentiment & Valence
boogie %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> boogie_afinn
## Joining, by = "word"
## Joining, by = "word"
boogie_afinn
## # A tibble: 133 x 3
##    word        n value
##    <chr>   <int> <dbl>
##  1 yeah      273     1
##  2 niggas     77    -5
##  3 shit       55    -4
##  4 fuck       53    -4
##  5 love       50     3
##  6 bitch      42    -5
##  7 bitches    38    -5
##  8 swear      22    -2
##  9 block      13    -1
## 10 dick       13    -4
## # … with 123 more rows
mean(boogie_afinn$value)
## [1] -0.8421053
boogie %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> boogie_bing
## Joining, by = "word"
## Joining, by = "word"
boogie_bing
## # A tibble: 164 x 3
##    word       n sentiment
##    <chr>  <int> <chr>    
##  1 shit      55 negative 
##  2 fuck      53 negative 
##  3 love      50 positive 
##  4 bitch     42 negative 
##  5 dick      13 negative 
##  6 afraid    11 negative 
##  7 mad       10 negative 
##  8 bad        9 negative 
##  9 fun        9 positive 
## 10 hang       9 negative 
## # … with 154 more rows
boogie %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

hoodie <- get_artist_audio_features('A Boogie Wit da Hoodie')

hoodie %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Hoodie SZN")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0693

Danceability
hoodie %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Hoodie SZN")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.026

Energy
hoodie %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("Hoodie SZN")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0413

Key
hoodie %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Luke Combs: “This One’s For You”

The number eleven album is Luke Comb’s “This One’s for You”. It released in June 2017 and is considered Country.

luke <-genius_album(artist = "Luke Combs", album = "This-one-s-for-you")
## Joining, by = c("track_title", "track_n", "track_url")
luke %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE) -> luke_words
## Joining, by = "word"
luke_words
## # A tibble: 528 x 2
##    word        n
##    <chr>   <int>
##  1 time       23
##  2 hit        15
##  3 yeah       15
##  4 beer       14
##  5 gonna      12
##  6 couple     10
##  7 song       10
##  8 bet         9
##  9 heart       9
## 10 singing     9
## # … with 518 more rows
wordcloud2(luke_words)
luke %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("afinn"))-> luke_afinn
## Joining, by = "word"
## Joining, by = "word"
luke_afinn
## # A tibble: 64 x 3
##    word        n value
##    <chr>   <int> <dbl>
##  1 yeah       15     1
##  2 crazy       5    -2
##  3 feeling     5     1
##  4 god         5     1
##  5 lost        5    -3
##  6 won         5     3
##  7 careful     4     2
##  8 lonely      4    -2
##  9 afraid      3    -2
## 10 broken      3    -1
## # … with 54 more rows
mean(luke_afinn$value)
## [1] -0.328125
luke %>% 
  unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
   count(word, sort = TRUE)%>% 
  inner_join(get_sentiments("bing"))-> luke_bing
## Joining, by = "word"
## Joining, by = "word"
luke_bing
## # A tibble: 74 x 3
##    word        n sentiment
##    <chr>   <int> <chr>    
##  1 crazy       5 negative 
##  2 lose        5 negative 
##  3 lost        5 negative 
##  4 won         5 positive 
##  5 lonely      4 negative 
##  6 afraid      3 negative 
##  7 break       3 negative 
##  8 broken      3 negative 
##  9 bust        3 negative 
## 10 confess     3 negative 
## # … with 64 more rows
luke %>% 
 unnest_tokens(word,lyric) %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments("bing")) %>% 
  count(word, sentiment, sort = TRUE) %>% 
  filter(n>3) %>% 
  ggplot(aes(reorder(word, n),n, fill = sentiment))+
  geom_col()+ coord_flip()+
  facet_wrap(~sentiment,scales = "free_y")
## Joining, by = "word"
## Joining, by = "word"

combs <- get_artist_audio_features('Luke Combs')

combs %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("This One's for You")) %>% 
  ggplot(aes(x = valence, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.101

Danceability
combs %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("This One's for You")) %>% 
  ggplot(aes(x = danceability, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.027

Energy
combs %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("This One's for You")) %>% 
  ggplot(aes(x = energy, y = album_name, fill = ..x..)) +
  geom_density_ridges_gradient()+
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0634

Key
combs %>% 
  count(key_mode, sort = TRUE) %>% 
  ggplot(aes(reorder(key_mode,n),n))+
  geom_col() + coord_flip()

Conclusion

Sentiment & Valence

Looking at all ten albums, it is clear that many of them have similarities. One of which being sentiment and valence. Below I made a data frame that shows each album and its median afinn_score.

albums <- c("Hoodie SZN", "Championships","WHEN WE ALL FALL ASLEEP, WHERE DO WE GO", "Hollywood's Bleeding", "ASTROWORLD","beerbongs & bentleys", "Thank U, Next", "Lover","This One's For You", "Scorpion")
afinn_score <- c("-0.84","-0.80", "-0.73", "-0.72", "-0.71", "-0.53", "-0.5", "-0.42", "-0.33",  "-0.29")

album_afinn <- data.frame(albums, afinn_score)

album_afinn
##                                     albums afinn_score
## 1                               Hoodie SZN       -0.84
## 2                            Championships       -0.80
## 3  WHEN WE ALL FALL ASLEEP, WHERE DO WE GO       -0.73
## 4                     Hollywood's Bleeding       -0.72
## 5                               ASTROWORLD       -0.71
## 6                     beerbongs & bentleys       -0.53
## 7                            Thank U, Next        -0.5
## 8                                    Lover       -0.42
## 9                       This One's For You       -0.33
## 10                                Scorpion       -0.29

Clearly most of the albums have a pretty negative score with only 3 out of 10 being over -0.5. Half of the albums are below -0.7 which shows that most successful albums, according to Billboard, have negative words. This information has to be taken with a grain of salt. Some of the words that have a negative afinn score such as “crazy” are not necessarily bad words. Many times the word crazy is used as an adjective like saying one is crazy in love. Many of these albums are also very explicit in nature. Curse words have a negative afinn score and in many albums profanities are within the top ten most used words. This causes for many albums to be perceived as more negative than they are.

Another thing to take into account is the number of times certain words are said. In the case of Drake’s album ‘Scorpion’, the average afinn score is relatively high meaning it is a more positive album. It was even considered the most positive in regards to afinn scoring. However, Drake’s top word used was “yeah” which has an afinn score of 1 and was said 117 times. The second most used word was “shit” which has an afinn score of -4, but was only said 65 times. Even though “yeah” is often used as a filler word in music, it was said almost twice the amount of times as the second most used word. Therefore, the averages can be thrown off by outliers which ultimately affect the total average.

The next comparison I made was between the amount of positive and negative words. As said before, afinn score averages could have been skewed due to the amount of times they showed up; so, I also looked at the sentiment of the top words individually. The top ten words from each album were given a bing score of either negative or positive. I then calculated a ratio of the amount of positive words to negative words.

albums2 <- c("WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?", "Thank U, Next", "Lover", "beerbongs & bentleys", "Scorpion", "Championships", "ASTROWORLD", "Hollywood's Bleeding", "Hoodie SZN", "This One's for You")

ratio <- c("2/10", "3/10", "7/10", "3/10", "3/10", "4/10", "4/10", "2/10", "2/10", "1/10")

positive_ratio <- data.frame(albums2,ratio)

positive_ratio
##                                     albums2 ratio
## 1  WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?  2/10
## 2                             Thank U, Next  3/10
## 3                                     Lover  7/10
## 4                      beerbongs & bentleys  3/10
## 5                                  Scorpion  3/10
## 6                             Championships  4/10
## 7                                ASTROWORLD  4/10
## 8                      Hollywood's Bleeding  2/10
## 9                                Hoodie SZN  2/10
## 10                       This One's for You  1/10

Minus one outlier of Taylor Swift’s album ‘Lover’, all of the other album’s top ten words have less than 5 positive words. This means that when listening to the albums, people will hear many negative words. Combining this information with the afinn scores, it shows that many populat albums use negative words. This does not necessarily mean that the songs themselves are negative, just the wording.

Context surrounding the words is important to look at to determine if the songs are actually negatve. Using a valence density graph, I analyzed each album individually and combined them together in the graph below.

eilish %>% 
  group_by(album_name) %>% 
  filter(album_name %in% c("WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?")) -> eilish2

grande %>%
  group_by(album_name) %>%
  filter(album_name %in% c("thank u, next"))  -> grande2

swift %>% 
group_by(album_name) %>%
  filter(album_name %in% c("Lover"))  -> swift2   

malone %>% 
  group_by(album_name) %>%
  filter(album_name %in% c("beerbongs & bentleys"))  -> malone3

dr_ake %>% 
  group_by(album_name) %>%
  filter(album_name %in% c("Scorpion"))  -> dr_ake2

mill %>% 
  group_by(album_name) %>%
  filter(album_name %in% c("Championships"))  ->mill2

scott %>% 
group_by(album_name) %>%
  filter(album_name %in% c("ASTROWORLD"))  -> scott2

malone2 %>% 
  group_by(album_name) %>%
  filter(album_name %in% c("Hollywood's Bleeding"))  -> malone4

hoodie %>% 
  group_by(album_name) %>%
  filter(album_name %in% c("Hoodie SZN"))  -> hoodie2

combs %>% 
  group_by(album_name) %>%
  filter(album_name %in% c("This One's for You"))  -> combs2



rbind(eilish2, grande2, swift2, malone3, dr_ake2, mill2, scott2, malone4, hoodie2, combs2) %>%
  ggplot(aes(x = valence, y = album_name, fill = album_name)) +
  geom_density_ridges_gradient() +
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0791

Spanning across five different genres, it is clear that top albums are relatively negative. While there are positive aspects, the main peaks in every album rise at .50 or below. A lot of Rap/Hip-Hop music is about coming up from hard times, and a lot of Pop and Country music is about heartbreak and the one that got away. This shows that audiences like to hear about hard times. All ten albums have had similarities between their afinn scores, bing scores, and valence. All three show that the biggest albums of 2019 were all negative. This does not mean that a positive album will not be popular at times. This just shows to make a successful album in the eyes of mainstream media, the words and content should be negative/tough overall.

Danceability

The content of the songs is not the only important aspect that makes up a top album. The density graph below shows how danceable each of the ten albums is.

rbind(eilish2, grande2, swift2, malone3, dr_ake2, mill2, scott2, malone4, hoodie2, combs2) %>%
  ggplot(aes(x = danceability, y = album_name, fill = album_name)) +
  geom_density_ridges_gradient() +
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0594

Luke Combs’s album ‘This One’s for You’, the only country album, is split on the halfway mark of being danceable. Billie Eilish’s ‘WHEN WE ALL FALL ASLEEP, WHERE DO WE GO?’ has a large range between danceable and not. With that said, the majority of the albums are considered very danceable. Danceability may play into how much an album is played. More danceable songs will be played at parties and social gatherings as well as used for dance trends on apps such as Tik Tok and Instagram. Most of the peaks are around the 0.75 mark which shows that the majority of the songs on each album are danceable. To make a popular album, in addition to having more negative content, many of the songs should be danceable.

Energy

Energy is another aspect that I looked at. Similar to danceability, energetic songs tend to be more popular so I wanted to see if the top albums had any similarities in energy.

rbind(eilish2, grande2, swift2, malone3, dr_ake2, mill2, scott2, malone4, hoodie2, combs2) %>%
  ggplot(aes(x = energy, y = album_name, fill = album_name)) +
  geom_density_ridges_gradient() +
  xlim(0,1)+
  theme(legend.position = "none")
## Picking joint bandwidth of 0.0593

The graph shows more variety between the albums, but the majority have relatively high energy songs. The albums individually have a range of energetic and not energetic songs. This shows that while songs may be similar, successful albums are more dynamic and have some differences between songs. However, these successful albums have more energetic songs than not. This excludes Billie Eilish’s album which is the complete opposite. Either way, the albums in general skew to one side or the other. For similar reasons for danceability, high energy songs are great for social gatherings, online trends, playing in the gym, or the car on the radio. Many hit songs are high energy because they make people feel good. In all, successful albums are dynamic in their energy but the majority of the most popular ones have a good amount of high energy songs.

Key

The final aspect that I looked at was the key signatures in each album. I made a separate data frame with the top key signature used from each album.

key <- c("G# Major", "F# Major", "G Major", "C Major", "C# Major", "C# Major", "F Minor", "C Minor", "G Minor", "C# Major")

album_key <- data.frame(albums2, key)

album_key
##                                     albums2      key
## 1  WHEN WE ALL FALL ASLEEP, WHERE DO WE GO? G# Major
## 2                             Thank U, Next F# Major
## 3                                     Lover  G Major
## 4                      beerbongs & bentleys  C Major
## 5                                  Scorpion C# Major
## 6                             Championships C# Major
## 7                                ASTROWORLD  F Minor
## 8                      Hollywood's Bleeding  C Minor
## 9                                Hoodie SZN  G Minor
## 10                       This One's for You C# Major

The majority of the albums use the major key more. The major key tends to sound happier and that could play into how many of the albums are considered danceable and higher energy. C# major is the most popular one used and it appears the most in the Rap/Hip-Hop and Country genres. Therefore, another attribute to a successful album is having most songs in the major key.

From Rap/Hip-Hop to Pop to Country, there are many similarities between the top ten albums of 2019 according to Billboard. The albums have a more negative sentiment. They use negative words, including profanities, more often than others. The overall valence of the albums is mostly negative meaning the subject matter is not completely optimistic. A lot of the songs on the albums are danceable and higher energy. This means that they will probably be used more in videos, social gatherings, and social media. Many hit songs are high energy and danceable and people are more likely to listen to an album if there are songs on it similar to the hits they know and love. Finally, a lot of the songs are in the major key, more specifically C# major.

All of these aspects are not guaranteed to make a top 10 album. Many of these artists have established a name for themselves already. Some of the albums were even released in 2018 and it took over a year for them to gain traction. With all that said, there are some strong similarities between all of the albums. They pertain to different genres and artists. A lot goes into creating a successful album, but having these elements may create a strong foundation to start with.