This first chunk is downloading the necessary packages to complete the analysis.

library(rtweet)
package 㤼㸱rtweet㤼㸲 was built under R version 4.0.5
library(tidyverse)
package 㤼㸱tidyverse㤼㸲 was built under R version 4.0.5replacing previous import 㤼㸱lifecycle::last_warnings㤼㸲 by 㤼㸱rlang::last_warnings㤼㸲 when loading 㤼㸱pillar㤼㸲Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
replacing previous import 㤼㸱lifecycle::last_warnings㤼㸲 by 㤼㸱rlang::last_warnings㤼㸲 when loading 㤼㸱hms㤼㸲-- Attaching packages --------------------------------------------------------------------------------- tidyverse 1.3.1 --
v ggplot2 3.3.5     v purrr   0.3.4
v tibble  3.1.6     v dplyr   1.0.7
v tidyr   1.1.4     v stringr 1.4.0
v readr   2.1.1     v forcats 0.5.1
package 㤼㸱ggplot2㤼㸲 was built under R version 4.0.5package 㤼㸱tibble㤼㸲 was built under R version 4.0.5package 㤼㸱tidyr㤼㸲 was built under R version 4.0.5package 㤼㸱readr㤼㸲 was built under R version 4.0.5package 㤼㸱purrr㤼㸲 was built under R version 4.0.5package 㤼㸱dplyr㤼㸲 was built under R version 4.0.5package 㤼㸱stringr㤼㸲 was built under R version 4.0.5package 㤼㸱forcats㤼㸲 was built under R version 4.0.5-- Conflicts ------------------------------------------------------------------------------------ tidyverse_conflicts() --
x dplyr::filter()  masks stats::filter()
x purrr::flatten() masks rtweet::flatten()
x dplyr::lag()     masks stats::lag()
library(tidytext)
package 㤼㸱tidytext㤼㸲 was built under R version 4.0.5
library(DT)
package 㤼㸱DT㤼㸲 was built under R version 4.0.5Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
library(plotly)
package 㤼㸱plotly㤼㸲 was built under R version 4.0.5Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

Attaching package: 㤼㸱plotly㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    last_plot

The following object is masked from 㤼㸱package:stats㤼㸲:

    filter

The following object is masked from 㤼㸱package:graphics㤼㸲:

    layout
library(wordcloud2)
package 㤼㸱wordcloud2㤼㸲 was built under R version 4.0.5

The following chunk then pulls 5000 tweets from the wall street journal for this analysis.

wsj_tweets <- get_timeline("wsj", n = 5000)
Requesting token on behalf of user...
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
Authentication complete.

This chunk along with the following one both separate the words to be analyzed more effectively, along with removing any unnecessary or irrelevant words.

wsj_words <- wsj_tweets %>% 
  unnest_tokens(word, text) %>% 
  select(screen_name, word)
wsj_words %>% 
  anti_join(stop_words) %>% 
  count(word, sort = T)
Joining, by = "word"

After seeing the list of included words after removing the stop words, https and t.co were both unnecessary in this analysis. The following chunk removes those as well.

wsj_words %>% 
  anti_join(stop_words) %>% 
  filter(!word == "https") %>%
  filter(!word == "t.co") %>%
  count(word, sort = T)
Joining, by = "word"

This chunk then uses the above data to make a word cloud excluding the unnecessary words.

wsj_words %>% 
  anti_join(stop_words) %>% 
  filter(!word == "https") %>%
  filter(!word == "t.co") %>%
  count(word, sort = T) %>%
  top_n(200) %>%
  wordcloud2(size = .5)
Joining, by = "word"Selecting by n

This chunk is retrieving the general attitudes from bing

bing <- get_sentiments("bing")
bing

This chunk narrows down the general sentiments with the ones specifically in the wall street journal.

wsj_words %>% 
  inner_join(bing) %>% 
  filter(!word == "trump") %>%
  count(word, sentiment, sort = TRUE)
Joining, by = "word"

This next chunk then creates a table of all the top words in the sentiment.

wsj_words %>% 
  inner_join(bing) %>% 
  filter(!word == "trump") %>%
  count(word, sentiment, sort = TRUE) %>%
  group_by(sentiment) %>%
  top_n(10) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(vars(sentiment), scales = "free") +
  labs(y = "News headlines: Words that contribute the most to each sentiment",
       x = NULL) +
  coord_flip() +
  theme_minimal()
Joining, by = "word"Selecting by n

The following chunks are repeating the above process that was done with bing, with nrc instead.

nrc <- get_sentiments("nrc")
nrc
wsj_words %>% 
  inner_join(nrc) %>% 
  filter(!word == "trump") %>%
  count(word, sentiment, sort = TRUE)
Joining, by = "word"
wsj_words %>% 
  inner_join(nrc) %>% 
  filter(!word == "trump") %>%
  count(word, sentiment, sort = TRUE) %>%
  group_by(sentiment) %>%
  top_n(10) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(vars(sentiment), scales = "free") +
  labs(y = "News headlines: Words that contribute the most to each sentiment",
       x = NULL) +
  coord_flip() +
  theme_minimal()
Joining, by = "word"Selecting by n

Next, this chunk unnests the tweets as bigrams in pairs while also removing stop words and errors.

wsj_tweets %>%
  select(text) %>%                                                 # this selects just the text of the tweets
  unnest_tokens(words, text, token = "ngrams", n = 2) %>% 
  separate(words, c("word1", "word2"), sep = " ") %>%          # separate them temporarily
  filter(!word1 %in% stop_words$word) %>%                      # remove if first word is a stop word
  filter(!word2 %in% stop_words$word) %>%                      # remove if second word is a stop word   
  unite(words, word1, word2, sep = " ")   

Next, this first chunk will create a table and the next will create a word cloud of the bigrams

news_bigrams %>%
  count(words, sort = T)
news_bigrams %>%
  count(words, sort = T) %>%
  top_n(100) %>%
  wordcloud2(size = .5)
Selecting by n

This final chunk will then analyze words that follow one another to better understand the information.

first_word <- c("COVID-19", "vaccine")                                  # these need to be lowercase

news_bigrams %>%             
  count(words, sort = TRUE) %>%
  separate(words, c("word1", "word2"), sep = " ") %>%       # separate the two words
  filter(word1 %in% first_word) %>%                          # find first words from our list
  count(word1, word2, wt = n, sort = TRUE)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGZpcnN0IGNodW5rIGlzIGRvd25sb2FkaW5nIHRoZSBuZWNlc3NhcnkgcGFja2FnZXMgdG8gY29tcGxldGUgdGhlIGFuYWx5c2lzLg0KYGBge3J9DQpsaWJyYXJ5KHJ0d2VldCkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSh0aWR5dGV4dCkNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkod29yZGNsb3VkMikNCmBgYA0KDQpUaGUgZm9sbG93aW5nIGNodW5rIHRoZW4gcHVsbHMgNTAwMCB0d2VldHMgZnJvbSB0aGUgd2FsbCBzdHJlZXQgam91cm5hbCBmb3IgdGhpcyBhbmFseXNpcy4NCmBgYHtyfQ0Kd3NqX3R3ZWV0cyA8LSBnZXRfdGltZWxpbmUoIndzaiIsIG4gPSA1MDAwKQ0KYGBgDQoNClRoaXMgY2h1bmsgYWxvbmcgd2l0aCB0aGUgZm9sbG93aW5nIG9uZSBib3RoIHNlcGFyYXRlIHRoZSB3b3JkcyB0byBiZSBhbmFseXplZCBtb3JlIGVmZmVjdGl2ZWx5LCBhbG9uZyB3aXRoIHJlbW92aW5nIGFueSB1bm5lY2Vzc2FyeSBvciBpcnJlbGV2YW50IHdvcmRzLg0KYGBge3J9DQp3c2pfd29yZHMgPC0gd3NqX3R3ZWV0cyAlPiUgDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkgJT4lIA0KICBzZWxlY3Qoc2NyZWVuX25hbWUsIHdvcmQpDQpgYGANCg0KDQpgYGB7cn0NCndzal93b3JkcyAlPiUgDQogIGFudGlfam9pbihzdG9wX3dvcmRzKSAlPiUgDQogIGNvdW50KHdvcmQsIHNvcnQgPSBUKQ0KYGBgDQpBZnRlciBzZWVpbmcgdGhlIGxpc3Qgb2YgaW5jbHVkZWQgd29yZHMgYWZ0ZXIgcmVtb3ZpbmcgdGhlIHN0b3Agd29yZHMsIGh0dHBzIGFuZCB0LmNvIHdlcmUgYm90aCB1bm5lY2Vzc2FyeSBpbiB0aGlzIGFuYWx5c2lzLiBUaGUgZm9sbG93aW5nIGNodW5rIHJlbW92ZXMgdGhvc2UgYXMgd2VsbC4NCmBgYHtyfQ0Kd3NqX3dvcmRzICU+JSANCiAgYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JSANCiAgZmlsdGVyKCF3b3JkID09ICJodHRwcyIpICU+JQ0KICBmaWx0ZXIoIXdvcmQgPT0gInQuY28iKSAlPiUNCiAgY291bnQod29yZCwgc29ydCA9IFQpDQpgYGANClRoaXMgY2h1bmsgdGhlbiB1c2VzIHRoZSBhYm92ZSBkYXRhIHRvIG1ha2UgYSB3b3JkIGNsb3VkIGV4Y2x1ZGluZyB0aGUgdW5uZWNlc3Nhcnkgd29yZHMuDQpgYGB7cn0NCndzal93b3JkcyAlPiUgDQogIGFudGlfam9pbihzdG9wX3dvcmRzKSAlPiUgDQogIGZpbHRlcighd29yZCA9PSAiaHR0cHMiKSAlPiUNCiAgZmlsdGVyKCF3b3JkID09ICJ0LmNvIikgJT4lDQogIGNvdW50KHdvcmQsIHNvcnQgPSBUKSAlPiUNCiAgdG9wX24oMjAwKSAlPiUNCiAgd29yZGNsb3VkMihzaXplID0gLjUpDQpgYGANCg0KVGhpcyBjaHVuayBpcyByZXRyaWV2aW5nIHRoZSBnZW5lcmFsIGF0dGl0dWRlcyBmcm9tIGJpbmcNCmBgYHtyfQ0KYmluZyA8LSBnZXRfc2VudGltZW50cygiYmluZyIpDQpiaW5nDQpgYGANCg0KDQpUaGlzIGNodW5rIG5hcnJvd3MgZG93biB0aGUgZ2VuZXJhbCBzZW50aW1lbnRzIHdpdGggdGhlIG9uZXMgc3BlY2lmaWNhbGx5IGluIHRoZSB3YWxsIHN0cmVldCBqb3VybmFsLg0KYGBge3J9DQp3c2pfd29yZHMgJT4lIA0KICBpbm5lcl9qb2luKGJpbmcpICU+JSANCiAgZmlsdGVyKCF3b3JkID09ICJ0cnVtcCIpICU+JQ0KICBjb3VudCh3b3JkLCBzZW50aW1lbnQsIHNvcnQgPSBUUlVFKQ0KYGBgDQpUaGlzIG5leHQgY2h1bmsgdGhlbiBjcmVhdGVzIGEgdGFibGUgb2YgYWxsIHRoZSB0b3Agd29yZHMgaW4gdGhlIHNlbnRpbWVudC4NCmBgYHtyfQ0Kd3NqX3dvcmRzICU+JSANCiAgaW5uZXJfam9pbihiaW5nKSAlPiUgDQogIGZpbHRlcighd29yZCA9PSAidHJ1bXAiKSAlPiUNCiAgY291bnQod29yZCwgc2VudGltZW50LCBzb3J0ID0gVFJVRSkgJT4lDQogIGdyb3VwX2J5KHNlbnRpbWVudCkgJT4lDQogIHRvcF9uKDEwKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUod29yZCA9IHJlb3JkZXIod29yZCwgbikpICU+JQ0KICBnZ3Bsb3QoYWVzKHdvcmQsIG4sIGZpbGwgPSBzZW50aW1lbnQpKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZmFjZXRfd3JhcCh2YXJzKHNlbnRpbWVudCksIHNjYWxlcyA9ICJmcmVlIikgKw0KICBsYWJzKHkgPSAiTmV3cyBoZWFkbGluZXM6IFdvcmRzIHRoYXQgY29udHJpYnV0ZSB0aGUgbW9zdCB0byBlYWNoIHNlbnRpbWVudCIsDQogICAgICAgeCA9IE5VTEwpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANClRoZSBmb2xsb3dpbmcgY2h1bmtzIGFyZSByZXBlYXRpbmcgdGhlIGFib3ZlIHByb2Nlc3MgdGhhdCB3YXMgZG9uZSB3aXRoIGJpbmcsIHdpdGggbnJjIGluc3RlYWQuDQpgYGB7cn0NCm5yYyA8LSBnZXRfc2VudGltZW50cygibnJjIikNCm5yYw0KYGBgDQoNCmBgYHtyfQ0Kd3NqX3dvcmRzICU+JSANCiAgaW5uZXJfam9pbihucmMpICU+JSANCiAgZmlsdGVyKCF3b3JkID09ICJ0cnVtcCIpICU+JQ0KICBjb3VudCh3b3JkLCBzZW50aW1lbnQsIHNvcnQgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyfQ0Kd3NqX3dvcmRzICU+JSANCiAgaW5uZXJfam9pbihucmMpICU+JSANCiAgZmlsdGVyKCF3b3JkID09ICJ0cnVtcCIpICU+JQ0KICBjb3VudCh3b3JkLCBzZW50aW1lbnQsIHNvcnQgPSBUUlVFKSAlPiUNCiAgZ3JvdXBfYnkoc2VudGltZW50KSAlPiUNCiAgdG9wX24oMTApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh3b3JkID0gcmVvcmRlcih3b3JkLCBuKSkgJT4lDQogIGdncGxvdChhZXMod29yZCwgbiwgZmlsbCA9IHNlbnRpbWVudCkpICsNCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBmYWNldF93cmFwKHZhcnMoc2VudGltZW50KSwgc2NhbGVzID0gImZyZWUiKSArDQogIGxhYnMoeSA9ICJOZXdzIGhlYWRsaW5lczogV29yZHMgdGhhdCBjb250cmlidXRlIHRoZSBtb3N0IHRvIGVhY2ggc2VudGltZW50IiwNCiAgICAgICB4ID0gTlVMTCkgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpOZXh0LCB0aGlzIGNodW5rIHVubmVzdHMgdGhlIHR3ZWV0cyBhcyBiaWdyYW1zIGluIHBhaXJzIHdoaWxlIGFsc28gcmVtb3Zpbmcgc3RvcCB3b3JkcyBhbmQgZXJyb3JzLg0KYGBge3J9DQp3c2pfdHdlZXRzICU+JQ0KICBzZWxlY3QodGV4dCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhpcyBzZWxlY3RzIGp1c3QgdGhlIHRleHQgb2YgdGhlIHR3ZWV0cw0KICB1bm5lc3RfdG9rZW5zKHdvcmRzLCB0ZXh0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikgJT4lIA0KICBzZXBhcmF0ZSh3b3JkcywgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUgICAgICAgICAgIyBzZXBhcmF0ZSB0aGVtIHRlbXBvcmFyaWx5DQogIGZpbHRlcighd29yZDEgJWluJSBzdG9wX3dvcmRzJHdvcmQpICU+JSAgICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBpZiBmaXJzdCB3b3JkIGlzIGEgc3RvcCB3b3JkDQogIGZpbHRlcighd29yZDIgJWluJSBzdG9wX3dvcmRzJHdvcmQpICU+JSAgICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBpZiBzZWNvbmQgd29yZCBpcyBhIHN0b3Agd29yZCAgIA0KICB1bml0ZSh3b3Jkcywgd29yZDEsIHdvcmQyLCBzZXAgPSAiICIpICAgDQpgYGANCg0KTmV4dCwgdGhpcyBmaXJzdCBjaHVuayB3aWxsIGNyZWF0ZSBhIHRhYmxlIGFuZCB0aGUgbmV4dCB3aWxsIGNyZWF0ZSBhIHdvcmQgY2xvdWQgb2YgdGhlIGJpZ3JhbXMNCg0KDQpgYGB7cn0NCm5ld3NfYmlncmFtcyAlPiUNCiAgY291bnQod29yZHMsIHNvcnQgPSBUKQ0KYGBgDQoNCmBgYHtyfQ0KbmV3c19iaWdyYW1zICU+JQ0KICBjb3VudCh3b3Jkcywgc29ydCA9IFQpICU+JQ0KICB0b3BfbigxMDApICU+JQ0KICB3b3JkY2xvdWQyKHNpemUgPSAuNSkNCmBgYA0KDQpUaGlzIGZpbmFsIGNodW5rIHdpbGwgdGhlbiBhbmFseXplIHdvcmRzIHRoYXQgZm9sbG93IG9uZSBhbm90aGVyIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSBpbmZvcm1hdGlvbi4NCmBgYHtyfQ0KZmlyc3Rfd29yZCA8LSBjKCJDT1ZJRC0xOSIsICJ2YWNjaW5lIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGVzZSBuZWVkIHRvIGJlIGxvd2VyY2FzZQ0KDQpuZXdzX2JpZ3JhbXMgJT4lICAgICAgICAgICAgIA0KICBjb3VudCh3b3Jkcywgc29ydCA9IFRSVUUpICU+JQ0KICBzZXBhcmF0ZSh3b3JkcywgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUgICAgICAgIyBzZXBhcmF0ZSB0aGUgdHdvIHdvcmRzDQogIGZpbHRlcih3b3JkMSAlaW4lIGZpcnN0X3dvcmQpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmaW5kIGZpcnN0IHdvcmRzIGZyb20gb3VyIGxpc3QNCiAgY291bnQod29yZDEsIHdvcmQyLCB3dCA9IG4sIHNvcnQgPSBUUlVFKQ0KYGBgDQoNCg==