Skip to content

Instantly share code, notes, and snippets.

@johnburnmurdoch
Last active March 22, 2025 12:38
Show Gist options
  • Save johnburnmurdoch/f8e7448d0cacb06ddc766c40d6859035 to your computer and use it in GitHub Desktop.
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
# 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))
@aaz
Copy link

aaz commented Mar 22, 2025

I needed to install package sjlabelled in order to get the as_character() function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment