Data transfer is highly controlled. The key notions are authentication and protocol.
There are several packages that run an interface with twitter:
rtweet, RTwitterAPI, streamR and
twitteR.
But since Auth V2, we will need RTwitterV2! But this
only runs on R v4.2!
Documentation: https://github.com/MaelKubli/RTwitterV2.
Recent packages are better because firms update their API policies (and
access), thus old protocols sometimes do not work!
Unfortunately, the Twitter API is no longer free!
Hence, in this notebook, we will test the competitor: mastodon!
The package for this will be rtoot.
First, the packages. Download…
if(!require(rtoot)){install.packages("rtoot")}
… and activate.
library(tidyverse)
library(plotly)
library(rtoot)
Second: authentication You have to choose a particular instance of the network. Personally, I am registered on “sciences.social”, the largest one is “mastodon.social” (see https://mastodonservers.net/servers/top) => Write the answer without the quotation marks and choose a public tocken
rtoot::auth_setup(
instance = "mastodon.social",
type = "public"
)
Token of type "public" for instance mastodon.social is valid
<mastodon bearer token> for instance: mastodon.social of type: public
# get_timeline_hashtag(hashtag = "rstats",
# instance = "mastodon.social",
# limit = 200)
Authentication can be an important part of the process. For more info
on that:
- https://cran.r-project.org/web/packages/googlesheets/vignettes/managing-auth-tokens.html
- https://httr.r-lib.org/reference/index.html (section
Authentication)
- https://blog.r-hub.io/2021/01/25/oauth-2.0/
If no error appears, we are ready to query. Depending on the number of requested tweets, this can take some time.
There are different types of queries that the packages allows.
For instance, below we use the get_timeline_hashtag
function to access toots that include one particular term, the
“hashtag”.
search_term <- "election"
toots <- get_timeline_hashtag(hashtag = search_term,
instance = "mastodon.social",
limit = 2000)
The reference book is: https://www.tidytextmining.com
A great interactive tutorial: https://juliasilge.shinyapps.io/learntidytext/
And the package is:
if(!require(tidytext)){install.packages("tidytext", repos = "https://cloud.r-project.org/")}
library(tidytext)
(see also: https://quanteda.io/index.html)
Now, let’s move forward to simple text analysis. First, we need to prepare the data! (as usual)
tokens <- toots %>%
select(id, content) %>% # Keeps only id and text/content of the tweet
unnest_tokens(word, content) # Creates tokens!
tokens
Let’s have a look at word frequencies.
tokens %>%
count(word, sort = TRUE)
This is polluted by small words. Let’s filter that (FIRST METHOD).
tokens %>% mutate(length = nchar(word))
Now let’s omit the small words (smaller than 5 characters).
NOTE: all the thresholds below depend on the
sample!
tokens %>%
mutate(length = nchar(word)) %>%
filter(length > 4) %>% # Keep words with length larger than 4
count(word, sort = TRUE) %>% # Count words
head(21) %>% # Keep only top 12 words
ggplot(aes(y = reorder(word,n), x = n)) + geom_col() + ylab("Words") + theme_bw()
A better way to proceed is to remove “stop words” like “a”, “I”, “of”, “the”, etc (SECOND METHOD). Also, it would make sense to remove the search item and “https”.
data("stop_words")
tidy_tokens <- tokens %>%
anti_join(stop_words) # Remove unrelevant terms
tidy_tokens %>%
count(word, sort = TRUE) %>% # Count words
head(20) %>% # Keep only top 15 words
ggplot(aes(y = reorder(word,n), x = n)) + geom_col() + ylab("Words") + theme_bw()
Problem: strange characters remain. We are going to remove them by converting the text to ASCII format and omit NA data.
new_stop_words <- c("https", "span", "class", "href", "target", "_blank", "rel", "tag",
"mastodon.social", "ellipsis", "mastodon.online", "mstdn.social", "amp",
"http", "invisible", "03", search_term, tolower(search_term), "d0", "src",
"tags", "mention", "noreferrer", "noopener", "nofollow", "hashtag", "translate",
"www", "url", "die", "der", "und", "a", "p", "br", "1", "2", "01", "02")
tidy_tokens <- tokens %>%
anti_join(stop_words) %>% # Remove unrelevant
mutate(word = iconv(word, from = "UTF-8", to = "ASCII")) %>% # Put in latin format
na.omit() %>% # Remove missing
filter(nchar(word) > 2, # Remove small words
!(word %in% new_stop_words) # search_term defined above
)
tidy_tokens %>%
count(word, sort = TRUE) %>% # Count words
head(30) %>% # Keep only top words
ggplot(aes(y = reorder(word,n), x = n)) + geom_col() + ylab("Words") + theme_bw()
Perfect!
This data can also be shown with a word cloud. We simply use the wordcloud package: https://cran.r-project.org/web/packages/wordcloud/index.html
The package wordcloud2 adds a few features: https://cran.r-project.org/web/packages/wordcloud2/vignettes/wordcloud.html
if(!require(wordcloud)){install.packages("wordcloud")}
library(wordcloud)
cloud_data <- tidy_tokens %>% count(word)
wordcloud(words = cloud_data$word,
freq = cloud_data$n, min.freq = 10,
max.words = 82, random.order = FALSE, rot.per = 0.15,
colors = brewer.pal(8, "Dark2"))