Анализ твитов Хиллари Клинтон и Дональда Трампа во время предвыборной гонки 2016 года

Анализ датасета твитов

Author

Ярослав Курганов

Published

20.12.2025

Abstract
Путешествие в прекрасный и яростный мир американской политики

1 Интернет-исследование одних из самых скандальных выборов XXI века

Гости из прошлого - Коммерсантъ

О чем это исследование? В 2016-м году прошли выборы президента США, победу в которых одержал текущий президент страны Дональд Трамп. В этом тексте мы проанализируем твиты Трампа (@realDonaldTrump) и его оппонентки из Демократической партии Хиллари Клинтон (@HillaryClinton).

Импортируем файл

library(dplyr)
library(tidyr)
library(ggplot2)
library(tidytext)
library(textdata)
library(wordcloud)
library(tidytext)
library(tidyverse)

tweets <- read.csv("Yandex.Disk.localized/tweets 2.csv", stringsAsFactors = FALSE)

tweets$candidate <- ifelse(tweets$handle == "HillaryClinton", "Clinton", "Trump")

2 Общие подсчеты

Считаем сколько у нас твитов всего: в том числе и у каждого кандидата отдельно.

#Клинтон
sum(tweets$candidate == "Clinton")
[1] 3226
#Трамп
sum(tweets$candidate == "Trump")
[1] 3218
#Всего
nrow(tweets)
[1] 6444
hashtags <- str_extract_all(tweets$text, "#[A-Za-z0-9_]+") |> unlist()
hashtag_counts <- table(tolower(hashtags)) |> sort(decreasing = TRUE)
print(head(hashtag_counts, 5))

            #trump2016 #makeamericagreatagain             #votetrump 
                   348                    254                     68 
         #americafirst              #rncincle 
                    67                     67 

Что это значит? C хэштегами получается интересная ситуация: 4 из 5 наиболее распространенных напрямую связаны с Трампом: будь то напрямую его фамилия или его же лозунги типа “americafirst” или “makeamericagreatagain”. И это несмотря на то, что общее количество твитов с минимальной разницей больше у Клинтон. С высоты 2025-го года уже давно известно, кто в той гонке одержал победу – но в этом исследовании через открытые данные я выделю основные аспекты ведения соцсетей республиканским кандидатом, которые помогли ему получить поддержку электората. Trump’s twisted tweets add to his popularity

А пока что токенизируем наши данные.

tokens_df <- tweets |>
  unnest_tokens(word, text) |>
  anti_join(stop_words) |>
  filter(!str_detect(word, "https|t\\.co|[0-9]"))
Joining with `by = join_by(word)`

3 Визуализируем!

Теперь визуализируем самые распространенные слова из твитов обоиз кандидатов. Ввиду особого оформления текстов на твиттере, включая различные элементы (https, @, t// и тд), фильтрация будет специфической.

word_freq <- tweets |>
  unnest_tokens(word, text) |>
  anti_join(stop_words) |>
  filter(!str_detect(word, "^https|^t\\.co|^@|^[0-9]+$")) |>
  count(candidate, word, sort = TRUE)
Joining with `by = join_by(word)`
top_words <- word_freq |>
  group_by(candidate) |>
  top_n(10, n) |>
  ungroup()

ggplot(top_words, aes(x = reorder(word, n), y = n, fill = candidate)) +
  geom_col() +
  coord_flip() +
  facet_wrap(~candidate, scales = "free") +
  labs(title = "Топ-10 слов по кандидатам", x = "Слово", y = "Частота") +
  scale_fill_manual(values = c("Clinton" = "blue", "Trump" = "red")) +
  theme_minimal()

summary_table <- tweets |>
  group_by(candidate) |>
  summarise(
    tweets = n(),
    avg_retweets = mean(as.numeric(retweet_count), na.rm = TRUE),
    avg_favorites = mean(as.numeric(favorite_count), na.rm = TRUE)
  )
summary_table
# A tibble: 2 × 4
  candidate tweets avg_retweets avg_favorites
  <chr>      <int>        <dbl>         <dbl>
1 Clinton     3226        2984.         6700.
2 Trump       3218        5812.        16614.

4 Эмоциональный анализ

Теперь анализируем эмоциональную составляющую текста:

afinn <- get_sentiments("afinn")
sentiment_afinn <- tokens_df |>
  inner_join(afinn, by = "word") |>
  group_by(candidate) |>
  summarise(
    net_sentiment = sum(value),
    total_words = n(),
    avg_sentiment = mean(value)
  )

sentiment_afinn
# A tibble: 2 × 4
  candidate net_sentiment total_words avg_sentiment
  <chr>             <dbl>       <int>         <dbl>
1 Clinton             171        3219        0.0531
2 Trump               350        3581        0.0977

Тут мы можем увидеть что Дональд Трамп в целом использует больше эмоциональной лексики – и исходя из этого как “позитивной, так и”негативной” у него тоже больше.

5 А как же штаты?

А вот и самая интересная часть моего исследования – штаты! В выборах США крайне важно, к какому конкретно региону обращается кандидат: иногда для него важно подчеркнуть какие-то тезисы для своего ядерного электората (тогда испоьзуются штаты с однозначной поддержкой той или иной партии), а иногда кандидату надо привлечь внимание людей из колеблющихся штатов: который из года в год голосует по разному.

Для такой задачи я заранее выписал все штаты (пока что, благо, без Гренландии и Канады :)) и приступил к их анализу:

states <- c("Alabama","Alaska","Arizona","Arkansas","California","Colorado",
            "Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho",
            "Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana",
            "Maine","Maryland","Massachusetts","Michigan","Minnesota",
            "Mississippi","Missouri","Montana","Nebraska","Nevada",
            "New Hampshire","New Jersey","New Mexico","New York",
            "North Carolina","North Dakota","Ohio","Oklahoma","Oregon",
            "Pennsylvania","Rhode Island","South Carolina","South Dakota",
            "Tennessee","Texas","Utah","Vermont","Virginia","Washington",
            "West Virginia","Wisconsin","Wyoming")

find_states <- function(text, state_list) {
  matches <- str_extract_all(text, regex(paste(state_list, collapse="|"), ignore_case=TRUE))
  return(unlist(matches))
}

# Клинтон
clinton_tweets <- tweets |> filter(candidate == "Clinton")
clinton_states <- unlist(lapply(clinton_tweets$text, find_states, states))

print(sort(table(tolower(clinton_states)), decreasing=TRUE)[1:5])

  new york washington    indiana   virginia       ohio 
        31         12         11         11         10 
#Трамп
trump_tweets <- tweets |> filter(candidate == "Trump")
trump_states <- unlist(lapply(trump_tweets$text, find_states, states))

print(sort(table(tolower(trump_states)), decreasing=TRUE)[1:5])  

         iowa          ohio       florida      new york new hampshire 
           82            58            54            51            49 

Для большей наглядности – визуализируем!

par(mfrow = c(1, 2), mar = c(0, 0, 2, 0))

wordcloud(names(table(clinton_states)), table(clinton_states),
          colors = brewer.pal(8, "Blues"), scale = c(2, 0.5),
          main = "Клинтон", max.words = 30)

wordcloud(names(table(trump_states)), table(trump_states),
          colors = brewer.pal(8, "Reds"), scale = c(2, 0.5),
          main = "Трамп", max.words = 30)

И что мы видим? Хиллари Клинтон (синяя) в основном обращается к традиционно “синим” штатам (Нью-Йорк, Вашингтон, Индиана). Дональд Трамп же хоть и тоже опирается на “красные” Неваду и Техас – в основном коммуницириует с так называемым “ржавым” поясом: регионом с колеблящимся электоратом. Штаты Iowa, Pennsylvania, Ohio, Indiana как раз были одним из самых упоминаемых в твитах президента (Клинтон некоторые из них тоже упоминает, но в меньшей степени). И что интересно – во всех перечисленных мною штатах республиканец одержал победу даже в прямом голосовании. (хоть и в некоторых с минимальным отрывом)

6 Выводы

Проведенное мною исследование показало следующие интересные моменты:
1) Дональд Трамп имел более активный фидбек со стороны пользователей (статистика по числу ретвитов на его стороне), также гораздо более активно работал с хэштегами.
2) Хиллари Клинтон писала менее эмоциональные твиты и опиралась на традиционно демократические штаты.
3) Трамп писал более эмоциональные твиты и опирался на как “свои” штаты, так и на колеблющиеся.
4) Трамп использует лозунги как инструмент для распространения своих твитов (через хэштеги).

7 Список литературы