---
title: "Sentiment Analysis"
subtitle: "Week 5 — Codealong Notes"
author: "YOUR NAME HERE"
date: "2026-09-21"
format: pdf
execute:
  echo: true
  warning: false
  message: false
  error: true
---

```{r}
library(tidyverse)
library(tidytext)
library(janeaustenr)
library(sentimentr)
```

## Tidying text recap

Last week you got text into tidy format and stripped out stop words:

```{r}
tidy_books <- austen_books() |>  # get books
  group_by(book) |> # do separately for each book
  mutate(linenumber = row_number(), # add line numbers
         chapter = cumsum(str_detect(text, # and chapter numbers
                    regex("^chapter [\\divxlc]", ignore_case = TRUE)))) |>
  ungroup() |> # stop grouping by book
  unnest_tokens(word, text) |> # tokenize
  anti_join(stop_words) # remove stop words

head(tidy_books) # look at a few rows
```

## Load sentiment lexicons - First time each session

## bing

Liu et al. — binary: positive or negative

```{r}
get_sentiments("_______")
```

## nrc

Mohammad & Turney — 10 categories: positive, negative, anger, anticipation, disgust, fear, joy, sadness, surprise, trust

```{r}
get_sentiments("_______")
```

## AFINN

Nielsen — numeric score. -5 (very negative) to +5 (very positive)

```{r}
get_sentiments("_______")
```


# 2.2 — Sentiment analysis with `inner_join()`
## The core pattern

This time we *keep* the matches instead of dropping them.

```{r}
tidy_books |>
  ______(get_sentiments("bing"), by = "word") |>
  head()
```

## Joy in *Emma*

```{r}
nrc_joy <- get_sentiments("_______") |>
  filter(sentiment == "_______")

tidy_books |>
  filter(book == "_______") |>
  inner_join(nrc_joy, by = "word") |>
  count(word, sort = TRUE)
```

## Your turn

Find the `"trust"` words in `"Pride & Prejudice"` using the nrc lexicon.

```{r}
nrc_trust <- get_sentiments("_______") |>
  filter(sentiment == "_______")

tidy_books |>
  filter(book == "_______") |>
  ______(nrc_trust, by = "word") |>
  ______(word, sort = TRUE)
```

# 2.3 — Comparing three lexicons

## Same passage, three scorers

```{r}
emma_ch1 <- tidy_books |>
  _______(book == "_______", _______)
```


## AFINN: frequency and score

Create a new variable `contribution` as the frequency of word occurrence (`n`) times the numeric sentiment `value` of the word.

```{r}
afinn_words <- emma_ch1 |>
  ______(get_sentiments("afinn"), by = "word") |>
  ______(word, value, sort = TRUE) |>
  mutate(contribution = ______ * ______)

head(afinn_words)
```

## Plot AFINN

Is there a strong sentiment (repeated positive or negative words) in this chapter?

```{r}
afinn_words |>
  mutate(label = if_else(abs(contribution) >= 6, word, "")) |>
  ggplot(aes(n, value, color = value > 0, size = abs(contribution))) +
  geom_point(alpha = 0.75, show.legend = FALSE) +
  geom_text(aes(label = label), check_overlap = TRUE,
            show.legend = FALSE, vjust = -0.7) +
  scale_y_continuous(breaks = -5:5) +
  labs(x = "Count in chapter", y = "AFINN score")
```

## Bing: positive and negative words

Count the number of times the words appear, but now the sentiment is added.

```{r}
bing_words <- emma_ch1 |>
  ______(get_sentiments("bing"), by = "word") |>
  ______(word, sentiment, sort = TRUE)

head(bing_words)
```

## Plot Bing

Allowing us to compare the most frequent positive and negative words.

```{r}
bing_words |>
  ______(sentiment) |>
  slice_max(n, n = 5) |>
  ungroup() |>
  mutate(word = reorder_within(word, n, sentiment)) |>
  ggplot(aes(n, word, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  scale_y_reordered() +
  labs(x = "Count in chapter", y = NULL)
```

## NRC: ten categories

```{r}
nrc_words <- emma_ch1 |>
  ______(get_sentiments("nrc"), by = "word") |>
  ______(word, sentiment, sort = TRUE)

head(nrc_words)
```

## Plot NRC

```{r}
nrc_words |>
  ______(sentiment) |>
  slice_max(n, n = 5) |>
  ungroup() |>
  mutate(word = reorder_within(word, n, sentiment)) |>
  ggplot(aes(n, word, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y", nrow = 2) +
  scale_y_reordered() +
  labs(x = "Count in chapter", y = NULL)
```


# 2.4 — Check the words, not just the score

## Your turn — fix it

Add `"miss"` to a custom stop-word list, rebuild `bing_words`, and see the negative counts change.

```{r}
custom_stop <- tibble(word = "_______", lexicon = "custom")

emma_ch1 |>
  ______(custom_stop, by = "word") |>
  ______(get_sentiments("bing"), by = "word") |>
  ______(word, sentiment, sort = TRUE)
```

# 2.6 — Sentence-level sentiment

## Sentence scores with `sentimentr`

The single `sentiment()` function tokenizes on sentences AND calculates a sentence-level score.

## Apply it to Austen

Add a couple data wrangling steps so we can see the sentences along with the scores.

```{r}
_______ <- _______(_______) |>
  unlist()

p_and_p_sentences <- tibble(
  sentence_id = seq_along(_______),
  sentence = _______
)

scores <- _______(p_and_p_sentences$_______) |>
  mutate(sentence_id = element_id) |>
  select(sentence_id, _______ = sentiment)

pp_sentence_scores <- p_and_p_sentences |>
  left_join(scores, by = "sentence_id")
```

## Most negative sentences

```{r}
_______ |>
  ______(score) |>
  slice(1:5) |>
  pull(_______)
```

```{r}
pp_sentence_scores |>
  arrange(_______) |>
  slice(1:5) |>
  _______(score)
```

## Most positive sentences

```{r}
pp_sentence_scores |>
  arrange(_______) |>
  slice(1:5) |>
  pull(_______)
```

```{r}
pp_sentence_scores |>
  arrange(desc(_______)) |>
  slice(1:5) |>
  select(score)
```
