This first chunk downloads all packages required to complete the analysis.

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 dplyr::lag()    masks stats::lag()
library(DT)
package 㤼㸱DT㤼㸲 was built under R version 4.0.5Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
library(tidytext)        # package for text analysis
package 㤼㸱tidytext㤼㸲 was built under R version 4.0.5
library(readxl)          # reads excel files, the format I used for the data

The following chunk then reads in the downloaded Excel file with all of the Inaugural Speeches sorted by name.

inaug_speeches <- read_excel("inaug_speeches.xlsx")

inaug_speeches

This chunk then uses the above data and separates the words so they can be analyzed, rather than a long string of words.

inaug_words <- inaug_speeches %>%
  unnest_tokens(word, text)

inaug_words
NA
NA

The below chunk then separates the data by number of words, lexical diversity (number of distinct words), and lexical density (number of distinct words divided by total number of words).

inaug_words %>% 
  group_by(author) %>% 
  summarise(num_words = n(),
            lex_diversity = n_distinct(word), 
            lex_density = n_distinct(word)/n())

This chunk is more simple than the one above and gives the mean word length for each speech.

inaug_words %>%
  group_by(author) %>% 
  mutate(word_length = nchar(word)) %>% 
  summarize(mean_word_length = mean(word_length)) %>% 
  arrange(-mean_word_length)

Using this chunk then gives mini graphs of each speech with the word length in the document.

inaug_words %>%
  mutate(word_length = nchar(word)) %>% 
  ggplot(aes(word_length)) +
  geom_histogram(binwidth = 1) +
  facet_wrap(vars(author), scales = "free_y") +
  labs(title = "Word Length By Author")

The following chunk first removes stop words, then creates a graph with the most common words from each speech.

inaug_words %>%
  anti_join(stop_words) %>% 
  group_by(author) %>% 
  count(word, sort = T) %>%
  top_n(5) %>% 
  ungroup() %>% 
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = author)) +
  geom_col(show.legend = FALSE) +
  labs(x = NULL, y = "Most common words") +
  facet_wrap(vars(author), scales = "free") +
  scale_fill_viridis_d() +
  theme_minimal() +
  coord_flip()
Joining, by = "word"Selecting by n

This chunk is necessary for the chunk below it, as this calculates the tf-idfs in each document.

inaug_word_counts <- inaug_speeches %>%             # This counts each word per author
  unnest_tokens(word, text) %>%
  count(author, word, sort = TRUE) 

total_words <- inaug_word_counts %>%               # This counts total words per author
  group_by(author) %>% 
  summarize(total = sum(n))

inaug_word_counts <- left_join(inaug_word_counts, total_words)    # Joins the two
Joining, by = "author"
inaug_tf_idf <- inaug_word_counts %>%             # Calculates tf-idf
  bind_tf_idf(word, author, n)

inaug_tf_idf %>%                                   # Displays it
  arrange(-tf_idf)                          
NA

This final chunk then takes the above data of the tf-idfs and graphs the words with the highest tf-idfs, by President.

inaug_tf_idf %>%
  arrange(-tf_idf) %>%
  mutate(word = factor(word, levels = rev(unique(word)))) %>% 
  group_by(author) %>% 
  top_n(5) %>% 
  ggplot(aes(word, tf_idf, fill = author)) +
  geom_col(show.legend = FALSE) +
  labs(x = NULL, y = "tf-idf") +
  facet_wrap(~author, scales = "free") +
  coord_flip() +
  theme_minimal() +
  scale_fill_viridis_d() +
  labs(title = "Most distinctive words in Inaugural Speeches")
Selecting by tf_idf

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGZpcnN0IGNodW5rIGRvd25sb2FkcyBhbGwgcGFja2FnZXMgcmVxdWlyZWQgdG8gY29tcGxldGUgdGhlIGFuYWx5c2lzLg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHRpZHl0ZXh0KSAgICAgICAgIyBwYWNrYWdlIGZvciB0ZXh0IGFuYWx5c2lzDQpsaWJyYXJ5KHJlYWR4bCkgICAgICAgICAgIyByZWFkcyBleGNlbCBmaWxlcywgdGhlIGZvcm1hdCBJIHVzZWQgZm9yIHRoZSBkYXRhDQpgYGANCg0KVGhlIGZvbGxvd2luZyBjaHVuayB0aGVuIHJlYWRzIGluIHRoZSBkb3dubG9hZGVkIEV4Y2VsIGZpbGUgd2l0aCBhbGwgb2YgdGhlIEluYXVndXJhbCBTcGVlY2hlcyBzb3J0ZWQgYnkgbmFtZS4NCg0KYGBge3J9DQppbmF1Z19zcGVlY2hlcyA8LSByZWFkX2V4Y2VsKCJpbmF1Z19zcGVlY2hlcy54bHN4IikNCg0KaW5hdWdfc3BlZWNoZXMNCmBgYA0KDQpUaGlzIGNodW5rIHRoZW4gdXNlcyB0aGUgYWJvdmUgZGF0YSBhbmQgc2VwYXJhdGVzIHRoZSB3b3JkcyBzbyB0aGV5IGNhbiBiZSBhbmFseXplZCwgcmF0aGVyIHRoYW4gYSBsb25nIHN0cmluZyBvZiB3b3Jkcy4NCmBgYHtyfQ0KaW5hdWdfd29yZHMgPC0gaW5hdWdfc3BlZWNoZXMgJT4lDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkNCg0KaW5hdWdfd29yZHMNCg0KDQpgYGANClRoZSBiZWxvdyBjaHVuayB0aGVuIHNlcGFyYXRlcyB0aGUgZGF0YSBieSBudW1iZXIgb2Ygd29yZHMsIGxleGljYWwgZGl2ZXJzaXR5IChudW1iZXIgb2YgZGlzdGluY3Qgd29yZHMpLCBhbmQgbGV4aWNhbCBkZW5zaXR5IChudW1iZXIgb2YgZGlzdGluY3Qgd29yZHMgZGl2aWRlZCBieSB0b3RhbCBudW1iZXIgb2Ygd29yZHMpLiANCmBgYHtyfQ0KaW5hdWdfd29yZHMgJT4lIA0KICBncm91cF9ieShhdXRob3IpICU+JSANCiAgc3VtbWFyaXNlKG51bV93b3JkcyA9IG4oKSwNCiAgICAgICAgICAgIGxleF9kaXZlcnNpdHkgPSBuX2Rpc3RpbmN0KHdvcmQpLCANCiAgICAgICAgICAgIGxleF9kZW5zaXR5ID0gbl9kaXN0aW5jdCh3b3JkKS9uKCkpDQpgYGANClRoaXMgY2h1bmsgaXMgbW9yZSBzaW1wbGUgdGhhbiB0aGUgb25lIGFib3ZlIGFuZCBnaXZlcyB0aGUgbWVhbiB3b3JkIGxlbmd0aCBmb3IgZWFjaCBzcGVlY2guDQpgYGB7cn0NCmluYXVnX3dvcmRzICU+JQ0KICBncm91cF9ieShhdXRob3IpICU+JSANCiAgbXV0YXRlKHdvcmRfbGVuZ3RoID0gbmNoYXIod29yZCkpICU+JSANCiAgc3VtbWFyaXplKG1lYW5fd29yZF9sZW5ndGggPSBtZWFuKHdvcmRfbGVuZ3RoKSkgJT4lIA0KICBhcnJhbmdlKC1tZWFuX3dvcmRfbGVuZ3RoKQ0KYGBgDQpVc2luZyB0aGlzIGNodW5rIHRoZW4gZ2l2ZXMgbWluaSBncmFwaHMgb2YgZWFjaCBzcGVlY2ggd2l0aCB0aGUgd29yZCBsZW5ndGggaW4gdGhlIGRvY3VtZW50Lg0KYGBge3J9DQppbmF1Z193b3JkcyAlPiUNCiAgbXV0YXRlKHdvcmRfbGVuZ3RoID0gbmNoYXIod29yZCkpICU+JSANCiAgZ2dwbG90KGFlcyh3b3JkX2xlbmd0aCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxKSArDQogIGZhY2V0X3dyYXAodmFycyhhdXRob3IpLCBzY2FsZXMgPSAiZnJlZV95IikgKw0KICBsYWJzKHRpdGxlID0gIldvcmQgTGVuZ3RoIEJ5IEF1dGhvciIpDQpgYGANClRoZSBmb2xsb3dpbmcgY2h1bmsgZmlyc3QgcmVtb3ZlcyBzdG9wIHdvcmRzLCB0aGVuIGNyZWF0ZXMgYSBncmFwaCB3aXRoIHRoZSBtb3N0IGNvbW1vbiB3b3JkcyBmcm9tIGVhY2ggc3BlZWNoLg0KYGBge3J9DQppbmF1Z193b3JkcyAlPiUNCiAgYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JSANCiAgZ3JvdXBfYnkoYXV0aG9yKSAlPiUgDQogIGNvdW50KHdvcmQsIHNvcnQgPSBUKSAlPiUNCiAgdG9wX24oNSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUod29yZCA9IHJlb3JkZXIod29yZCwgbikpICU+JQ0KICBnZ3Bsb3QoYWVzKHdvcmQsIG4sIGZpbGwgPSBhdXRob3IpKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgbGFicyh4ID0gTlVMTCwgeSA9ICJNb3N0IGNvbW1vbiB3b3JkcyIpICsNCiAgZmFjZXRfd3JhcCh2YXJzKGF1dGhvciksIHNjYWxlcyA9ICJmcmVlIikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZCgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgY29vcmRfZmxpcCgpDQpgYGANCg0KVGhpcyBjaHVuayBpcyBuZWNlc3NhcnkgZm9yIHRoZSBjaHVuayBiZWxvdyBpdCwgYXMgdGhpcyBjYWxjdWxhdGVzIHRoZSB0Zi1pZGZzIGluIGVhY2ggZG9jdW1lbnQuDQpgYGB7cn0NCmluYXVnX3dvcmRfY291bnRzIDwtIGluYXVnX3NwZWVjaGVzICU+JSAgICAgICAgICAgICAjIFRoaXMgY291bnRzIGVhY2ggd29yZCBwZXIgYXV0aG9yDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkgJT4lDQogIGNvdW50KGF1dGhvciwgd29yZCwgc29ydCA9IFRSVUUpIA0KDQp0b3RhbF93b3JkcyA8LSBpbmF1Z193b3JkX2NvdW50cyAlPiUgICAgICAgICAgICAgICAjIFRoaXMgY291bnRzIHRvdGFsIHdvcmRzIHBlciBhdXRob3INCiAgZ3JvdXBfYnkoYXV0aG9yKSAlPiUgDQogIHN1bW1hcml6ZSh0b3RhbCA9IHN1bShuKSkNCg0KaW5hdWdfd29yZF9jb3VudHMgPC0gbGVmdF9qb2luKGluYXVnX3dvcmRfY291bnRzLCB0b3RhbF93b3JkcykgICAgIyBKb2lucyB0aGUgdHdvDQoNCmluYXVnX3RmX2lkZiA8LSBpbmF1Z193b3JkX2NvdW50cyAlPiUgICAgICAgICAgICAgIyBDYWxjdWxhdGVzIHRmLWlkZg0KICBiaW5kX3RmX2lkZih3b3JkLCBhdXRob3IsIG4pDQoNCmluYXVnX3RmX2lkZiAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGlzcGxheXMgaXQNCiAgYXJyYW5nZSgtdGZfaWRmKSAgICAgICAgICAgICAgICAgICAgICAgICAgDQoNCmBgYA0KDQpUaGlzIGZpbmFsIGNodW5rIHRoZW4gdGFrZXMgdGhlIGFib3ZlIGRhdGEgb2YgdGhlIHRmLWlkZnMgYW5kIGdyYXBocyB0aGUgd29yZHMgd2l0aCB0aGUgaGlnaGVzdCB0Zi1pZGZzLCBieSBQcmVzaWRlbnQuDQpgYGB7cn0NCmluYXVnX3RmX2lkZiAlPiUNCiAgYXJyYW5nZSgtdGZfaWRmKSAlPiUNCiAgbXV0YXRlKHdvcmQgPSBmYWN0b3Iod29yZCwgbGV2ZWxzID0gcmV2KHVuaXF1ZSh3b3JkKSkpKSAlPiUgDQogIGdyb3VwX2J5KGF1dGhvcikgJT4lIA0KICB0b3Bfbig1KSAlPiUgDQogIGdncGxvdChhZXMod29yZCwgdGZfaWRmLCBmaWxsID0gYXV0aG9yKSkgKw0KICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSAidGYtaWRmIikgKw0KICBmYWNldF93cmFwKH5hdXRob3IsIHNjYWxlcyA9ICJmcmVlIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZCgpICsNCiAgbGFicyh0aXRsZSA9ICJNb3N0IGRpc3RpbmN0aXZlIHdvcmRzIGluIEluYXVndXJhbCBTcGVlY2hlcyIpDQpgYGANCg0K