
classroom
classroom.RmdTeaching with a public-domain corpus
Aesop’s fables are short, narrative, and structured around morals—which makes them unusually good for research methods teaching:
Operationalization: “What counts as sentiment?” “What counts as a theme?”
Measurement decisions: Tokenization, stop words, lexicon choice
Transparency & replication: Same corpus, different pipelines, different conclusions
Critical thinking: What do methods miss in moral storytelling?
We’ll use one fable as a running example: “The Fox and the Grapes.”
library(aesopR)
Helper: pick the fable (“Fox and the Grapes”)
fox_rows <- grepl("fox", aesops_fables$title, ignore.case = TRUE) &
grepl("grape", aesops_fables$title, ignore.case = TRUE)
fox_grapes <- aesops_fables[fox_rows, ]
fox_grapes[, c("fable_id", "title", "moral")]
fable_id <- fox_grapes$fable_id[1]
fable_id
Activity 1: “Guess the moral” from partial evidence
Goal: Show how conclusions depend on what evidence you allow yourself to see.
Setup (5 minutes):
Give students only the title and the top 10–15 words.
Ask them to write a one-sentence “predicted moral.”
Then reveal the full moral and discuss mismatches.
Instructor code: top words
fox_tokens <- aesops_tokens |> filter(fable_id == "005")
top_words <- fox_tokens |> count(word,sort = TRUE) |> slice_head(n = 10)
top_words
Prompt (students):
Based on the title and these words, what do you think happens?
What do you think the moral is?
What words might be misleading?
Discussion points:
Frequency ≠ importance
Stop words and narrative function words
“Theme inference” is not purely mechanical
Activity 2: “Methods as measurement” (lexicon comparison)
Goal: Demonstrate that measurement depends on instrument choice (lexicon choice).
Quick prompt (students):
Do these methods agree about whether the fable is “positive” or “negative”?
What kinds of words do they treat as meaningful?
Bing sentiment counts
fox_bing <- aesops_bing |> filter(fable_id == "005")
table(fox_bing$sentiment)
Identify sentiment-driving words (simple)
# Bing: which words appear most in each label?
sort(table(fox_bing$word[fox_bing$sentiment == "negative"]), decreasing = TRUE)[1:10]
sort(table(fox_bing$word[fox_bing$sentiment == "positive"]), decreasing = TRUE)[1:10]
# AFINN: strongest positive/negative words
afinn_ordered <- fox_afinn[order(fox_afinn$value), c("word", "value")]
head(afinn_ordered, 8)
tail(afinn_ordered, 8)
Discussion points:
Lexicons were built for different purposes
Context blindness (sarcasm, negation, narrative framing)
Reliability/validity analogy: lexicon as “instrument”
Activity 3: “Operational definitions” (what counts as a construct?)
Goal: Have students define a construct (e.g., “frustration” or “self-justification”)
and propose a text-based operationalization.
Small-group task (10–15 minutes):
Pick one construct and propose:
An operational definition in plain language
A rule-based measurement plan using tokens/sentiment
A limitation statement
Example constructs:
Frustration
Perseverance
Envy
Self-justification (“sour grapes”)
Rationalization
Instructor code: create simple “dictionary” counts
Below is a simple, transparent “dictionary method” that students can critique.
# Tiny hand-built dictionary (edit in-class)
rationalization_terms <- c("couldn't", "cannot", "never", "worth", "sour", "fine")
# Count dictionary hits
sum(fox_tokens$word %in% tolower(rationalization_terms))
Prompt (students):
Are these terms reasonable indicators?
What false positives/negatives might occur?
How would you improve the dictionary?
Discussion points:
Face validity vs construct validity
Researcher degrees of freedom
Pre-registration and transparency
devtools::document()
devtools::check()
pkgdown::build_site()