Last active
March 22, 2025 12:38
-
-
Save johnburnmurdoch/f8e7448d0cacb06ddc766c40d6859035 to your computer and use it in GitHub Desktop.
Replication code for Financial Times analysis of the association between getting news from TikTok and shifting towards Reform UK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Model impact on vote choice of having seen political content on social media | |
needs(tidyverse, stats, haven, survey, MASS) | |
# Read in BESIP trend file, which you can download from here: https://www.britishelectionstudy.com/data-object/british-election-study-combined-wave-1-29-internet-panel/ | |
BESIP_trend <- read_dta("path/to/BES2024_W29_Panel_v29A.0.dta", encoding = "latin1") | |
BESIP_trend_dd <- stata_summary(BESIP_trend) | |
# If social media political content is missing (because the respondent does not use that platform), code it the same way as people who said they saw no content | |
# Group education into four segments, including current full-time students | |
# Vote variables are vote intention as at May 2021 and immediately before the 2024 general election | |
data_for_model <- BESIP_trend %>% | |
transmute( | |
id, | |
sex = gender, | |
# Political info on TikTok | |
cand_TT = replace_na(socMediaInfo_TikTok_1W28,2), | |
friend_TT = replace_na(socMediaInfo_TikTok_2W28,2), | |
other_TT = replace_na(socMediaInfo_TikTok_3W28,2), | |
# Political info on YouTube | |
cand_YT = replace_na(socMediaInfo_Youtube_1W28,2), | |
friend_YT = replace_na(socMediaInfo_Youtube_2W28,2), | |
other_YT = replace_na(socMediaInfo_Youtube_3W28,2), | |
# Political info on Instagram | |
cand_IG = replace_na(socMediaInfo_Instagram_1W28,2), | |
friend_IG = replace_na(socMediaInfo_Instagram_2W28,2), | |
other_IG = replace_na(socMediaInfo_Instagram_3W28,2), | |
# Political info on Facebook | |
cand_FB = replace_na(fbInfo_1W28,2), | |
friend_FB = replace_na(fbInfo_2W28,2), | |
other_FB = replace_na(fbInfo_3W28,2), | |
# Demographics | |
age = ageW28, | |
educ = case_when( | |
p_work_statW28 == 4 ~ "Student", | |
p_educationW28 < 11 ~ "Less than A-levels", | |
p_educationW28 >= 11 & p_educationW28 <= 15 ~ "A-levels and/or FE", | |
p_educationW28 >= 16 & p_educationW28 <= 17 ~ "BA or higher", | |
T ~ "Other" | |
), | |
# Starting left-right position | |
lr = lr_scaleW21, | |
# Vote intention | |
v1 = generalElectionVoteW21, | |
v2 = generalElectionVoteW28, | |
weight = wt_new_W28 | |
) %>% | |
mutate( | |
# Combine political info vars into one yes/no binary per platform | |
TT = (cand_TT == 1 | friend_TT == 1 | other_TT == 1), | |
YT = (cand_YT == 1 | friend_YT == 1 | other_YT == 1), | |
IG = (cand_IG == 1 | friend_IG == 1 | other_IG == 1), | |
FB = (cand_FB == 1 | friend_FB == 1 | other_FB == 1) | |
) %>% | |
# Keep only records where we have a valid voting intention for both waves | |
drop_na(v1, v2) %>% | |
# Tidy up and keep only vars we need for the model | |
transmute( | |
id, | |
sex = as_character(sex), | |
age = as.numeric(age), | |
educ, | |
TT = as.numeric(TT), | |
YT = as.numeric(YT), | |
IG = as.numeric(IG), | |
FB = as.numeric(FB), | |
# Binary vars for Reform voting intention | |
ref1 = as.factor(as.numeric(v1 == 12)), | |
ref2 = as.factor(as.numeric(v2 == 12)), | |
weight | |
) | |
# Fit a logistic regression model, modelling probability of a Reform voting intention on election-eve, conditional on initial Reform VI three years prior, plus exposure to political content on different social media platforms, plus initial self-placement on left-right scale, plus socio-demographic controls for sex, age and highest education level, with interaction terms for social platform and sex | |
model_logit <- glm(ref2 ~ ref1 + TT:sex + FB:sex + YT:sex + IG:sex + sex + age + educ + lr, data = data_for_model, weights = weight, family = binomial()) | |
# Summary of results: | |
# TikTok and YouTube both have significant positive effects on Reform vote. Notably, the TikTok effect is both stronger and much more statistically significant for men than for women | |
summary(model_logit) | |
exp(coef(model_logit)) | |
# Model illustrative examples: | |
# A young man with less than A-levels who wasn’t planning to vote Reform in May 2021, and by July 2024 had not seen any political content on TikTok, had a 16% probability of voting Reform come July 2024 | |
predict(model_logit, type = "response", newdata = tibble(sex = "Male", age = 23, educ = "Less than A-levels", ref1 = as.factor(0), TT = 0, YT = 0, IG = 0, FB = 0)) | |
# A young man with less than A-levels who wasn’t planning to vote Reform in May 2021, and by July 2024 *had* seen political content on TikTok, had a 30% probability of voting Reform come July 2024 | |
predict(model_logit, type = "response", newdata = tibble(sex = "Male", age = 23, educ = "Less than A-levels", ref1 = as.factor(0), TT = 1, YT = 0, IG = 0, FB = 0)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I needed to install package
sjlabelled
in order to get theas_character()
function