Chance the Rapper Sentiment Analysis

Chance the Rapper has had his music career followed criticially since his debut mix tape, “10 Day”, from 2012. He has followed this up with the albums Acid Rap, Coloring Book, and The Big Day. In recent years, fans of his have noted a significant change in quality and tone of his music over the years. This text analysis of Chance the Rapper’s four biggest works will try to calculate if these claims have any merit. This will look at the overall sentiment of each album, along with comparing the most frequently used words in comparison to the other pieces of work.

This will begin with installing all of the required files, scraping the lyrics and assigning those lyrics to groups that can be analyzed.

#install.packages("rjson")
#install.packages("json")
library(jsonlite)
library(tidyverse)
#install.packages('tidytext')
library(tidytext)
library(textdata)


thebigday <- fromJSON("~/desktop/lyrics_TheBigDay.json")
coloringbook <- fromJSON("~/desktop/lyrics_ColoringBook.json")
tenday <- fromJSON("~/desktop/lyrics_10Day.json")
acidrap <- fromJSON("~/desktop/lyrics_AcidRap.json")

Most Common Words

The first step was to look at the most common words of each album and see how many times those words were used. The first album looked at was The Big Day.

as.data.frame(thebigday$tracks$song) -> thebigday_df


thebigday_words <- thebigday_df %>% 
  unnest_tokens(word, lyrics) 
  thebigday_words %>% count(word, sort = TRUE) %>% 
    anti_join(stop_words) %>% 
    head(25) %>% 
    filter(!word %in% c("verse", "1", "chorus", "2", "3"))
##       word   n
## 1     yeah 138
## 2   chance  83
## 3   rapper  79
## 4   single  67
## 5      ooh  66
## 6     love  54
## 7     time  46
## 8     baby  41
## 9      bag  39
## 10 forever  37
## 11     die  36
## 12     day  34
## 13    step  33
## 14   slide  30
## 15      uh  30
## 16  people  29
## 17     god  27
## 18     yuh  24
## 19   wanna  23
## 20     ayy  21
## 21     gon  21
## 22   gotta  21

The next album looked at and its most common words was Coloring Book.

as.data.frame(coloringbook$tracks$song) -> coloringbook_df

coloringbook_words <- coloringbook_df %>% 
  unnest_tokens(word, lyrics)
coloringbook_words %>% count(word, sort = TRUE) %>% 
  anti_join(stop_words) %>% 
  head(25) %>% 
  filter(!word %in% c("verse", "1", "chorus", "2", "3"))
##         word  n
## 1     chance 64
## 2     rapper 64
## 3      ready 44
## 4      night 36
## 5  blessings 34
## 6        god 33
## 7        ayy 28
## 8   drinking 28
## 9        bom 27
## 10       gon 27
## 11   deserve 25
## 12     drugs 25
## 13  citywide 24
## 14        na 24
## 15   friends 23
## 16      79th 22
## 17       huh 21
## 18       hey 20
## 19      juke 18
## 20      time 17
## 21     wanna 17
## 22    praise 16

Many standout words were more positive, such as “blessings”, “ready”, and “god”. The next album looked at was 10 Day.

as.data.frame(tenday$tracks$song) -> tenday_df

tenday_words <- tenday_df %>% 
  unnest_tokens(word, lyrics)
tenday_words %>% count(word, sort = TRUE) %>% 
  anti_join(stop_words) %>% 
  head(25) %>% 
  filter(!word %in% c("verse", "1", "chorus", "2", "3"))
##       word   n
## 1     juke 110
## 2     fuck  98
## 3     bout  69
## 4    nigga  62
## 5     tahm  62
## 6     time  38
## 7     mama  37
## 8    break  32
## 9   niggas  32
## 10    shit  32
## 11   brain  27
## 12   cells  27
## 13  burned  24
## 14  chance  24
## 15     day  22
## 16     gon  19
## 17     chi  18
## 18 fucking  18
## 19  rapper  18
## 20     fam  17
## 21    love  17
## 22     til  17
## 23    town  17

Swear words covered the most common words in this album. There was a strong difference in the type of language used from the Coloring Book and 10 Day. The last album is Acid Rap.

as.data.frame(acidrap$tracks$song) -> acidrap_df

acidrap_words <- acidrap_df %>% 
  unnest_tokens(word, lyrics)
acidrap_words %>% count(word, sort = TRUE) %>% 
  anti_join(stop_words) %>% 
  head(25) %>% 
  filter(!word %in% c("verse", "1", "chorus", "2", "3"))
##          word   n
## 1          na 119
## 2      chance  59
## 3        love  59
## 4      rapper  58
## 5       juice  53
## 6        shit  51
## 7        yeah  49
## 8         jam  48
## 9      kisses  40
## 10      smoke  34
## 11        ooh  33
## 12        igh  31
## 13       fuck  29
## 14       bout  27
## 15      bitch  24
## 16      nigga  21
## 17       miss  20
## 18     niggas  20
## 19 cigarettes  19
## 20       talk  19
## 21       time  19
## 22     butter  18
## 23      cocoa  18

Acid Rap had a variety of positive and negative words in the most common list.

Word Clouds

The next step to better visualize the words used in these albums was to create a word cloud of the most common words. This began with downloading the required packages to make a word cloud.

#install.packages("wordcloud")
library(wordcloud2)
library(devtools)
#install.packages("devtools")

#install_github('lchiffon/wordcloud2')

The first album to look at in the cloud is The Big Day.

thebigday_words %>%
  anti_join(stop_words) %>% 
  count(word, sort = TRUE) %>% 
  filter(!word %in% c("verse", "1", "chorus", "2", "3")) %>% 
  head(50) %>% 
  wordcloud2()

The next album is Coloring Book.

coloringbook_words %>% 
  anti_join(stop_words) %>% 
  count(word, sort = TRUE) %>% 
  filter(!word %in% c("verse", "1", "chorus", "2", "3")) %>% 
  head(50) %>% 
  wordcloud2()

Next up is 10 Day.

tenday_words %>% 
  anti_join(stop_words) %>% 
  count(word, sort = TRUE) %>% 
  filter(!word %in% c("verse", "1", "chorus", "2", "3")) %>% 
  head(50) %>% 
  wordcloud2()

The last word cloud is for Acid Rap.

acidrap_words %>% 
  anti_join(stop_words) %>% 
  count(word, sort = TRUE) %>% 
  filter(!word %in% c("verse", "1", "chorus", "2", "3")) %>% 
  head(50) %>% 
  wordcloud2()

Sentiment Analysis

To properly determine if the albums were overall more positive or negative with their language usage, this code was used to rank every word on a -5 to 5 scale with the more hateful words being closer to a -5 and the happier words being closer to 5 with neutral words falling closer to 0. An overall count was factored in to rank how many positive and negative words were included in the albums.

Here is the sentiment analysis for The Big Day.

thebigday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(-value)) %>% 
  head(25)
##        word value  n
## 1    niggas    -5 17
## 2     bitch    -5 10
## 3   bitches    -5  2
## 4      cock    -5  1
## 5      fuck    -4 19
## 6      shit    -4 16
## 7      damn    -4 11
## 8       ass    -4  6
## 9  bullshit    -4  2
## 10     dick    -4  1
## 11   fucked    -4  1
## 12  fucking    -4  1
## 13   pissed    -4  1
## 14      die    -3 36
## 15      bad    -3 14
## 16     dead    -3  2
## 17     fake    -3  2
## 18    cheat    -3  1
## 19   cheats    -3  1
## 20    cruel    -3  1
## 21   damage    -3  1
## 22     died    -3  1
## 23   faking    -3  1
## 24  goddamn    -3  1
## 25     hate    -3  1
thebigday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(value)) %>% 
  head(25)
##         word value  n
## 1        win     4  1
## 2       love     3 54
## 3      super     3  5
## 4       glad     3  4
## 5     excite     3  2
## 6        fan     3  2
## 7   grateful     3  2
## 8     lovely     3  2
## 9    perfect     3  2
## 10 celebrate     3  1
## 11  goodness     3  1
## 12     grand     3  1
## 13     lucky     3  1
## 14   popular     3  1
## 15       woo     3  1
## 16    chance     2 83
## 17     worth     2 15
## 18       hug     2  8
## 19     sweet     2  7
## 20       top     2  7
## 21      fine     2  4
## 22      kiss     2  4
## 23     proud     2  4
## 24      true     2  4
## 25     clean     2  3
thebigday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value < 0) %>% 
  count()
##     n
## 1 317
thebigday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value > 0) %>% 
  count()
##     n
## 1 470

It is important to note that in this album, the word love was used significantly more than any of the overwhelmingly negative swear words. Overall, there were 317 repeated negative words in this album, but that was shadowed by the 470 positive words.

Here is the same code ran on Coloring Book.

coloringbook_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(-value)) %>% 
  head(25)
##       word value  n
## 1    bitch    -5 15
## 2   niggas    -5  9
## 3  bitches    -5  4
## 4     fuck    -4 14
## 5     shit    -4 11
## 6     damn    -4  6
## 7     hell    -4  3
## 8   fucked    -4  2
## 9      ass    -4  1
## 10    dick    -4  1
## 11     bad    -3  9
## 12    lost    -3  5
## 13     die    -3  2
## 14    kill    -3  2
## 15 worried    -3  2
## 16   cheat    -3  1
## 17   crime    -3  1
## 18    died    -3  1
## 19  faking    -3  1
## 20     mad    -3  1
## 21   worry    -3  1
## 22   drown    -2  6
## 23   swear    -2  5
## 24   crazy    -2  4
## 25   lobby    -2  3
coloringbook_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(value)) %>% 
  head(25)
##           word value  n
## 1      miracle     4 11
## 2          win     4  1
## 3       praise     3 16
## 4         love     3 12
## 5      praises     3 10
## 6         haha     3  9
## 7          woo     3  8
## 8        happy     3  2
## 9      perfect     3  2
## 10 blockbuster     3  1
## 11       charm     3  1
## 12         fan     3  1
## 13       grand     3  1
## 14     loyalty     3  1
## 15       lucky     3  1
## 16        nice     3  1
## 17  successful     3  1
## 18       super     3  1
## 19      chance     2 64
## 20        care     2 11
## 21        true     2  5
## 22          ha     2  4
## 23     freedom     2  3
## 24       smile     2  3
## 25      worthy     2  3
coloringbook_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value < 0) %>% 
  count()
##     n
## 1 181
coloringbook_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value > 0) %>% 
  count()
##     n
## 1 297

Coloring Book follows the same trend as The Big Day where there are significantly more positive words used than negative with that being 297 to 181. This would meet the expectations of fans that assumed these two albums had much more positive themes than 10 Day and Acid Rap.

tenday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(-value)) %>% 
  head(25)
##        word value  n
## 1    niggas    -5 32
## 2     bitch    -5  9
## 3   bitches    -5  1
## 4     prick    -5  1
## 5      fuck    -4 98
## 6      shit    -4 32
## 7   fucking    -4 18
## 8       ass    -4 14
## 9    fucked    -4 11
## 10     dick    -4  3
## 11     damn    -4  2
## 12  asshole    -4  1
## 13  torture    -4  1
## 14  worried    -3  8
## 15      bad    -3  7
## 16     lost    -3  3
## 17     fake    -3  2
## 18      mad    -3  2
## 19 arrested    -3  1
## 20    awful    -3  1
## 21     dead    -3  1
## 22      die    -3  1
## 23     dumb    -3  1
## 24   haters    -3  1
## 25    idiot    -3  1
tenday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(value)) %>% 
  head(25)
##            word value  n
## 1         funny     4  9
## 2           fun     4  3
## 3          love     3 17
## 4          nice     3  3
## 5          luck     3  2
## 6        classy     3  1
## 7           fan     3  1
## 8          glad     3  1
## 9          haha     3  1
## 10        loved     3  1
## 11       lovely     3  1
## 12      loyalty     3  1
## 13       chance     2 24
## 14        smile     2 10
## 15         hope     2  9
## 16       hoping     2  7
## 17        saved     2  7
## 18         save     2  6
## 19       favors     2  4
## 20         true     2  3
## 21         fair     2  2
## 22       smiles     2  2
## 23 accomplished     2  1
## 24  comfortable     2  1
## 25     enjoying     2  1
tenday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value < 0) %>% 
  count()
##     n
## 1 338
tenday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value > 0) %>% 
  count()
##     n
## 1 184

10 Day flips back the complete opposite way. There are 338 words with negative sentiment with only 184 positive words used.

acidrap_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(-value)) %>% 
  head(25)
##             word value  n
## 1          bitch    -5 24
## 2         niggas    -5 20
## 3        bitches    -5  3
## 4  motherfucking    -5  3
## 5   motherfucker    -5  1
## 6           shit    -4 51
## 7           fuck    -4 29
## 8            ass    -4 14
## 9        fucking    -4  9
## 10          damn    -4  8
## 11          dick    -4  7
## 12       asshole    -4  1
## 13      bullshit    -4  1
## 14        fucked    -4  1
## 15        fucker    -4  1
## 16          hell    -4  1
## 17        pissed    -4  1
## 18          lost    -3 11
## 19           bad    -3  4
## 20       goddamn    -3  4
## 21          ugly    -3  4
## 22          dead    -3  3
## 23           die    -3  3
## 24          hate    -3  3
## 25          died    -3  2
acidrap_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  count(word, value, sort = TRUE) %>% 
  arrange(desc(value)) %>% 
  head(25)
##         word value  n
## 1        win     4  1
## 2       love     3 59
## 3      lucky     3  3
## 4  beautiful     3  2
## 5       glad     3  2
## 6     hahaha     3  2
## 7      happy     3  2
## 8       nice     3  2
## 9     praise     3  2
## 10    classy     3  1
## 11      haha     3  1
## 12 happiness     3  1
## 13       joy     3  1
## 14    chance     2 59
## 15      hope     2  7
## 16  favorite     2  6
## 17       hug     2  6
## 18    hoping     2  3
## 19      save     2  3
## 20    loving     2  2
## 21     proud     2  2
## 22      avid     2  1
## 23      care     2  1
## 24   chances     2  1
## 25     clean     2  1
acidrap_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value < 0) %>% 
  count()
##     n
## 1 362
acidrap_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) %>% 
  filter(value > 0) %>% 
  count()
##     n
## 1 278

With Acid Rap, one of the most used words, “love”, is overwhelmingly positive, but overall the album has much more negative words than positive. There were 362 negative words in comparison to 278 positive words in Acid Rap. It is not as polar as the other albums, but still more negative than positive.

Average Sentiment

The last step of this analysis is to determine the average sentiment of each album and compare the mean value of every word used.

thebigday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) -> thebigday_sentiment

mean(thebigday_sentiment$value)
## [1] -0.02541296
coloringbook_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) -> coloringbook_sentiment

mean(coloringbook_sentiment$value)
## [1] 0.1338912
tenday_words %>% 
  anti_join(stop_words) %>% 
  inner_join(get_sentiments('afinn')) -> tenday_sentiment

mean(tenday_sentiment$value)
## [1] -1.528736
acidrap_words %>%
  anti_join(stop_words) %>%
  inner_join(get_sentiments('afinn')) -> acidrap_sentiment

mean(acidrap_sentiment$value)
## [1] -0.9046875

Comparing the average sentiment of each album resulted in a similar conclusion that most fans had already assumed. 10 Day and Acid Rap are much more negative albums with an average sentiment of -1.5 and -0.9 respectively. The surprising outcome is that The Big Day landed just under 0 with a sentiment of -0.025. What was seen as an almost too positive album, had an overall average in the negative. Coloring Book followed what was expected with an average sentiment of 0.13.

Conclusion

When comparing the sentiment of each Chance the Rapper album, it can be seen that there were clear changes in his themes and overall positivity over time. The first two works he put out were significantly more negative than his two most recent projects. Fans have speculated over this for years, but the numbers back up the ideas of a new Chance the Rapper in comparison to the one who was trying to make it in the music industry. The clearest outliar would be the average sentiment of The Big Day, which was seen as an album that was too happy and too positive by the fans, and yet the average sentiment of the language used was in the negative.