Text frequency analysis

Exercise

Exercise 6
Author

Emi Tanaka

Published

June 4, 2025

The image depicts a futuristic scene with a humanoid robot at the center.

install.packages(c("tidyverse", "tidytext", "wordcloud"))

First let’s get the book “Sense & Sensibility” by Jane Austen

library(tidyverse)
library(tidytext)
library(wordcloud)
book <- janeaustenr::austen_books() |> 
  filter(book == "Sense & Sensibility")
slice(book, 50:60)
# A tibble: 11 × 2
   text                                                                    book 
   <chr>                                                                   <fct>
 1 and daughters than for himself or his son;--but to his son, and his     Sens…
 2 son's son, a child of four years old, it was secured, in such a way, as Sens…
 3 to leave to himself no power of providing for those who were most dear  Sens…
 4 to him, and who most needed a provision by any charge on the estate, or Sens…
 5 by any sale of its valuable woods.  The whole was tied up for the       Sens…
 6 benefit of this child, who, in occasional visits with his father and    Sens…
 7 mother at Norland, had so far gained on the affections of his uncle, by Sens…
 8 such attractions as are by no means unusual in children of two or three Sens…
 9 years old; an imperfect articulation, an earnest desire of having his   Sens…
10 own way, many cunning tricks, and a great deal of noise, as to outweigh Sens…
11 all the value of all the attention which, for years, he had received    Sens…

1 Tokenization and Word Frequencies

Let’s split the text by words and count their frequencies.

tokens <- book |> 
  unnest_tokens(word, text) |> 
  count(word, sort = TRUE)

The result shows that there are a lot of words which are not very informative, such as “the”, “and”, “to”, etc.

tokens 
# A tibble: 6,419 × 2
   word      n
   <chr> <int>
 1 to     4116
 2 the    4105
 3 of     3571
 4 and    3490
 5 her    2543
 6 a      2092
 7 i      1998
 8 in     1979
 9 was    1861
10 it     1755
# ℹ 6,409 more rows
wordcloud(words = tokens$word[1:200], 
          freq = tokens$n[1:200])

2 Remove stop words

Let’s remove common stop words from the tokens. The tidytext package provides a built-in list of stop words.

clean_tokens <- tokens |> 
  anti_join(stop_words, by = "word") 

We can see now the informative frequest words in the book:

clean_tokens 
# A tibble: 5,897 × 2
   word           n
   <chr>      <int>
 1 elinor       623
 2 marianne     492
 3 time         239
 4 dashwood     231
 5 sister       229
 6 edward       220
 7 mother       213
 8 miss         210
 9 jennings     199
10 willoughby   181
# ℹ 5,887 more rows
wordcloud(words = clean_tokens$word[1:30], 
          freq = clean_tokens$n[1:30])

3 Bigram Analysis

Some times, we want to look at pairs of words (bigrams) instead of single words. This can help us understand common phrases or terms used in the text.

bigrams <- book |> 
  unnest_tokens(bigram, text, token = "ngrams", n = 2) |> 
  count(bigram, sort = TRUE) |> 
  separate(bigram, into = c("word1", "word2"), sep = " ", remove = FALSE) |> 
  # remove if both word are stop words
  filter(!word1 %in% stop_words$word & !word2 %in% stop_words$word) 
  
bigrams
# A tibble: 4,974 × 4
   bigram          word1    word2         n
   <chr>           <chr>    <chr>     <int>
 1 <NA>            <NA>     <NA>       2199
 2 colonel brandon colonel  brandon      96
 3 sir john        sir      john         94
 4 lady middleton  lady     middleton    75
 5 miss dashwood   miss     dashwood     55
 6 john dashwood   john     dashwood     34
 7 thousand pounds thousand pounds       27
 8 replied elinor  replied  elinor       26
 9 cried marianne  cried    marianne     25
10 miss steeles    miss     steeles      25
# ℹ 4,964 more rows




🎉 Yee-haw! You’ve reached the end of this exercise! You are smashing! Proceed to …

next slide

next exercise