Race-conscious admission has been one of the ways to implement affirmative action in higher education. It has provided certain advantages in admission to applicants who are racially minoritized, such as Black and Hispanic individuals. Numerous controversies surrounding this system have continually arisen, along with a multitude of lawsuits. Since at least 1979, the year of the first landmark ruling from the Supreme Court allowing race to be considered in higher education admission, this system has long been in place in post-secondary education, until recently. However, on June 29th of last year, the Supreme Court overturned previous rulings and issued another landmark ruling stating race itself cannot be used in admission anymore.
This recent ruling is more complicated than previous cases because Asian-American students filed a lawsuit against Harvard University to overturn race-conscious admission, arguing that they have been consistently discriminated against in admissions as this system favored Black and other race-ethnicity students whose academic abilities are lower than Asians.
From the perspective of equity and equality, the public holds a variety of thoughts and opinions. The purpose of this paper is to analyze the major sentiments and topics regarding the race-conscious admission system and the recent ruling, focusing on changes before and after last year’s ruling.
Research questions for this study are as follows: 1. What sentiments are expressed in public comments regarding race-conscious admission? a) Are there differences between sentiments before and after the recent Supreme Court ruling? 2. What topics emerge from public comments? a) Are there differences in topics before and after the recent ruling?
To address these questions, sentiment analysis and topic modeling methods are employed. The primary audience for this study includes policymakers and administrators in higher education institutions, who may use the findings to operate future admission systems.
To gain insights into public sentiments and topics, this paper analyzed YouTube comments on broadcasts from five news agencies: Fox News, CNN, NBC, CBS, and ABC. These agencies were chosen to encompass a range of political perspectives, including both Republicans and Democrats, as well as moderates. According to the Pew Research Center (Jurkowitz et al., 2020), Republicans primarily rely on Fox news, while Democrats tend to turn to CNN and NBC. CBS and ABC are agencies that both Republicans and Democrats rely on (Jurkowitz et al., 2020). Republicans and Democrats generally hold different positions on affirmative action, so including both groups contributes to the credibility of the analysis.
To examine the change in the public’s sentiment and topics regarding race-conscious admission before and after the Court ruling, comments were collected from YouTube broadcasts of each news agency. YouTube videos from each news agencies were searched using several key terms such as ‘race-conscious admission’, ‘affirmative action in admission’. The criteria date was set as June 29th 2023, the date of the Supreme Court ruling. comments after the ruling were gathered from broadcasts on and after this date. Consequently, Public comments on the ruling were compiled as well. To collect comments before the ruling, the same key words were used to search for videos, enabling the collection of comments dating back to 2012.
# Preparing analysis
library(dplyr)
##
## 다음의 패키지를 부착합니다: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(readr)
library(tidyr)
library(rtweet)
library(writexl)
library(readxl)
library(tidytext)
library(textdata)
library(ggplot2)
library(textdata)
library(scales)
##
## 다음의 패키지를 부착합니다: 'scales'
## The following object is masked from 'package:readr':
##
## col_factor
library(tm)
## 필요한 패키지를 로딩중입니다: NLP
##
## 다음의 패키지를 부착합니다: 'NLP'
## The following object is masked from 'package:ggplot2':
##
## annotate
library(wordcloud)
## 필요한 패키지를 로딩중입니다: RColorBrewer
library(wordcloud2)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ lubridate 1.9.3 ✔ tibble 3.2.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ NLP::annotate() masks ggplot2::annotate()
## ✖ scales::col_factor() masks readr::col_factor()
## ✖ purrr::discard() masks scales::discard()
## ✖ dplyr::filter() masks stats::filter()
## ✖ purrr::flatten() masks rtweet::flatten()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidytext)
library(SnowballC)
library(topicmodels)
library(stm)
## stm v1.3.7 successfully loaded. See ?stm for help.
## Papers, resources, and other materials at structuraltopicmodel.com
library(ldatuning)
library(knitr)
library(LDAvis)
library(treemap)
library(lubridate)
library(gridExtra)
##
## 다음의 패키지를 부착합니다: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
# Import dataset
FOX_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "FOX")
CNN_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "CNN")
NBC_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "NBC")
CBS_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "CBS")
ABC_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "ABC")
FOX_1_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "FOX_1")
CNN_1_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "CNN_1")
NBC_1_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "NBC_1")
CBS_1_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "CBS_1")
ABC_1_comments <- read_xlsx("C:/Users/sag2f/Downloads/comments.xlsx", sheet = "ABC_1")
FOX_text <-
FOX_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "FOX") %>%
relocate(standards)
CNN_text <-
CNN_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "CNN") %>%
relocate(standards)
NBC_text <-
NBC_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "NBC") %>%
relocate(standards)
CBS_text <-
CBS_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "CBS") %>%
relocate(standards)
ABC_text <-
ABC_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "ABC") %>%
relocate(standards)
FOX_1_text <-
FOX_1_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "FOX") %>%
relocate(standards)
CNN_1_text <-
CNN_1_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "CNN") %>%
relocate(standards)
NBC_1_text <-
NBC_1_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "NBC") %>%
relocate(standards)
CBS_1_text <-
CBS_1_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "CBS") %>%
relocate(standards)
ABC_1_text <-
ABC_1_comments %>%
mutate(comment_reply = paste(Comment, Reply, sep = " ")) %>%
mutate(time_published = paste(Time, Published, sep = " ")) %>%
mutate(name = paste(Name, ReplyAuthor, sep = "")) %>%
select(name, comment_reply, time_published) %>%
mutate(standards = "ABC") %>%
relocate(standards)
YTcomments <- bind_rows(FOX_text, CNN_text, NBC_text, CBS_text, ABC_text, FOX_1_text, CNN_1_text, NBC_1_text, CBS_1_text, ABC_1_text)
# Dividing data into Before and After the ruling
YTcomments <- YTcomments %>%
mutate(time_published = if_else(substr(time_published, 1, 2) == "NA", substr(time_published, 4, nchar(time_published)), time_published))
YTcomments_before <- YTcomments %>%
filter(time_published < ymd("2023-06-29"))
YTcomments_after <- YTcomments %>%
filter(time_published >= ymd("2023-06-29"))
# Tokenization
YTcomments_before_tokens <- YTcomments_before %>%
unnest_tokens(output = word,
input = comment_reply,
token = "words")
YTcomments_after_tokens <- YTcomments_after %>%
unnest_tokens(output = word,
input = comment_reply,
token = "words")
# Removing stopwords,numbers, and other unnecessary words
filter_numeric_words <- function(data) {
data %>%
filter(!grepl("\\d", word))
}
### Besides stop words, certain tokens were frequently present in comments
### but may not significantly contribute to the analysis. So they have been excluded.
### Additionally, since "affirmative action" itself is a topic, it is included in both
### sentiment analysis and topic modeling with high frequency. Hence, it has been excluded from the analysis.
tidy_befor <-
YTcomments_before_tokens %>%
anti_join(stop_words, by = "word") %>%
filter(!word %in% c("na", "39", "br", "quot", "lol", "affirmative", "action"))
tidy_befor <- filter_numeric_words(tidy_befor)
tidy_afte <-
YTcomments_after_tokens %>%
anti_join(stop_words, by = "word") %>%
filter(!word %in% c("na", "39", "br", "quot", "lol", "affirmative", "action"))
tidy_afte <- filter_numeric_words(tidy_afte)
### Also, there are similar words such as 'asians' and 'asian'. Therefore, similar words
### are combined in one word.
replace_multiple_words <- function(data, word_col, replacement_pairs) {
for (pair in replacement_pairs) {
target_word <- pair[[1]]
replacement_word <- pair[[2]]
data <- mutate(data, {{word_col}} := ifelse({{word_col}} == target_word, replacement_word, {{word_col}}))
}
return(data)
}
replacement_pairs <- list(c("asians", "asian"), c("americans", "american"), c("students", "student"))
tidy_before <- replace_multiple_words(tidy_befor, word, replacement_pairs)
tidy_after <- replace_multiple_words(tidy_afte, word, replacement_pairs)
Now we are going to see what words and to what extent they appear in public comments before the Supreme Court ruling.
word_freq <- table(tidy_before$word)
word_freq <- table(tidy_before$word)
wordcloud(words = names(head(sort(word_freq, decreasing = TRUE), 100)),
freq = head(sort(word_freq, decreasing = TRUE), 100),
random.order = FALSE,
colors = brewer.pal(8, "Dark2"),
scale = c(3, 0.5))
It seems that the terms related to race are predominantly mentioned in the comments. Specifically, some news covered that Asian-American students filed a lawsuit against Harvard University that they have been discriminated from admission process due to race-conscious admission. I presume that is the reason why “Asian” is prevalent word, and also “White”, “black”, and “Harvard” appear in this word cloud.
Now let’s see what words and to what extent they appear in public comments after the Supreme Court ruling.
corpus <- Corpus(VectorSource(tidy_after$word))
corpus <- tm_map(corpus, content_transformer(tolower))
## Warning in tm_map.SimpleCorpus(corpus, content_transformer(tolower)):
## transformation drops documents
corpus <- tm_map(corpus, removePunctuation)
## Warning in tm_map.SimpleCorpus(corpus, removePunctuation): transformation drops
## documents
tdm <- TermDocumentMatrix(corpus)
word_freq <- rowSums(as.matrix(tdm))
word_freq <- head(sort(word_freq, decreasing = TRUE), 100)
colors <- brewer.pal(8, "Dark2")
wordcloud(words = names(word_freq), freq = word_freq, random.order = FALSE, colors = colors)
Unlike before the ruling, the most frequent words in public comments after the ruling are “people,” and “white”. Additionally, we can observe that words such as “Asian,” “black,” “race,” “student,” and “college” are frequently mentioned in the comments.
Sentiment analysis identifies whether text expresses positive or negative emotions using lexicons. In this analysis, four lexicons (i.e., afinn, bing, NRC, loughran) are employed, as each lexicon has different list of words.
# Four lexicons for sentiment analysis
afinn <- get_sentiments("afinn")
afinn
## # A tibble: 2,477 × 2
## word value
## <chr> <dbl>
## 1 abandon -2
## 2 abandoned -2
## 3 abandons -2
## 4 abducted -2
## 5 abduction -2
## 6 abductions -2
## 7 abhor -3
## 8 abhorred -3
## 9 abhorrent -3
## 10 abhors -3
## # ℹ 2,467 more rows
bing <- get_sentiments("bing")
bing
## # A tibble: 6,786 × 2
## word sentiment
## <chr> <chr>
## 1 2-faces negative
## 2 abnormal negative
## 3 abolish negative
## 4 abominable negative
## 5 abominably negative
## 6 abominate negative
## 7 abomination negative
## 8 abort negative
## 9 aborted negative
## 10 aborts negative
## # ℹ 6,776 more rows
nrc <- get_sentiments("nrc")
nrc
## # A tibble: 13,872 × 2
## word sentiment
## <chr> <chr>
## 1 abacus trust
## 2 abandon fear
## 3 abandon negative
## 4 abandon sadness
## 5 abandoned anger
## 6 abandoned fear
## 7 abandoned negative
## 8 abandoned sadness
## 9 abandonment anger
## 10 abandonment fear
## # ℹ 13,862 more rows
loughran <- get_sentiments("loughran")
loughran
## # A tibble: 4,150 × 2
## word sentiment
## <chr> <chr>
## 1 abandon negative
## 2 abandoned negative
## 3 abandoning negative
## 4 abandonment negative
## 5 abandonments negative
## 6 abandons negative
## 7 abdicated negative
## 8 abdicates negative
## 9 abdicating negative
## 10 abdication negative
## # ℹ 4,140 more rows
sentiment_afinn <- inner_join(tidy_before, afinn, by = "word")
sentiment_afinn
## # A tibble: 11,333 × 5
## standards name time_published word value
## <chr> <chr> <chr> <chr> <dbl>
## 1 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA free 1
## 2 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA motivated 2
## 3 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA desire 1
## 4 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA resolving 2
## 5 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win 4
## 6 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win 4
## 7 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA unjust -2
## 8 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA racists -3
## 9 FOX @terrybruce5923NA 2018-09-05T20:16:26Z NA damage -3
## 10 FOX @dendrobialbright7616NA 2018-07-13T06:47:46Z NA free 1
## # ℹ 11,323 more rows
sentiment_bing <- inner_join(tidy_before, bing, by = "word")
sentiment_bing
## # A tibble: 12,166 × 5
## standards name time_published word sentiment
## <chr> <chr> <chr> <chr> <chr>
## 1 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA free positive
## 2 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA proven positive
## 3 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA motivated positive
## 4 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA diversified positive
## 5 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win positive
## 6 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win positive
## 7 FOX @JamesSmith-vk2kyNA 2018-11-06T00:01:22Z NA succeed positive
## 8 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA correct positive
## 9 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA unjust negative
## 10 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA imbalance negative
## # ℹ 12,156 more rows
sentiment_nrc <- inner_join(tidy_before, bing, by = "word")
sentiment_nrc
## # A tibble: 12,166 × 5
## standards name time_published word sentiment
## <chr> <chr> <chr> <chr> <chr>
## 1 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA free positive
## 2 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA proven positive
## 3 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA motivated positive
## 4 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA diversified positive
## 5 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win positive
## 6 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win positive
## 7 FOX @JamesSmith-vk2kyNA 2018-11-06T00:01:22Z NA succeed positive
## 8 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA correct positive
## 9 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA unjust negative
## 10 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA imbalance negative
## # ℹ 12,156 more rows
sentiment_loughran <- inner_join(tidy_before, bing, by = "word")
sentiment_loughran
## # A tibble: 12,166 × 5
## standards name time_published word sentiment
## <chr> <chr> <chr> <chr> <chr>
## 1 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA free positive
## 2 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA proven positive
## 3 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA motivated positive
## 4 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA diversified positive
## 5 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win positive
## 6 FOX @akeejackson1474NA 2019-07-11T19:22:33Z NA win positive
## 7 FOX @JamesSmith-vk2kyNA 2018-11-06T00:01:22Z NA succeed positive
## 8 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA correct positive
## 9 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA unjust negative
## 10 FOX @hudsonhawk90NA 2018-11-04T21:36:00Z NA imbalance negative
## # ℹ 12,156 more rows
sentiment_afinn <- sentiment_afinn %>%
mutate(sentiment = ifelse(value > 0, "positive", ifelse(value < 0, "negative", "neutral")))
summary_afinn <- sentiment_afinn %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "AFINN") %>%
relocate(lexicon)
summary_afinn
## # A tibble: 5 × 5
## # Groups: standards [5]
## lexicon standards negative positive ratio
## <chr> <chr> <int> <int> <dbl>
## 1 AFINN ABC 335 213 0.636
## 2 AFINN CBS 186 118 0.634
## 3 AFINN CNN 4599 3584 0.779
## 4 AFINN FOX 611 345 0.565
## 5 AFINN NBC 772 570 0.738
summary_bing <- sentiment_bing %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(sentiment = positive - negative) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "bing") %>%
relocate(lexicon)
summary_bing
## # A tibble: 5 × 6
## # Groups: standards [5]
## lexicon standards negative positive sentiment ratio
## <chr> <chr> <int> <int> <int> <dbl>
## 1 bing ABC 363 196 -167 0.540
## 2 bing CBS 207 143 -64 0.691
## 3 bing CNN 5227 3400 -1827 0.650
## 4 bing FOX 756 406 -350 0.537
## 5 bing NBC 890 578 -312 0.649
summary_nrc <- sentiment_nrc %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(sentiment = positive - negative) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "nrc") %>%
relocate(lexicon)
summary_nrc
## # A tibble: 5 × 6
## # Groups: standards [5]
## lexicon standards negative positive sentiment ratio
## <chr> <chr> <int> <int> <int> <dbl>
## 1 nrc ABC 363 196 -167 0.540
## 2 nrc CBS 207 143 -64 0.691
## 3 nrc CNN 5227 3400 -1827 0.650
## 4 nrc FOX 756 406 -350 0.537
## 5 nrc NBC 890 578 -312 0.649
summary_loughran <- sentiment_loughran %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(sentiment = positive - negative) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "loughran") %>%
relocate(lexicon)
summary_loughran
## # A tibble: 5 × 6
## # Groups: standards [5]
## lexicon standards negative positive sentiment ratio
## <chr> <chr> <int> <int> <int> <dbl>
## 1 loughran ABC 363 196 -167 0.540
## 2 loughran CBS 207 143 -64 0.691
## 3 loughran CNN 5227 3400 -1827 0.650
## 4 loughran FOX 756 406 -350 0.537
## 5 loughran NBC 890 578 -312 0.649
combined_summary <- bind_rows(summary_afinn, summary_bing, summary_nrc, summary_loughran)
kable(combined_summary)
| lexicon | standards | negative | positive | ratio | sentiment |
|---|---|---|---|---|---|
| AFINN | ABC | 335 | 213 | 0.6358209 | NA |
| AFINN | CBS | 186 | 118 | 0.6344086 | NA |
| AFINN | CNN | 4599 | 3584 | 0.7792998 | NA |
| AFINN | FOX | 611 | 345 | 0.5646481 | NA |
| AFINN | NBC | 772 | 570 | 0.7383420 | NA |
| bing | ABC | 363 | 196 | 0.5399449 | -167 |
| bing | CBS | 207 | 143 | 0.6908213 | -64 |
| bing | CNN | 5227 | 3400 | 0.6504687 | -1827 |
| bing | FOX | 756 | 406 | 0.5370370 | -350 |
| bing | NBC | 890 | 578 | 0.6494382 | -312 |
| nrc | ABC | 363 | 196 | 0.5399449 | -167 |
| nrc | CBS | 207 | 143 | 0.6908213 | -64 |
| nrc | CNN | 5227 | 3400 | 0.6504687 | -1827 |
| nrc | FOX | 756 | 406 | 0.5370370 | -350 |
| nrc | NBC | 890 | 578 | 0.6494382 | -312 |
| loughran | ABC | 363 | 196 | 0.5399449 | -167 |
| loughran | CBS | 207 | 143 | 0.6908213 | -64 |
| loughran | CNN | 5227 | 3400 | 0.6504687 | -1827 |
| loughran | FOX | 756 | 406 | 0.5370370 | -350 |
| loughran | NBC | 890 | 578 | 0.6494382 | -312 |
All ratios are under 1, indicating that comments from all news agencies have more negative words than positive words, regardless of lexicons. With the exception of Afinn, the ratios from the other lexicons are consistent across all news agencies.
Let me illustrate whether there is difference across news agency.
combined_summary %>%
ggplot(aes(x = standards, y = ratio, fill = standards)) +
geom_bar(width = 0.8, stat = "identity") +
geom_hline(yintercept = 1) +
labs(title = "Sentiments ratio on race-conscious admission before the ruling",
subtitle = "October 2012 to June 18th 2023",
x = "Standards",
y = "Ratio of Positive Words / Negative Words") +
ylim(0, 1)
## Warning: Removed 15 rows containing missing values (`geom_bar()`).
Though it would be possibly influenced by the amount of comments, it seems that public comments from Fox News have relatively more negative words than comments from other news agencies. We should note that Republicans mostly rely on Fox News. In their conservative perspective, they might oppose race-conscious admission system; therefore, it makes sense that more negative sentiment appeared in comments of broadcasts from the Fox News.
Let’s look into what positive and negative words are in Fox News comments before the ruling. We are going to make treemap.
FOX_sentiment <- sentiment_bing %>%
filter(standards == "FOX")
# I chose top 8 words in both positive and negative sentiments.
top_positive_words <- FOX_sentiment %>%
filter(sentiment == "positive") %>%
count(word) %>%
top_n(8, wt = n)
top_negative_words <- FOX_sentiment %>%
filter(sentiment == "negative") %>%
count(word) %>%
top_n(8, wt = n)
# And I will show it with treemap.
word_counts <- bind_rows(
mutate(top_positive_words, sentiment = "positive"),
mutate(top_negative_words, sentiment = "negative")
)
positive_palette <- c("#66c2a5", "#8da0cb", "#e78ac3", "#a6d854")
negative_palette <- c("#fc8d62", "#e78ac3", "#8da0cb", "#a6d854")
word_counts <- word_counts %>%
mutate(sentiment_type = ifelse(sentiment == "negative", "Negative", "Positive"))
# Drawing a treemap
treemap(word_counts, index = "word", vSize = "n", vColor = "sentiment_type",
palette = c(Negative = negative_palette, Positive = positive_palette))
It is strange that “Trump” is considered as a positive word in this analysis. However, we can observe that “racist” and “racism” are the most frequently mentioned negative sentiments, and “merit” and “fair” are also frequently discussed in public sentiments on Fox News before the ruling.
Not only for Fox News comments, but also for overall proportions of positive and negative words,we are going to examine proportion of positive and negative sentiments across all news agencies. We are going to use “bing” lexicon as all lexicon shows the same ratios except for Afinn.
bing_sentiment <- combined_summary %>%
filter(lexicon == "bing")
bing_sentiment %>%
summarise(total_positive = sum(positive),
total_negative = sum(negative),
ratio = total_negative / total_positive) %>%
pivot_longer(cols = c(total_positive, total_negative),
names_to = "Sentiment before",
values_to = "Total Count") %>%
ggplot(aes(x = "", y = `Total Count`, fill = `Sentiment before`)) +
geom_col(width = 0.5) +
geom_text(aes(label = ifelse(`Sentiment before` == "Total Count", "", "")),
position = position_stack(vjust = 0.5),
size = 0) +
labs(title = "Sentiment Ratio of Before the Ruling",
y = "Total Count",
fill = "Sentiment") +
theme_minimal() +
coord_polar(theta = "y")
We can observe that there are more negative sentiments expressed across all news agencies compared to positive sentiments.
Now we are going to analyze public sentiment after the Supreme Court ruling, using four lexicons.
sentiment_afinn_a <- inner_join(tidy_after, afinn, by = "word")
sentiment_afinn_a
## # A tibble: 7,833 × 5
## standards name time_published word value
## <chr> <chr> <chr> <chr> <dbl>
## 1 FOX @umpire29NA 2023-07-04T17:07:48Z NA cut -1
## 2 FOX @umpire29NA 2023-07-04T17:07:48Z NA yeah 1
## 3 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA dream 1
## 4 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA dream 1
## 5 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA responsible 2
## 6 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA responsible 2
## 7 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA damned -4
## 8 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA responsible 2
## 9 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA pay -1
## 10 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA war -2
## # ℹ 7,823 more rows
sentiment_bing_a <- inner_join(tidy_after, bing, by = "word")
sentiment_bing_a
## # A tibble: 8,825 × 5
## standards name time_published word sentiment
## <chr> <chr> <chr> <chr> <chr>
## 1 FOX @andypearson3776NA 2023-08-30T03:50:45Z NA supreme positive
## 2 FOX @andypearson3776NA 2023-08-30T03:50:45Z NA corruption negative
## 3 FOX @David-pf5tfNA 2023-07-09T01:36:10Z NA merit positive
## 4 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA damned negative
## 5 FOX @darzellenone7626NA 2023-07-04T14:03:29Z NA supreme positive
## 6 FOX @darzellenone7626NA 2023-07-04T14:03:29Z NA capable positive
## 7 FOX @Punisher1830NA 2023-07-03T20:05:47Z NA racism negative
## 8 FOX @chuck9380NA 2023-07-03T02:10:42Z NA loopholes negative
## 9 FOX @chuck9380NA 2023-07-03T02:10:42Z NA rich positive
## 10 FOX @chuck9380NA 2023-07-03T02:10:42Z NA wealthy positive
## # ℹ 8,815 more rows
sentiment_nrc_a <- inner_join(tidy_after, bing, by = "word")
sentiment_nrc_a
## # A tibble: 8,825 × 5
## standards name time_published word sentiment
## <chr> <chr> <chr> <chr> <chr>
## 1 FOX @andypearson3776NA 2023-08-30T03:50:45Z NA supreme positive
## 2 FOX @andypearson3776NA 2023-08-30T03:50:45Z NA corruption negative
## 3 FOX @David-pf5tfNA 2023-07-09T01:36:10Z NA merit positive
## 4 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA damned negative
## 5 FOX @darzellenone7626NA 2023-07-04T14:03:29Z NA supreme positive
## 6 FOX @darzellenone7626NA 2023-07-04T14:03:29Z NA capable positive
## 7 FOX @Punisher1830NA 2023-07-03T20:05:47Z NA racism negative
## 8 FOX @chuck9380NA 2023-07-03T02:10:42Z NA loopholes negative
## 9 FOX @chuck9380NA 2023-07-03T02:10:42Z NA rich positive
## 10 FOX @chuck9380NA 2023-07-03T02:10:42Z NA wealthy positive
## # ℹ 8,815 more rows
sentiment_loughran_a <- inner_join(tidy_after, bing, by = "word")
sentiment_loughran_a
## # A tibble: 8,825 × 5
## standards name time_published word sentiment
## <chr> <chr> <chr> <chr> <chr>
## 1 FOX @andypearson3776NA 2023-08-30T03:50:45Z NA supreme positive
## 2 FOX @andypearson3776NA 2023-08-30T03:50:45Z NA corruption negative
## 3 FOX @David-pf5tfNA 2023-07-09T01:36:10Z NA merit positive
## 4 FOX @badwabbit1973NA 2023-07-04T15:03:37Z NA damned negative
## 5 FOX @darzellenone7626NA 2023-07-04T14:03:29Z NA supreme positive
## 6 FOX @darzellenone7626NA 2023-07-04T14:03:29Z NA capable positive
## 7 FOX @Punisher1830NA 2023-07-03T20:05:47Z NA racism negative
## 8 FOX @chuck9380NA 2023-07-03T02:10:42Z NA loopholes negative
## 9 FOX @chuck9380NA 2023-07-03T02:10:42Z NA rich positive
## 10 FOX @chuck9380NA 2023-07-03T02:10:42Z NA wealthy positive
## # ℹ 8,815 more rows
sentiment_afinn_a <- sentiment_afinn_a %>%
mutate(sentiment = ifelse(value > 0, "positive", ifelse(value < 0, "negative", "neutral")))
summary_afinn_a <- sentiment_afinn_a %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "AFINN") %>%
relocate(lexicon)
summary_afinn_a
## # A tibble: 5 × 5
## # Groups: standards [5]
## lexicon standards negative positive ratio
## <chr> <chr> <int> <int> <dbl>
## 1 AFINN ABC 245 182 0.743
## 2 AFINN CBS 2233 1863 0.834
## 3 AFINN CNN 324 230 0.710
## 4 AFINN FOX 815 646 0.793
## 5 AFINN NBC 725 570 0.786
summary_bing_a <- sentiment_bing_a %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(sentiment = positive - negative) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "bing") %>%
relocate(lexicon)
summary_bing_a
## # A tibble: 5 × 6
## # Groups: standards [5]
## lexicon standards negative positive sentiment ratio
## <chr> <chr> <int> <int> <int> <dbl>
## 1 bing ABC 282 189 -93 0.670
## 2 bing CBS 2607 1988 -619 0.763
## 3 bing CNN 380 238 -142 0.626
## 4 bing FOX 1022 737 -285 0.721
## 5 bing NBC 825 557 -268 0.675
summary_nrc_a <- sentiment_nrc_a %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(sentiment = positive - negative) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "nrc") %>%
relocate(lexicon)
summary_nrc_a
## # A tibble: 5 × 6
## # Groups: standards [5]
## lexicon standards negative positive sentiment ratio
## <chr> <chr> <int> <int> <int> <dbl>
## 1 nrc ABC 282 189 -93 0.670
## 2 nrc CBS 2607 1988 -619 0.763
## 3 nrc CNN 380 238 -142 0.626
## 4 nrc FOX 1022 737 -285 0.721
## 5 nrc NBC 825 557 -268 0.675
summary_loughran_a <- sentiment_loughran_a %>%
group_by(standards) %>%
count(sentiment, sort = TRUE) %>%
spread(sentiment, n) %>%
mutate(sentiment = positive - negative) %>%
mutate(ratio = positive / negative) %>%
mutate(lexicon = "loughran") %>%
relocate(lexicon)
summary_loughran_a
## # A tibble: 5 × 6
## # Groups: standards [5]
## lexicon standards negative positive sentiment ratio
## <chr> <chr> <int> <int> <int> <dbl>
## 1 loughran ABC 282 189 -93 0.670
## 2 loughran CBS 2607 1988 -619 0.763
## 3 loughran CNN 380 238 -142 0.626
## 4 loughran FOX 1022 737 -285 0.721
## 5 loughran NBC 825 557 -268 0.675
combined_summary_a <- bind_rows(summary_afinn_a, summary_bing_a, summary_nrc_a, summary_loughran_a)
kable(combined_summary_a)
| lexicon | standards | negative | positive | ratio | sentiment |
|---|---|---|---|---|---|
| AFINN | ABC | 245 | 182 | 0.7428571 | NA |
| AFINN | CBS | 2233 | 1863 | 0.8343036 | NA |
| AFINN | CNN | 324 | 230 | 0.7098765 | NA |
| AFINN | FOX | 815 | 646 | 0.7926380 | NA |
| AFINN | NBC | 725 | 570 | 0.7862069 | NA |
| bing | ABC | 282 | 189 | 0.6702128 | -93 |
| bing | CBS | 2607 | 1988 | 0.7625623 | -619 |
| bing | CNN | 380 | 238 | 0.6263158 | -142 |
| bing | FOX | 1022 | 737 | 0.7211350 | -285 |
| bing | NBC | 825 | 557 | 0.6751515 | -268 |
| nrc | ABC | 282 | 189 | 0.6702128 | -93 |
| nrc | CBS | 2607 | 1988 | 0.7625623 | -619 |
| nrc | CNN | 380 | 238 | 0.6263158 | -142 |
| nrc | FOX | 1022 | 737 | 0.7211350 | -285 |
| nrc | NBC | 825 | 557 | 0.6751515 | -268 |
| loughran | ABC | 282 | 189 | 0.6702128 | -93 |
| loughran | CBS | 2607 | 1988 | 0.7625623 | -619 |
| loughran | CNN | 380 | 238 | 0.6263158 | -142 |
| loughran | FOX | 1022 | 737 | 0.7211350 | -285 |
| loughran | NBC | 825 | 557 | 0.6751515 | -268 |
Just like the sentiments and ratios before the Court ruling, all ratios are under 1, indicating that comments from all news agencies have more negative words than positive words, regardless of lexicons. Additionally, the sentiment ratios in each news agency are identical across lexicons except for Afinn.
I created bar graph of ratio of each news agency to examine difference among them.
combined_summary_a %>%
ggplot(aes(x = standards, y = ratio, fill = standards)) +
geom_bar(width = 0.8, stat = "identity") +
geom_hline(yintercept = 1) +
labs(title = "Sentiments ratio on race-conscious admission after the ruling",
subtitle = "June 23th 2023 to Present",
x = "Standards",
y = "Ratio of Positive Words / Negative Words") +
ylim(0, 1)
## Warning: Removed 15 rows containing missing values (`geom_bar()`).
The sentiment ratios appear similar across news agencies, but comments on CNN have relatively more negative words compared to positive words. Considering CNN is a news agency that Democrats rely on, they might usually support race-conscious admission. Then it makes sense that there are more negative sentiments regarding the Supreme Court ruling, which bans the consideration of race itself in future admission systems.
Let me further examine the sentiments of comments from CNN after the Court ruling.
CNN_sentiment <- sentiment_bing_a %>%
filter(standards == "CNN")
top_positive_words_a <- CNN_sentiment %>%
filter(sentiment == "positive") %>%
count(word) %>%
top_n(8, wt = n)
top_negative_words_a <- CNN_sentiment %>%
filter(sentiment == "negative") %>%
count(word) %>%
top_n(8, wt = n)
word_counts_a <- bind_rows(
mutate(top_positive_words_a, sentiment = "positive"),
mutate(top_negative_words_a, sentiment = "negative")
)
positive_palette <- c("#66c2a5", "#8da0cb", "#e78ac3", "#a6d854") # 파스텔톤의 초록색들
negative_palette <- c("#fc8d62", "#e78ac3", "#8da0cb", "#a6d854") # 파스텔톤의 주황색들
word_counts_a <- word_counts_a %>%
mutate(sentiment_type = ifelse(sentiment == "negative", "Negative", "Positive"))
# Let me illustrate the top eight positive and negative words from CNN comments using a treemap.
treemap(word_counts_a, index = "word", vSize = "n", vColor = "sentiment_type",
palette = c(Negative = negative_palette, Positive = positive_palette))
Similarly with comments of Fox News of before the Court ruling, “racism”, “racist”, and “discrimination” were mentioned most frequently in negative sentiments.
Not only for CNN comments, but also for overall proportions of positive and negative words, we are going to examine proportion of positive and negative sentiments across all news agencies, using sentiment examined by bing lexicon. (As I mentioned before, all lexicon shows the same ratios.)
bing_sentiment_a <- combined_summary_a %>%
filter(lexicon == "bing")
bing_sentiment_a %>%
summarise(total_positive = sum(positive),
total_negative = sum(negative),
ratio = total_negative / total_positive) %>%
pivot_longer(cols = c(total_positive, total_negative),
names_to = "Sentiment after",
values_to = "Total Count") %>%
ggplot(aes(x = "", y = `Total Count`, fill = `Sentiment after`)) +
geom_col(width = 0.5) +
geom_text(aes(label = ifelse(`Sentiment after` == "Total Count", "", "")),
position = position_stack(vjust = 0.5),
size = 0) +
labs(title = "Sentiment Ratio of After the Ruling",
y = "Total Count",
fill = "Sentiment") +
theme_minimal() +
coord_polar(theta = "y")
Compared to the proportion of before the Court ruling, there are slightly more positive sentiments in comments after the Court ruling. This might mean that more people shows little more agreement with banning affirmative action in higher education. However, there are more negative sentiments than positive one toward race-conscious admission even after the ruling.
Let me show this difference with sentiment proportion of before and after the ruling at the same time.
a <- bing_sentiment %>%
summarise(total_positive = sum(positive),
total_negative = sum(negative),
ratio = total_negative / total_positive) %>%
pivot_longer(cols = c(total_positive, total_negative),
names_to = "Sentiment before",
values_to = "Total Count") %>%
ggplot(aes(x = "", y = `Total Count`, fill = `Sentiment before`)) +
geom_col(width = 0.5) +
geom_text(aes(label = ifelse(`Sentiment before` == "Total Count", "", "")),
position = position_stack(vjust = 0.5),
size = 0) +
labs(title = "Sentiment Ratio of Before the Ruling",
y = "Total Count",
fill = "Sentiment") +
theme_minimal() +
coord_polar(theta = "y")
b <- bing_sentiment_a %>%
summarise(total_positive = sum(positive),
total_negative = sum(negative),
ratio = total_negative / total_positive) %>%
pivot_longer(cols = c(total_positive, total_negative),
names_to = "Sentiment after",
values_to = "Total Count") %>%
ggplot(aes(x = "", y = `Total Count`, fill = `Sentiment after`)) +
geom_col(width = 0.5) +
geom_text(aes(label = ifelse(`Sentiment after` == "Total Count", "", "")),
position = position_stack(vjust = 0.5),
size = 0) +
labs(title = "Sentiment Ratio of After the Ruling",
y = "Total Count",
fill = "Sentiment") +
theme_minimal() +
coord_polar(theta = "y")
grid.arrange(a, b, ncol = 2)
As we can see, there is a slightly higher proportion of positive sentiment after the ruling than before the ruling. However, it is not that big change. Additionally, we should also note that there are more negative sentiments in both before and after the ruling.
Topic modeling is part of a class of text analysis methods that analyze “bags” or groups of words together—instead of counting them individually in order to capture how the meaning of words is dependent upon the broader context in which they are used in natural language (Bail, 2020). Two main ways of topic modeling are Latent Dirichlet Allocation (LDA) and Structural Topic Modeling (STM). This analysis employs both LDA and STM will be employed to find topics within public comments.
Similarly with sentiment analysis conduct, We are going to see whether there is difference in topics between comments from before the ruling and comments from after the ruling.
We are going to first examine topics in comments of before the ruling.
# Stemming and Document Term Matrix
stemmed_before <- tidy_before %>%
mutate(stem = wordStem(word))
before_dtm <- stemmed_before %>%
count(name, stem) %>%
cast_dtm(name, stem, n)
We have to set the right number of K to conduct topic modeling. There are several measures to find the K.
# Finding K
k_metrics <- FindTopicsNumber(
before_dtm,
topics = seq(1, 10, by = 1),
metrics = c("Griffiths2004", "CaoJuan2009", "Arun2010", "Deveaud2014"),
method = "Gibbs"
)
FindTopicsNumber_plot(k_metrics)
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
## of ggplot2 3.3.4.
## ℹ The deprecated feature was likely used in the ldatuning package.
## Please report the issue at <https://github.com/nikita-moor/ldatuning/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Graph shows that common crossover point is nearly 4. So we are going to use 4 for the value of k.
An LDA model was run using 4 as topic count K. And the data excluded the term “affirmative” and “action” because of its prevalence. As affirmative action is a topic itself, excluding these terms would be reasonable.
before_lda <- LDA(before_dtm,
k = 4,
control = list(seed = 588)
)
before_lda
## A LDA_VEM topic model with 4 topics.
Let’s look at longer lists of the terms in each topic to see more differentiation.
terms(before_lda, 10)
## Topic 1 Topic 2 Topic 3 Topic 4
## [1,] "peopl" "harvard" "asian" "school"
## [2,] "racist" "admiss" "white" "student"
## [3,] "white" "base" "black" "asian"
## [4,] "racism" "race" "american" "race"
## [5,] "color" "student" "peopl" "colleg"
## [6,] "skin" "don’t" "african" "peopl"
## [7,] "trump" "it’" "countri" "black"
## [8,] "minor" "asian" "latino" "score"
## [9,] "equal" "merit" "privileg" "educ"
## [10,] "don" "monei" "america" "american"
The four topics look slightly different each other.
Now we are going to further examine these topics.
tidy_lda <- tidy(before_lda)
tidy_lda
## # A tibble: 29,324 × 3
## topic term beta
## <int> <chr> <dbl>
## 1 1 cnn 3.12e- 3
## 2 2 cnn 1.71e- 6
## 3 3 cnn 2.37e-11
## 4 4 cnn 6.54e-13
## 5 1 domest 2.14e- 4
## 6 2 domest 1.63e-13
## 7 3 domest 1.15e- 5
## 8 4 domest 3.04e-20
## 9 1 lt 6.24e- 4
## 10 2 lt 3.13e-22
## # ℹ 29,314 more rows
top_terms <- tidy_lda %>%
group_by(topic) %>%
slice_max(beta, n = 10, with_ties = FALSE) %>%
ungroup() %>%
arrange(topic, -beta)
top_terms %>%
mutate(term = reorder_within(term, beta, topic)) %>%
group_by(topic, term) %>%
arrange(desc(beta)) %>%
ungroup() %>%
ggplot(aes(beta, term, fill = as.factor(topic))) +
geom_col(show.legend = FALSE) +
scale_y_reordered() +
labs(title = "Top 10 terms in each LDA topic",
x = expression(beta), y = NULL) +
facet_wrap(~ topic, ncol = 4, scales = "free")
Considering graph each topic could be:
Topic 1: Trump administration policy which does not consider skin color anymore - could it be racism? Topic 2: Whether Harvard University’s race-based admission does not consider Asians Topic 3: How to consider various race-ethnicity in higher education Topic 4: Issues in schools with race-conscious admission (especially regarding score discrepancy among students)
Now we are going to see relative popularity of each topic, measured by the statistic gamma.
td_beta <- tidy(before_lda)
td_gamma <- tidy(before_lda, matrix = "gamma")
td_beta
## # A tibble: 29,324 × 3
## topic term beta
## <int> <chr> <dbl>
## 1 1 cnn 3.12e- 3
## 2 2 cnn 1.71e- 6
## 3 3 cnn 2.37e-11
## 4 4 cnn 6.54e-13
## 5 1 domest 2.14e- 4
## 6 2 domest 1.63e-13
## 7 3 domest 1.15e- 5
## 8 4 domest 3.04e-20
## 9 1 lt 6.24e- 4
## 10 2 lt 3.13e-22
## # ℹ 29,314 more rows
td_gamma
## # A tibble: 12,644 × 3
## document topic gamma
## <chr> <int> <dbl>
## 1 @0Diazzz0NA 1 0.793
## 2 @1115keyNA 1 0.561
## 3 @111GtfoNA 1 0.435
## 4 @1231nlpNA 1 0.164
## 5 @13HangfireNA 1 0.655
## 6 @18890426NA 1 0.118
## 7 @1940limitedNA 1 0.349
## 8 @1966bluemaxNA 1 0.140
## 9 @1titansNA 1 0.102
## 10 @236HerbinatorNA 1 0.659
## # ℹ 12,634 more rows
top_terms <- td_beta %>%
arrange(beta) %>%
group_by(topic) %>%
top_n(10, beta) %>%
arrange(-beta) %>%
select(topic, term) %>%
summarise(terms = list(term)) %>%
mutate(terms = map(terms, paste, collapse = ", ")) %>%
unnest()
## Warning: `cols` is now required when using `unnest()`.
## ℹ Please use `cols = c(terms)`.
gamma_terms <- td_gamma %>%
group_by(topic) %>%
summarise(gamma = mean(gamma)) %>%
arrange(desc(gamma)) %>%
left_join(top_terms, by = "topic") %>%
mutate(topic = paste0("Topic ", topic),
topic = reorder(topic, gamma))
gamma_terms %>%
select(topic, gamma, terms) %>%
kable(digits = 3,
col.names = c("Topic", "Expected topic proportion", "Top 10 terms"))
| Topic | Expected topic proportion | Top 10 terms |
|---|---|---|
| Topic 1 | 0.320 | peopl, racist, white, racism, color, skin, trump, minor, equal, don |
| Topic 4 | 0.252 | school, student, asian, race, colleg, peopl, black, score, educ, american |
| Topic 3 | 0.218 | asian, white, black, american, peopl, african, countri, latino, privileg, america |
| Topic 2 | 0.209 | harvard, admiss, base, race, student, don’t, it’, asian, merit, monei |
The above chart tells that the topics appear in proportions, varying between 20.9% and 32%. We should expect topic 1 appears 32% in comments, topic 4 appears 25.2%, topic 3 appears 21.8%, topic 2 appears 20.9%.
There are many ways to conduct topic modeling besides LDA. Structural Topic Modeling (STM) is one of the popular techniques in recent year and very similar to LDA (Bail, 2020). STM uses meta data about documents to enhance the allocation of words to latent topics within a corpus (Bail, 2020).
temp <- textProcessor(YTcomments_before$comment_reply,
metadata = YTcomments_before,
lowercase=TRUE,
removestopwords=TRUE,
removenumbers=TRUE,
removepunctuation=TRUE,
wordLengths=c(3,Inf),
stem=TRUE,
onlycharacter= FALSE,
striphtml=TRUE,
customstopwords=NULL)
## Building corpus...
## Converting to Lower Case...
## Removing punctuation...
## Removing stopwords...
## Removing numbers...
## Stemming...
## Creating Output...
meta <- temp$meta
vocab <- temp$vocab
docs <- temp$documents
# We are going to use 4 for k in STM as well.
before_stm <- stm(documents=docs,
data=meta,
vocab=vocab,
K=4,
max.em.its=25,
verbose = FALSE)
before_stm
## A topic model with 4 topics, 5094 documents and a 8967 word dictionary.
Now, we are going to see to what extent topics are distributed.
toLDAvis(mod = before_stm, docs = docs)
## 필요한 네임스페이스를 로딩합니다: servr
Although topic 3 and 4 are partly overlapped, other topics are separated each other.
STM with four topics shows the following chart that includes expected topic proportions and top words in each topic.
plot.STM(before_stm, n = 10)
Approximately 38% of comments are topic 2: Asian-Americans’ argument that college admission has yielded discrimination, 33% of comments are topic 3: Whether Harvard University can make justice for both Whites and Blacks, with affirmative action, 19% of comments are topic 4: Public opinions on race and job opportunity, 16% of comments are topic 1: Actual benefit that students in minor race-ethnicity receive in university.
We can see examples of comments in each topic as follows, though it includes foreign language other than English.
before_reduced <-YTcomments_before$comment_reply[-temp$docs.removed]
findThoughts(before_stm,
texts = before_reduced,
topics = 1:4,
n = 1,
thresh = 0.4)
##
## Topic 1:
## NA @WE WUZ VIKANGS!!! n shiet. "outrage" me. friggin lil punk...lol...
## Topic 2:
## NA @@cj2708 I had a much longer, more comprehensive reply to the last message, however I decided to save it in a word doc as a personal journal entry and respond with a shorter statement because the reply was becoming too long and the argument one that I don't want to expand upon. I like to have these discussions, however when I have to explain every little thing in detail the whole discussion becomes less appealing. The part where the discussion becomes somewhat annoying is when you claim that Asians are as individualistic as Americans, which is far from the truth. It's clear that you were offended. <br><br><br>I never stated that "if you belong to a certain Ethnicity, you MUST act a certain way". Don't misrepresent what I said. We are not talking about individuals, we are talking about groups. When analyzing groups, generalizations are made to most accurately depict the group in a concise manner. This does not assert in absolutes, but instead in tendencies over time periods. In reality different groups of people behave differently. An example is the following statement: Christians are more tolerant of gay people when compared to Muslims. Analysis supports the claim very easily because it is measurable when looking at how certain nations persecute these individuals differently. There are, nonetheless, exceptions to this 'rule' or generalization. What we are talking about are tendencies of certain groups. Tendencies which reflect the values and ideals of the groups in question. You are implying that if there are exceptions then generalizations cannot be made and, therefore, you are also inadvertently implying that one cannot say anything about any group of people because exceptions exist in every group (within a reasonable sample size of course). The whole basis of this discussion is analyzing the scores of Asians, which tend to be higher based on X, Y and Z, which you have already stated. The contradiction is that you argue against these very generalizations which show up statistically. These very statistics support the claim that there are different tendencies within the various groups. <br><br><br>I also find it somewhat hard to believe that you legitimately have lived in these separate areas, as you don't actually understand the difference in thought to any significant degree. It is possible that you haven't explored the various populations you've been around pertaining to certain aspects of life in dialogue. Nonetheless, there is a distinct rift in thought along the Collectivism vs. Individualism spectrum; both of which have good arguments for and against. If you want to understand why Asians think how they do, you have to look at their society's history. I'm assuming you are Asian American, but not actually very American ethnically given your interpretation of our people. <br><br><br>On Chinese(Asian) vs American culture:<br>The dominant player in the discussion would be China, which boasts a large immigrant population in the US and is the dominant group of people in what people consider Asia (excluding India, The Middle East and Russia due to geological, ethnic and genetic variation) <br>Chinese culture, to a large degree, was shaped by Confucius more than 2 thousand years ago. Although there was more diversity in thought, the Chinese emperors decided that Confucianism was the best route and indoctrinated the rest of the population to reflect this decision. Confucianism was likely favored and, therefore, adopted because of the behavior it promoted among the general population. A major aspect of the teaching goes like this: the father is the head of the household and the rest of the family should be obedient, The emperor is to the state what the father is to the household and those under the emperor should be obedient to the emperor like a wife and kids are to the father. By relating the family to society, for a man to revolt against the emperor would be similar to condoning his own wife revolting against himself and, therefore, undermine his own stature in the home. This level of obedience is argued to promote order and stability in the nation, which it did for much of Chinese history and is still prevalent in China today despite the changes occurring. It is very intelligent in many ways, however it is very Collectivist in nature. <br>The United States is on the other end of the spectrum, as it was born of revolution and rebellion and still embodies many of those ideals today; such as life, liberty and the pursuit of happiness all of which trump any justification for restriction of individual activity and freedom. The right to free speech, The right to bear arms, the right to assemble, the right to property, the right to privacy, the right to "no taxation without representation". There are pros and cons to both systems. China vs. America, Collectivist vs Individualist. Not necessarily better or worse in either direction, just different.<br><br><br>I also find it somewhat offensive to describe Americans as "gun-slinging red-necking" simply for valuing the empowerment of the general population and the individual via being armed: an idea which is a fundamental aspect of American culture and is one of the most effective checks on the power of the central government.
## Topic 3:
## Right-Wing: Fake News by Fake Experts, Left-Wing: Deplorables and Uneducated! This is the outcome of Harvard Fake Graduates because of the intervention of Affirmative Action, the Deplorables will surely qualify Harvard anytime because they can identify Fake Experts and Fake News. hi hi hi hi! I can't think seriously... the world turns funnier and funnier because of left-wing and right-wing politics. NA
## Topic 4:
## "We relate to you such accounts of earlier towns : some of them are still standing, while others have cease to exist,<br>We did not wrong them, they wronged themselves.. (100,101 Hud)<br><br>In the ancient chronicles events relating to King and military generals have been mentioned but events relating to prophets and their communities find no place therein.<br>History as written by man has omitted those very things which in the eyes of the Creator, were most worthy of mention.<br>However the Quran describes at great length the dawah work performed by the Prophets and the reaction of their addressees to the call. Other matters have been ignored by the Quran as being of no importance.<br><br>Whenever a man indulges in arrogance and transgression, he does so on the strength of some notion.<br>He considers something or beings as supports and thinks that they will continue to be so in difficult times.<br>But these supports will be such for only so long as the God gives them leave.<br>When according to the law of God, the period of respite ends and God announces His final verdict, then man will come to know that the assumptions which in his foolishness he had made about his "supports" were all false.<br><br>The QURAN, translation and commentary by Maulana Wahiduddin Khan free download from <a href="http://www.cpsglobal.org/">www.cpsglobal.org</a> <br>دعوت کا اسلوب<br><br>ربیعہ بن عباد الدیلی روایت کرتے ہیں کہ انهوں نے رسول اللہ کو ذوالمجاز کے سوق میں دیکها- آپ لوگوں کے پاس جاتے اور ان سے کہتے : یاایهاالناس قولوا :لا اله الااللہ ، تفلحوا(مسند احمد : 16063)- اس روایت کو لے کر بعض لوگ کہتے ہیں کہ دعوت کا صحیح طریقہ یہ ہے کہ لوگوں سے مل کر ان کو کلمہ پڑهنے کے لیے کہا جائے- اس کے علاوه دعوت کا کوئی اور اسلوب درست نہیں هو سکتا- <br><br>اگر دعوت کا یہی واحد اسلوب تها تو قرآن میں یقینا اس کو بتایا گیا هوتا- مگر هم دیکهتے ہیں کہ قرآن میں ایسی کوئی هدایت موجود نہیں- البتہ قرآن کے مطالعے سے اس سلسلے میں کئی اسلوب ملتے ہیں- مثلا یاایها المدثر قم فآنذر (74:1-2)- اسی طرح اس سلسلے میں قرآن کی ایک آیت یہ ہے : یا ایها الرسول بلغ ما انزل الیک من ربک (5:66)- خود احادیث سے بهی دوسرے اسالیب معلوم هوتے ہیں- مثلا ایک روایت میں یہ الفاظ آئے ہیں : عرض علیهم الاسلام ، وتلا علیهم القرآن (سیت ابن هشام :1/428) ، وغیره -<br><br> اصولی طور پر دعوت کا صرف ایک اسلوب ہے، اور وه قرآن کی ایک آیت میں اس طرح بتایا گیا ہے : قل لهم فی انفسهم قولا بلیغا (4:63)- یعنی ان سے ایسے اسلوب میں کلام کرو جو ان کے ذہن کو ایڈریس کرنے والا هو- اس قرآنی ہدایت کے مطابق ظاہری اعتبار سے دعوت کے مختلف اسلوب هو سکتے ہیں- اسلوب ہمیشہ مخاطب کے اعتبار سے متعین هو گا- پہلے مخاطب کا مطالعہ کیا جائے گا، اور پهر اس کے ذہن کے اعتبار سے ایسا اسلوب اختیار کیا جائے گا جو اس کے ذہن کو اپیل کرنے والا هو-<br><br>دعوت کا نشانہ یہ ہے کہ مدعو کے اوپر اتمام حجت هو جائے : یعنی تاکہ رسولوں کے بعد لوگوں کے پاس اللہ کے مقابلہ میں کوئی حجت باقی نہ رہے- (<a href="https://www.youtube.com/watch?v=19i_MfsIDg0&t=256">4:16</a>5) حجت کبهی کسی قسم کے مقرر الفاظ کی ادائیگی سے نہیں هوتی- حجت کے لیے ضروری ہے کہ اس میں مدعو کے ذہن کی رعایت کی گئی هو- حقیقت یہ ہے کہ دعوت کا اسلوب مدعو کے اعتبار سے متعین هو گا، نہ کہ کسی اور اعتبار سے-<br><br>الرسالہ، ستمبر 2015<br>مولانا وحیدالدین خان NA
Now we are going to examine topics in comments of after the ruling.
# Stemming and Document Term Matrix
stemmed_after <- tidy_after %>%
mutate(stem = wordStem(word))
after_dtm <- stemmed_after %>%
count(name, stem) %>%
cast_dtm(name, stem, n)
We have to set the right number of K to conduct topic modeling. There are several measures to find the K, and graph shows that common crossover point is nearly 6.
# Finding K
k_metrics_a <- FindTopicsNumber(
after_dtm,
topics = seq(1, 10, by = 1),
metrics = c("Griffiths2004", "CaoJuan2009", "Arun2010", "Deveaud2014"),
method = "Gibbs"
)
FindTopicsNumber_plot(k_metrics_a)
We are going to use 6 as a k value.
after_lda <- LDA(after_dtm,
k = 6,
control = list(seed = 588)
)
after_lda
## A LDA_VEM topic model with 6 topics.
Let’s look at longer lists of the terms in each topic to see more differentiation
terms(after_lda, 10)
## Topic 1 Topic 2 Topic 3 Topic 4 Topic 5 Topic 6
## [1,] "racism" "student" "white" "race" "school" "court"
## [2,] "peopl" "color" "peopl" "colleg" "student" "suprem"
## [3,] "colleg" "black" "black" "admiss" "kid" "decis"
## [4,] "racist" "colleg" "asian" "legaci" "parent" "justic"
## [5,] "govern" "skin" "american" "base" "colleg" "rule"
## [6,] "countri" "race" "minor" "discrimin" "rich" "law"
## [7,] "democrat" "peopl" "major" "equal" "monei" "discrimin"
## [8,] "system" "base" "final" "applic" "fund" "god"
## [9,] "commun" "divers" "republican" "merit" "educ" "vote"
## [10,] "race" "merit" "qualifi" "educ" "children" "racist"
The six topics looks slightly different each other. Now we are going to further examine these topics.
tidy_lda_after <- tidy(after_lda)
tidy_lda_after
## # A tibble: 37,908 × 3
## topic term beta
## <int> <chr> <dbl>
## 1 1 accept 2.26e-19
## 2 2 accept 7.65e- 3
## 3 3 accept 6.02e- 7
## 4 4 accept 3.14e-12
## 5 5 accept 3.55e- 3
## 6 6 accept 6.90e-17
## 7 1 action 3.87e-20
## 8 2 action 7.11e- 4
## 9 3 action 4.79e- 4
## 10 4 action 2.11e- 4
## # ℹ 37,898 more rows
top_terms_after <- tidy_lda_after %>%
group_by(topic) %>%
slice_max(beta, n = 10, with_ties = FALSE) %>%
ungroup() %>%
arrange(topic, -beta)
top_terms_after %>%
mutate(term = reorder_within(term, beta, topic)) %>%
group_by(topic, term) %>%
arrange(desc(beta)) %>%
ungroup() %>%
ggplot(aes(beta, term, fill = as.factor(topic))) +
geom_col(show.legend = FALSE) +
scale_y_reordered() +
labs(title = "Top 10 terms in each LDA topic",
x = expression(beta), y = NULL) +
facet_wrap(~ topic, ncol = 4, scales = "free")
The Graph depicts each topic as follows: Topic 1: Whether banning race-conscious admission could be racism Topic 2: Contemplating students’ skin color versus their merits in admission for fostering diversity in colleges Topic 3: Considering students’ qualification in admission regardless of race or major/minor groups Topic 4: Legacy admission as another form of discrimination system alongside race-conscious admission Topic 5: The advantages of kid with rich parents and highly funded schools resulting from the banning of race-conscious admission Topic 6: Justification of the Supreme Court’s decision; whether it signifies achieving justice or aligns with racist beliefs Now we are going to see the relative popularity.
td_beta_after <- tidy(after_lda)
td_gamma_after <- tidy(after_lda, matrix = "gamma")
td_beta_after
## # A tibble: 37,908 × 3
## topic term beta
## <int> <chr> <dbl>
## 1 1 accept 2.26e-19
## 2 2 accept 7.65e- 3
## 3 3 accept 6.02e- 7
## 4 4 accept 3.14e-12
## 5 5 accept 3.55e- 3
## 6 6 accept 6.90e-17
## 7 1 action 3.87e-20
## 8 2 action 7.11e- 4
## 9 3 action 4.79e- 4
## 10 4 action 2.11e- 4
## # ℹ 37,898 more rows
td_gamma_after
## # A tibble: 19,608 × 3
## document topic gamma
## <chr> <int> <dbl>
## 1 @--xX_Xx--NA 1 0.0403
## 2 @05jorgeruizNA 1 0.0254
## 3 @0penthaughtzNA 1 0.0101
## 4 @10-10-NA 1 0.0354
## 5 @1001HobbiesNA 1 0.00998
## 6 @1219supermanNA 1 0.0593
## 7 @12NordseeNA 1 0.0137
## 8 @1515candoNA 1 0.0223
## 9 @17NateJohnsonNA 1 0.00897
## 10 @18S12NA 1 0.0179
## # ℹ 19,598 more rows
top_terms_after <- td_beta_after %>%
arrange(beta) %>%
group_by(topic) %>%
top_n(10, beta) %>%
arrange(-beta) %>%
select(topic, term) %>%
summarise(terms = list(term)) %>%
mutate(terms = map(terms, paste, collapse = ", ")) %>%
unnest()
## Warning: `cols` is now required when using `unnest()`.
## ℹ Please use `cols = c(terms)`.
gamma_terms_after <- td_gamma_after %>%
group_by(topic) %>%
summarise(gamma = mean(gamma)) %>%
arrange(desc(gamma)) %>%
left_join(top_terms_after, by = "topic") %>%
mutate(topic = paste0("Topic ", topic),
topic = reorder(topic, gamma))
gamma_terms_after %>%
select(topic, gamma, terms) %>%
kable(digits = 3,
col.names = c("Topic", "Expected topic proportion_after", "Top 10 terms"))
| Topic | Expected topic proportion_after | Top 10 terms |
|---|---|---|
| Topic 2 | 0.205 | student, color, black, colleg, skin, race, peopl, base, divers, merit |
| Topic 6 | 0.188 | court, suprem, decis, justic, rule, law, discrimin, god, vote, racist |
| Topic 4 | 0.181 | race, colleg, admiss, legaci, base, discrimin, equal, applic, merit, educ |
| Topic 3 | 0.150 | white, peopl, black, asian, american, minor, major, final, republican, qualifi |
| Topic 5 | 0.146 | school, student, kid, parent, colleg, rich, monei, fund, educ, children |
| Topic 1 | 0.130 | racism, peopl, colleg, racist, govern, countri, democrat, system, commun, race |
The above chart tells that the topics appear in proportions, varying between 13% and 20.5%. We should expect that topic 2 appears 20.5% in comments, topic 6 appears 18.8%, topic 4 appears 18.1%, topic 3 appears 15%, topic 5 appears 14.6 %, topic 1 appears 13% in comments.
temp_after <- textProcessor(YTcomments_after$comment_reply,
metadata = YTcomments_after,
lowercase=TRUE,
removestopwords=TRUE,
removenumbers=TRUE,
removepunctuation=TRUE,
wordLengths=c(3,Inf),
stem=TRUE,
onlycharacter= FALSE,
striphtml=TRUE,
customstopwords=NULL)
## Building corpus...
## Converting to Lower Case...
## Removing punctuation...
## Removing stopwords...
## Removing numbers...
## Stemming...
## Creating Output...
temp_after
## A text corpus with 5164 documents, and an 8108 word dictionary.
meta_after <- temp_after$meta
vocab_after <- temp_after$vocab
docs_after <- temp_after$documents
## We are going to use the same value of K with LDA modeling.
after_stm <- stm(documents=docs_after,
data=meta_after,
vocab=vocab_after,
K=6,
max.em.its=25,
verbose = FALSE)
after_stm
## A topic model with 6 topics, 5164 documents and a 8108 word dictionary.
Now, we are going to see to what extent topics are distributed.
toLDAvis(mod = after_stm, docs = docs_after)
Topic 1, 2, and 3 are overlapped each other, but topic 4, 5, and 6 distributed.
We will assign a label to each topic based on their anticipated proportion in the dataset.
plot.STM(after_stm, n = 10)
Approximately 23% of comments are topic 4: Whether the Court decision was good or racism regarding equal admission, especially when considering legacy admission issue, 18% of comments are topic 6: Question about the right time for universities to terminate race-conscious admission which considers students’ skin colors, 17% of comments are topic 2: How long does it take for school to change their admission system based on law (i.e., the Supreme Court ruling), 16% of comments are topic 5: Now we should still think about better admission system than race (color)-based admission, 15% of comments are topic 3: The influence of the Supreme Court ruling on merit based admission that many Black applicants should compete with other races, 14% of comments are topic 1: The influence of banning affirmative action on Asian students, kids, and diversity in U.S.
We can see examples of comments in each topic as follows
after_reduced <-YTcomments_after$comment_reply[-temp_after$docs.removed]
findThoughts(after_stm,
texts = after_reduced,
topics = 1:6,
n = 1,
thresh = 0.4)
##
## Topic 1:
## « أَعُوذُ بِكَلِمَاتِ اللهِ التَّامَّاتِ مِنْ شَرِّ مَا خَلَقَ »<br>(( I seek refuge by the complete, perfect words of Allaah from the evil of what He has created )) NA
## Topic 2:
## Pronuncio-me como Cavaliere Della Madre; com insígnias para honrar a América e levantar personas para uma Civilização de Valor Pessoal e também Político em países como Austrália, Singapura, etc, etc. Valho-me de conceitos-avantes e valores intrínsecos ao suporte do viver de nossa espécie (e quiçá, outras; segundo o que vemos via JWT).
<br>Defendo que Trump foi "assaltado" em seu cargo na cara dos Americanos e do Mundo; e isto se deu por conluio de pastores evangélicos ladro-narco-milício-corruptos com uma maçonaria estragada, unidos em tráfico e milícias covardes, sob o "bafo" baderneiro-sabotador de países encoberto (em vermelho-preto-azul. numa ruína maquinada da Fé legítima e Valores legítimos solapados) sorrateiramente num AFRO-Nazismo (que persegue, espreita, difama, rouba, sabota, mata, destruindo empresas e a Sociedade, e descaradamente outras etnias; para a soberba e regalo de bandos malignos que posicionaram "bonecos" criminosos em cargos máximos já em várias nações; tendo isto sido encubado no Brasil pela podridão "pulhítica" que ali se vê).
<br>Há príncipes “fajutos” atuando deslavadamente nesse conluio de “empoderamento” da canalhice que está desgraçando as empresas e finanças em várias partes do Mundo; que está destruindo o Brasil (cite-se a destruição insana em Angra dos Reis). Quanto à isso, um aviso: A Celestial Madre os avisou; e já está na mão dos verdadeiros poderosos a “seta que voa de dia”.
<br>Conquanto, é de Valor, Fibra, e Fé, que não só os Americanos devem lançar à frente o Brio de suas faces e recuperar desses bandidos o que nos roubaram e destruíram.
<br>OBS: Essa desgraça arrebentou a Política e Sociedades países na América do Sul, rumou para os EUA, Austrália, e já atraiçoou a soberania do povo russo.
<br>Putin deve mirar em incursões de “missões” do submundo “da paz”; embustes gritantes entupiram a América de tráfico-milicianos antes das eleições americanas; e agora os ladro-corruptos “abençoados” intentam desarmar os americanos (como se fez deploravelmente no território brasileiro; onde o povo padece vigiado por um “deus no controle”, que nada mais é que, a mais perversa e depravada corrupção e desfaçatez criminosa, generalizada, e sem escape -- se a atenção dos poderes internacionais não acudir). NA
## Topic 3:
## NA @@scottowensbyable My grandmother was a book keeper @ Blake, Moffet and Towne Papaer in San Francisco.<br>She was born at the turn of the century and lifed through The San Francisco Earthquake<br>WWI, the Spanish Flu, the Depression, WWII, and all supsequesnt MIC wars up until she died in 96' at 90 and a self-made millionaire.<br>She didn't go to college.
## Topic 4:
## NA @@hartfordsignpost589And Dr's, accountants, sales reps, policemen, firemen, etc etc.<br>Enough of these woke racist quotas!
## Topic 5:
## NA @@goldbud2287 <br>Go Jack Smith, Bragg and Willis in Georgia. Send your losing cult leader all of your money.🤡🤭💰💰💰
## Topic 6:
## NA @@wgsmit02Many people go by what the MEDIA pushes and promotes and people tend to forget that which is HATE AND PRIVILEGE.....people use that energy in their everyday lives. Some people are TAUGHT HATE😮💯<br><br>Although you are right about what you said also....it's deeper than all of what they have people fighting over!
The purpose of this paper is to see if there is difference in sentiments and topics regarding race-conscious admission among the public before and after the Supreme Court ruling, which banned race-conscious admission. The results show that there are differences in both sentiments and topics between before and after the ruling.
Specifically, in sentiment analysis, a slightly higher proportion of positive sentiment has been observed in comments from broadcasts after the Court ruling compared to the proportion of sentiments in comments before the ruling. However, it is important to note that the proportion of positive and negative sentiments on race-conscious admission tends toward negative sentiments. Thus, overall sentiments toward race-conscious admission are generally more negative than positive.
Additionally, different topics were identified from each set of
comments before and after the ruling. Before the Court ruling, public
comments on race-conscious admission suggested four different topics as
follows, which were identified through a combination of LDA and STM: 1)
Trump administration’s policy banning affirmative action 2) Harvard
University’s race-based admission policies and discrimination against
Asian-Americans 3) How to implement affirmative action in higher
education without alleged discrimination
4) The actual benefits that students from minority racial and ethnic
backgrounds receive in universities.
After the Court ruling, topics from public comments are as follows; these are also a combination of LDA and STM: 1) Justification of the decision from the Supreme Court; whether banning race-conscious admission could be racism? 2) Considering students’ race versus merits in admission 3) Legacy admission issue 4) How to achieve equity without considering race 5) The appropriate timing to terminate race-conscious admission system 6) How long it takes for schools to incorporate the Supreme Court ruling into their admission system? 7) The impact of banning affirmative action on Asian students, kids, and diversity in U.S.
There is a need to focus on the finding that topics regarding race-conscious admission became much more varied and specific after the Court ruling. The public questioned the justification of ruling and whether it is the right time to revoke affirmative action. Additionally, they are interested in more specific ways to realize race-neutral measures, along with ramification in U.S. society.
Given the Supreme Court ruling would be much more influential on institutions actively implementing affirmative action, it requires actions based on deliberation and reflection of public concerns.
Furthermore, from the perspective that affirmative action is reverse discrimination, the legacy admission system, which refers to the practice of giving preferential treatment to applicants who have family members who attended the same institution, has arisen in controversy. In this analysis, the public also raised questions and concerns about it; if race-conscious admission violates the Constitution due to its inequality, how about legacy admission? Is this fair system? Therefore, policymakers and administrators should prepare how they might answer the above inquiries and handle the admission system to create a fairer academic environment.
I believe there are no ethical or legal concerns in this analysis, but there is a limitation pertaining to the data analyzed in this paper. While YouTube comments provide opinions and thoughts from the publics, comments are brief and respond to specific news topics. Therefore, they might not include contents as comprehensive or specific as that found in Tweeter or news articles regarding race-conscious admission. In a follow-up study, using another dataset would allow researcher to gain more comprehensive sentiments and topics with greater insights.
Bail, C. (2020). Topic modeling. Retrieved from https://sicss.io/2020/materials/day3-text-analysis/topic-modeling/rmarkdown/Topic_Modeling.html#running-your-first-topic-model
Jurkowitz, M., Mitchell, A., Shearer, E., & Walker, M. (2020). Americans are divided by party in the resources they turn to for political news. Pew Research Center. Retrieved from https://www.pewresearch.org/journalism/2020/01/24/americans-are-divided-by-party-in-the-sources-they-turn-to-for-political-news/