Sir Robert Bryson Hall II, better known as Logic, is an American rapper, singer, songwriter and record producer. He is best known for his creative conceptual albums and broad range of music. This analysis will generate the different sentiments from each of his 8 albums. Logic is known to discuss topics raning from mental health and race to drugs and partying so because of this, it is predicted that his albums will have an overall negative sentiment.
Step One: To run the genius package and select the first Logic album, Under Pressure
library(genius)
genius_album(artist = "logic", album = "under pressure") ->logic_pressure
## Joining, by = c("track_title", "track_n", "track_url")
Step Two: Filter out stop words and sort the remaining by number of appearances
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()
library(tidytext)
logic_pressure %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_pressure
## Joining, by = "word"
tidy_pressure
## # A tibble: 1,160 x 2
## word n
## <chr> <int>
## 1 yeah 69
## 2 shit 50
## 3 feel 48
## 4 fuck 44
## 5 na 36
## 6 uh 32
## 7 love 29
## 8 mind 26
## 9 fame 25
## 10 gotta 25
## # … with 1,150 more rows
Step Three: Create a custom stop words list
stopWords <- c("yeah", "na", "uh", "gotta", "i'ma", "wanna", "em")
stopWordsDF <- tibble(stopWords)
Step Four: Remove the remaining unwanted words
tidy_pressure1 <- tidy_pressure %>%
anti_join(stopWordsDF, by = c("word" = "stopWords"))
tidy_pressure1
## # A tibble: 1,153 x 2
## word n
## <chr> <int>
## 1 shit 50
## 2 feel 48
## 3 fuck 44
## 4 love 29
## 5 mind 26
## 6 fame 25
## 7 life 24
## 8 bitch 22
## 9 god 21
## 10 hit 18
## # … with 1,143 more rows
Step Five: Generate a numbered sentiment from -5 to 5 for each word
tidy_pressure1afinn <- tidy_pressure1 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_pressure1afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 shit 50 -4
## 2 fuck 44 -4
## 3 love 29 3
## 4 fame 25 1
## 5 bitch 22 -5
## 6 god 21 1
## 7 alive 14 1
## 8 hard 13 -1
## 9 crazy 11 -2
## 10 bitches 10 -5
Step Six: Create a wordcloud of all words
library(wordcloud2)
##install.packages("devtools")
library(devtools)
## Loading required package: usethis
##install_github("gaospecial/wordcloud2")
wordcloud2(tidy_pressure1)
This process was then repeated for each album.
genius_album(artist = "logic", album = "the incredible true story") -> logic_story
## Joining, by = c("track_title", "track_n", "track_url")
logic_story %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_story
## Joining, by = "word"
tidy_story
## # A tibble: 1,356 x 2
## word n
## <chr> <int>
## 1 yeah 82
## 2 fuck 52
## 3 life 45
## 4 shit 43
## 5 uh 39
## 6 em 38
## 7 fade 35
## 8 hold 31
## 9 love 26
## 10 people 26
## # … with 1,346 more rows
stopWords1 <- c("uh", "em", "yeah")
stopWordsDF1 <- tibble(stopWords1)
tidy_story1 <- tidy_story %>%
anti_join(stopWordsDF1, by = c("word" = "stopWords1"))
tidy_story1
## # A tibble: 1,353 x 2
## word n
## <chr> <int>
## 1 fuck 52
## 2 life 45
## 3 shit 43
## 4 fade 35
## 5 hold 31
## 6 love 26
## 7 people 26
## 8 bitch 21
## 9 day 21
## 10 feel 21
## # … with 1,343 more rows
tidy_story1afinn <- tidy_story1 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_story1afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 fuck 52 -4
## 2 shit 43 -4
## 3 love 26 3
## 4 bitch 21 -5
## 5 paradise 13 3
## 6 damn 12 -4
## 7 god 11 1
## 8 goddamn 10 -3
## 9 wrong 10 -2
## 10 doubt 9 -1
library(wordcloud2)
wordcloud2(tidy_story1)
genius_album(artist = "logic", album = "bobby tarantino") -> logic_bt
## Joining, by = c("track_title", "track_n", "track_url")
logic_bt %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_bt
## Joining, by = "word"
tidy_bt
## # A tibble: 771 x 2
## word n
## <chr> <int>
## 1 shit 98
## 2 yeah 65
## 3 god 49
## 4 money 48
## 5 fuck 37
## 6 goodness 34
## 7 deeper 32
## 8 hey 29
## 9 killin 21
## 10 flickin 18
## # … with 761 more rows
stopWords2 <- c("hey", "yeah")
stopWordsDF2 <- tibble(stopWords2)
tidy_bt1 <- tidy_bt %>%
anti_join(stopWordsDF2, by = c("word" = "stopWords2"))
tidy_bt1
## # A tibble: 769 x 2
## word n
## <chr> <int>
## 1 shit 98
## 2 god 49
## 3 money 48
## 4 fuck 37
## 5 goodness 34
## 6 deeper 32
## 7 killin 21
## 8 flickin 18
## 9 life 17
## 10 motherfucker 17
## # … with 759 more rows
tidy_bt1afinn <- tidy_bt1 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_bt1afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 shit 98 -4
## 2 god 49 1
## 3 fuck 37 -4
## 4 goodness 34 3
## 5 motherfucker 17 -5
## 6 bitch 13 -5
## 7 hard 12 -1
## 8 fucking 8 -4
## 9 happy 8 3
## 10 damn 7 -4
wordcloud2(tidy_bt1)
genius_album(artist = "logic", album = "everybody") -> logic_evb
## Joining, by = c("track_title", "track_n", "track_url")
logic_evb %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_evb
## Joining, by = "word"
tidy_evb
## # A tibble: 1,147 x 2
## word n
## <chr> <int>
## 1 black 94
## 2 mind 77
## 3 god 68
## 4 wanna 68
## 5 people 66
## 6 shit 64
## 7 i'ma 55
## 8 feel 51
## 9 life 50
## 10 atom 48
## # … with 1,137 more rows
stopWords3 <- c("i'ma")
stopWordsDF3 <- tibble(stopWords3)
tidy_evb1 <- tidy_evb %>%
anti_join(stopWordsDF3, by = c("word" = "stopWords3"))
tidy_evb1
## # A tibble: 1,146 x 2
## word n
## <chr> <int>
## 1 black 94
## 2 mind 77
## 3 god 68
## 4 wanna 68
## 5 people 66
## 6 shit 64
## 7 feel 51
## 8 life 50
## 9 atom 48
## 10 fuck 40
## # … with 1,136 more rows
tidy_evb1afinn <- tidy_evb1 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_evb1afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 god 68 1
## 2 shit 64 -4
## 3 fuck 40 -4
## 4 yeah 36 1
## 5 feeling 32 1
## 6 love 25 3
## 7 fight 22 -1
## 8 ass 16 -4
## 9 bitch 16 -5
## 10 die 16 -3
wordcloud2(tidy_evb1)
genius_album(artist = "logic", album = "bobby tarantino ii") -> logic_bt2
## Joining, by = c("track_title", "track_n", "track_url")
logic_bt2 %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_bt2
## Joining, by = "word"
tidy_bt2
## # A tibble: 966 x 2
## word n
## <chr> <int>
## 1 yeah 127
## 2 shit 96
## 3 fuck 47
## 4 em 44
## 5 bitch 43
## 6 bobby 30
## 7 logic 30
## 8 life 28
## 9 morty 22
## 10 ay 20
## # … with 956 more rows
stopWords5 <- c("em", "ay", "yeah", "la", "woo")
stopWordsDF5 <- tibble(stopWords5)
tidy_bt21 <- tidy_bt2 %>%
anti_join(stopWordsDF5, by = c("word" = "stopWords5"))
tidy_bt21
## # A tibble: 961 x 2
## word n
## <chr> <int>
## 1 shit 96
## 2 fuck 47
## 3 bitch 43
## 4 bobby 30
## 5 logic 30
## 6 life 28
## 7 morty 22
## 8 money 20
## 9 feel 18
## 10 reason 18
## # … with 951 more rows
tidy_bt21afinn <- tidy_bt21 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_bt21afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 shit 96 -4
## 2 fuck 47 -4
## 3 bitch 43 -5
## 4 die 16 -3
## 5 hard 15 -1
## 6 fire 13 -2
## 7 leave 11 -1
## 8 love 11 3
## 9 trap 11 -1
## 10 warm 10 1
wordcloud2(tidy_bt21)
genius_album(artist = "logic", album = "ysiv") -> logic_ysiv
## Joining, by = c("track_title", "track_n", "track_url")
logic_ysiv %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_ysiv
## Joining, by = "word"
tidy_ysiv
## # A tibble: 2,167 x 2
## word n
## <chr> <int>
## 1 shit 108
## 2 yeah 107
## 3 love 57
## 4 day 53
## 5 uh 51
## 6 fuck 47
## 7 feel 44
## 8 em 39
## 9 gotta 39
## 10 life 39
## # … with 2,157 more rows
stopWords6 <- c("em", "uh", "yeah")
stopWordsDF6 <- tibble(stopWords6)
tidy_ysiv1 <- tidy_ysiv %>%
anti_join(stopWordsDF6, by = c("word" = "stopWords6"))
tidy_ysiv1
## # A tibble: 2,164 x 2
## word n
## <chr> <int>
## 1 shit 108
## 2 love 57
## 3 day 53
## 4 fuck 47
## 5 feel 44
## 6 gotta 39
## 7 life 39
## 8 ayo 37
## 9 time 37
## 10 sinatra 29
## # … with 2,154 more rows
tidy_ysiv1afinn <- tidy_ysiv1 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_ysiv1afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 shit 108 -4
## 2 love 57 3
## 3 fuck 47 -4
## 4 bitch 25 -5
## 5 alive 21 1
## 6 damn 16 -4
## 7 crazy 15 -2
## 8 die 14 -3
## 9 fucking 13 -4
## 10 hate 13 -3
wordcloud2(tidy_ysiv1)
genius_album(artist = "logic", album = "Supermarket") -> logic_super
## Joining, by = c("track_title", "track_n", "track_url")
logic_super %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_super
## Joining, by = "word"
tidy_super
## # A tibble: 379 x 2
## word n
## <chr> <int>
## 1 girl 34
## 2 na 33
## 3 yeah 33
## 4 baby 32
## 5 friend 26
## 6 world 22
## 7 guess 18
## 8 break 15
## 9 time 15
## 10 love 14
## # … with 369 more rows
stopWords7 <- c("na")
stopWordsDF7 <- tibble(stopWords7)
tidy_super1 <- tidy_super %>%
anti_join(stopWordsDF7, by = c("word" = "stopWords7"))
tidy_super1
## # A tibble: 378 x 2
## word n
## <chr> <int>
## 1 girl 34
## 2 yeah 33
## 3 baby 32
## 4 friend 26
## 5 world 22
## 6 guess 18
## 7 break 15
## 8 time 15
## 9 love 14
## 10 fall 13
## # … with 368 more rows
tidy_super1afinn <- tidy_super1 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_super1afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 yeah 33 1
## 2 love 14 3
## 3 pretty 13 1
## 4 promise 12 1
## 5 beautiful 11 3
## 6 shit 8 -4
## 7 risk 7 -2
## 8 drop 6 -1
## 9 free 6 1
## 10 fuck 6 -4
wordcloud2(tidy_super1)
genius_album(artist = "logic", album = "confessions of a dangerous mind") -> logic_cdm
## Joining, by = c("track_title", "track_n", "track_url")
logic_cdm %>%
unnest_tokens(word,lyric) %>%
anti_join(stop_words) %>%
count(word, sort = TRUE) -> tidy_cdm
## Joining, by = "word"
tidy_cdm
## # A tibble: 1,454 x 2
## word n
## <chr> <int>
## 1 shit 96
## 2 ballin 88
## 3 yeah 73
## 4 ayy 57
## 5 fuck 51
## 6 bobby 49
## 7 uh 49
## 8 icy 46
## 9 break 39
## 10 wanna 39
## # … with 1,444 more rows
stopWords8 <- c("ayy", "uh", "yeah")
stopWordsDF8 <- tibble(stopWords8)
tidy_cdm1 <- tidy_cdm %>%
anti_join(stopWordsDF8, by = c("word" = "stopWords8"))
tidy_cdm1
## # A tibble: 1,451 x 2
## word n
## <chr> <int>
## 1 shit 96
## 2 ballin 88
## 3 fuck 51
## 4 bobby 49
## 5 icy 46
## 6 break 39
## 7 wanna 39
## 8 clean 38
## 9 y'all 37
## 10 boy 33
## # … with 1,441 more rows
tidy_cdm1afinn <- tidy_cdm1 %>%
inner_join(get_sentiments("afinn")) %>%
head(10)
## Joining, by = "word"
tidy_cdm1afinn
## # A tibble: 10 x 3
## word n value
## <chr> <int> <dbl>
## 1 shit 96 -4
## 2 fuck 51 -4
## 3 clean 38 2
## 4 afraid 32 -2
## 5 bitch 29 -5
## 6 love 27 3
## 7 leave 21 -1
## 8 damn 19 -4
## 9 motherfucker 15 -5
## 10 stop 13 -1
wordcloud2(tidy_cdm1)
Clearly Logic has an overall negative sentiment when analyzing his lyrics. By taking the afinn score of the top ten words in each album, an overall number score can be generated to easily compare each of them.
score <- c("-25", "-21", "-20", "-17", "-16", "-15", "-6", "-1")
album <- c("YSIV", "Confessions of a Dangerous Mind", "Bobby Tarantino", "Bobby Tarantino II", "The Incredible True Story", "Under Pressure", "Everybody", "Supermarket")
albumscore <- data.frame(score, album)
albumscore
## score album
## 1 -25 YSIV
## 2 -21 Confessions of a Dangerous Mind
## 3 -20 Bobby Tarantino
## 4 -17 Bobby Tarantino II
## 5 -16 The Incredible True Story
## 6 -15 Under Pressure
## 7 -6 Everybody
## 8 -1 Supermarket
Looking at Logic’s overall sentiment, it is clear that it is mainly negative. There is one exception being the album Supermarket. This is because Logic published a book of the same name and released this album to accompany it. The book is a love story, which strays from the usual topics that Logic raps about. Besides this album, Logic’s albums can be considered extremely negative.
The most frequent words that Logic uses are derogatory. Each slur created a -4 or -5 rating which heavily impacted the albums overall sentiment. There were also many words that could not be analyzed. For instance, in the album Everybody, Logic talks a lot about God and and his experience being biracial. Two of the top three words in that album were ‘god’ and ‘black’. These words taken out of context cannot have a sentiment analysis therefore they could not contribute to the overall sentiment. In fact, this is why most of his albums seems so negative. Taken out of context and analyzed individually, Logic’s lyrics are very crass and explicit. However, when listening to the songs as a whole it is clear that Logic is a pretty positive person. He takls about tough issues like mental health and racial issues which have negative sentiments. Logic also likes to poke fun at the explicit nature of rap music which is made most appearant in the track “Granpa’s Spaceship” off of the Bobby Tarantino II album. This track is a conversation exchange between two popular TV characters, Rick and Morty. Rick says:
“Don’t come at me like a little punk ass motherfucker, don’t try to come at me, Morty I’m saying that he’s got a plethora of music that varies from mood to mood, Morty, okay? And I’m saying that I’m in the mood to turn some shit up, Morty I’m not in the mood for a message about how I can be whatever I want or Ooh you know like equality and everybody and all that shit, alright? Just wanna hear some fuckin’, about titties, throwin’ stacks on some ass, you know Just some good old fuckin’ ATL style club rap, Morty”
Again, this is extremely explicit in nature but by doing so it is ironically playing at the culture of rap music. Even though the hypothesis was correct about Logic’s albums having an overall negative sentiment, this is solely due to his choice of words, the subject matter and the irony of the words instead of the actual context of the lyrics.