This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.
Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed. ##PACKAGES
library(cregg)
library(ggplot2)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ lubridate 1.9.3 ✔ tibble 3.2.1
## ✔ purrr 1.0.2 ✔ tidyr 1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readxl)
library(forcats)
library(tinytex)
data <- read_excel("Creator Help Center - finaldf.xlsx")
moderator <- read_excel("Creator Help Center - finalmoderator.xlsx")
##COLOURS
scale_colour_gradient2(name=waiver(), low = "#57ECB3", mid = "#FCC2DF" , high = "#FF82C1")
## <ScaleContinuous>
## Range:
## Limits: 0 -- 1
##PREPROCESSING FOR FULL CONJOINT
###Step 1: extract scenarios and drop NA
cj_data <- pivot_longer(data,
cols = -c(ResponseID, Screener_1, Screener_2, socialmedia_select, Followerstt, Historytt, Followersinsta, Historyinsta, Topic, Topic_20_TEXT, Shadowbann_expewarn, Shadowbann_expefeel, Shadowbann_search, Shadowbann_feature, Shadowbannawareness, feedback_ui, feedback_q, feedback_missing, feedback_idea),
names_to = "Scenario",
values_to = "Output",
values_drop_na = TRUE
)
###Step 2: extract attribute levels
cj_data <- separate(cj_data, Scenario, into = c("Timing", "Scale", "Inquiry", "Dep"), sep = "_", remove = FALSE)
cj_data$Scenario <- sub("_[^_]*$", "", cj_data$Scenario)
# Verify the changes
unique(cj_data$Timing)
## [1] "C" "explo" "B" "A"
###Step 3: extract outcome variables from the header
cj_data <- pivot_wider(cj_data, names_from = Dep, values_from = Output)
###Step 4: Rename the levels and outcome variables
names(cj_data)[which(names(cj_data) %in% c("S", "L1", "U", "L2","3"))] <- c("SenseofAgency", "LearnedHelplessness", "Understanding", "Action","Question")
cj_data <- cj_data %>%
mutate(Timing = case_when(
Timing == "A" ~ "Post Details",
Timing == "B" ~ "New Post",
Timing == "C" ~ "Post Analytics"
))
cj_data <- cj_data %>%
mutate(Scale= case_when(
Scale == "X" ~ "No scale",
Scale == "Y" ~ "Scale"
))
cj_data <- cj_data %>%
mutate(Inquiry= case_when(
Inquiry == "1" ~ "Community guideline",
Inquiry == "2" ~ "Community guideline + Get to know why",
Inquiry == "3" ~ "Community guideline + Ask why"
))
###Step 5: encoding of the Linkert scale
recode_scale <- function(x) {
case_when(
x == "Strongly disagree" ~ 1,
x == "Somewhat disagree" ~ 2,
x == "Neither agree nor disagree" ~ 3,
x == "Somewhat agree" ~ 4,
x == "Strongly agree" ~ 5
)
}
cj_data <- cj_data %>%
mutate_at(vars("SenseofAgency", "LearnedHelplessness", "Understanding", "Action"), recode_scale)
###Step 6: Cregg prep - Convert features variables into factors
features <- c("Timing", "Scale", "Inquiry", "Shadowbann_expewarn", "Shadowbann_expefeel", "Shadowbann_search", "Shadowbann_feature")
cj_data[features] <- lapply(cj_data[features], factor)
##PREPROCESSING FOR SUBGROUP ANALYSIS
###Step 1: Unite followers and history columns
cj_data <- cj_data %>%
unite("Followers", Followerstt, Followersinsta, sep = "/", remove = FALSE) %>%
mutate(Followers = if_else(is.na(Followersinsta), Followerstt, Followersinsta)) %>%
select(-Followerstt, -Followersinsta)
cj_data <- cj_data %>%
unite("History", Historytt, Historyinsta, sep = "/", remove = FALSE) %>%
mutate(History = if_else(is.na(Historyinsta), Historytt, Historyinsta)) %>%
select(-Historytt, -Historyinsta)
moderator <- moderator %>%
unite("Followers", Followerstt, Followersinsta, sep = "/", remove = FALSE) %>%
mutate(Followers = if_else(is.na(Followersinsta), Followerstt, Followersinsta)) %>%
select(-Followerstt, -Followersinsta)
moderator <- moderator %>%
unite("History", Historytt, Historyinsta, sep = "/", remove = FALSE) %>%
mutate(History = if_else(is.na(Historyinsta), Historytt, Historyinsta)) %>%
select(-Historytt, -Historyinsta)
###Step 2: Unite topics
cj_data <- cj_data %>%
unite("Topics", Topic, Topic_20_TEXT, sep = "", na.rm = TRUE)
moderator <- moderator %>%
unite("Topics", Topic, Topic_20_TEXT, sep = "", na.rm = TRUE)
cj_data$Topics <- gsub("Other please specify", "", cj_data$Topics)
moderator$Topics <- gsub("Other please specify", "", moderator$Topics)
##DESCRIPTIVE GRAPHS
###Participants
participants <- cj_data %>%
pull(ResponseID) %>%
n_distinct()
print(participants)
## [1] 19
###4outputs
ggplot(cj_data, aes(x = SenseofAgency)) +
geom_histogram(binwidth = 1, fill = "#57ECB3", color = "#244F26", alpha = 0.7) +
labs(title = "Distribution of Sense of Agency", x = "Sense of Agency", y = "Frequency") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree"))
## Warning: Removed 14 rows containing non-finite outside the scale range
## (`stat_bin()`).
ggplot(cj_data, aes(x = LearnedHelplessness)) +
geom_histogram(binwidth = 1, fill = "#FCC2DF", color = "#244F26", alpha = 0.7) +
labs(title = "Distribution of Learned Helplessness", x = "Learned Helplessness", y = "Frequency") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree"))
## Warning: Removed 14 rows containing non-finite outside the scale range
## (`stat_bin()`).
ggplot(cj_data, aes(x = Understanding)) +
geom_histogram(binwidth = 1, fill = "#95D185", color = "#244F26", alpha = 0.7) +
labs(title = "Distribution of Understanding", x = "Understanding", y = "Frequency")+
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree"))
## Warning: Removed 14 rows containing non-finite outside the scale range
## (`stat_bin()`).
ggplot(cj_data, aes(x = Action)) +
geom_histogram(binwidth = 1, fill = "#FF82C1", color = "#244F26", alpha = 0.7) +
labs(title = "Distribution of Action", x = "Action", y = "Frequency")+
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree"))
## Warning: Removed 14 rows containing non-finite outside the scale range
## (`stat_bin()`).
###askwhyquestions
questions <- data.frame(Question = na.omit(cj_data$Question))
questions <- questions[!grepl("same", questions$Question, ignore.case = TRUE), , drop = FALSE]
###Shadow banning
custom_labels <- c(
Shadowbann_expewarn = "Proxying",
Shadowbann_expefeel = "Decrease in analytics",
Shadowbann_search = "Search bar",
Shadowbann_feature = "Feature block"
)
shadowbann_df <- moderator %>%
pivot_longer(cols = c(Shadowbann_expewarn, Shadowbann_expefeel, Shadowbann_search, Shadowbann_feature), names_to = "Experiences", values_to = "Responses")
experience_freq <- shadowbann_df %>%
count(Experiences) %>%
arrange(n)
# Reorder Experiences based on ascending frequency
shadowbann_df <- shadowbann_df %>%
mutate(Experiences = factor(Experiences, levels = experience_freq$Experiences))
ggplot(shadowbann_df, aes(x = reorder(Experiences, -table(Experiences)[Experiences]), fill = Responses)) +
geom_bar(position = "dodge") +
scale_fill_manual(values = c("Never" = "#FCC2DF", "Rarely" = "#1EFC1E", "Sometimes" = "#57ECB3", "Frequently" = "#FF82C1", "Always" = "#244F26")) +
scale_x_discrete(labels = custom_labels) +
labs(x = " Shadow banning experiences", y = "Responses frequency") +
theme_minimal()
###Creator followers Reorder follower increasing range
moderator <- moderator %>%
group_by(Followers) %>%
mutate(Frequency = n())
moderator = moderator %>% mutate(Followers = factor(Followers, levels = c("0-100 followers", "101-500 followers", "501-1,000 followers", "1,001-5,000 followers","5,001-10,000 followers", "10,001-50,000 followers", "50,001-100,000 followers", "100,001-500,000 followers", "500,001-1,000,000 followers", "More than 1,000,000 followers")))
moderator %>% ggplot(aes(x=Followers, y = Frequency)) +
geom_bar(stat="identity", fill="#FF82C1") +
labs(title = "Frequency of Followers",
x = "Number of Followers",
y = "Frequency") +
theme_minimal() +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey")+
theme(legend.position = "none")
###Creator history
ggplot(cj_data, aes(x = History)) +
geom_bar(position = "dodge", fill = "#FCC2DF") +
labs(title = "Participant history on social media", x = "History", y = "Frequency") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
###Creator Topics
exclude_words <- c("and", "x", "other", "&", "/","i")
Recurrenttopics <- moderator %>%
mutate(Topics = tolower(Topics)) %>%
separate_rows(Topics, sep = "\\s+|,") %>%
filter(Topics != ""& !(Topics %in% exclude_words)) %>%
count(Topics, sort = TRUE)
head(Recurrenttopics, 10)
###Attribute frequencies
cj_data_long <- cj_data %>%
pivot_longer(cols = c(Timing, Scale, Inquiry), names_to = "Features", values_to = "Factor")
# Define custom labels for the x-axis
custom_labels <- c("New Post" = "New Post",
"Post Analytics" = "Post Analytics",
"Post Details" = "Post Details",
"No Scale" = "No Scale",
"Scale" = "Scale",
"Community guideline" = "Community guideline",
"Community guideline + Ask why" = "Community guideline + Ask why",
"Community guideline + Get to know why" = "Community guideline + Get to know why")
# Create the bar plot
ggplot(cj_data_long, aes(x = Factor, fill = Features)) +
geom_bar(position = "dodge") +
scale_fill_manual(values = c("Timing" = "#FF82C1", "Scale" = "#FCC2DF", "Inquiry" = "#57ECB3")) +
scale_x_discrete(labels = custom_labels) +
labs(title = "Features frequency", x = "Features", y = "Frequency") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
##MARGINAL MEANS
###Cj marginal means
#generate a table with marginal means values
mm1 <-
cj(
cj_data,
SenseofAgency ~ Timing + Scale + Inquiry,
id = ~ ResponseID,
estimate = "mm")
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
#plot
ggplot(mm1, aes(x = estimate, y = level, color = level)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Sense of Agency", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
mm2 <-
cj(
cj_data,
LearnedHelplessness ~ Timing + Scale + Inquiry,
id = ~ ResponseID,
estimate = "mm")
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
ggplot(mm2, aes(x = estimate, y = level, color = level)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Learned Helplessness", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
mm3 <-
cj(
cj_data,
Understanding ~ Timing + Scale + Inquiry,
id = ~ ResponseID,
estimate = "mm")
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
ggplot(mm3, aes(x = estimate, y = level, color = level)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Understanding", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
mm4 <-
cj(
cj_data,
Action ~ Timing + Scale + Inquiry,
id = ~ ResponseID,
estimate = "mm")
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
ggplot(mm4, aes(x = estimate, y = level, color = level)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Action", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
###Subgroup by shadowbanning
#encode the shadowbanning
cj_data <- cj_data %>%
mutate(Shadowbann_expewarn_group = case_when(
Shadowbann_expewarn %in% c("Always", "Frequently") ~ "high",
Shadowbann_expewarn== "Sometimes" ~ "medium",
Shadowbann_expewarn %in% c("Never", "Rarely") ~ "low",
TRUE ~ NA_character_
),
Shadowbann_expefeel_group = case_when(
Shadowbann_expefeel %in% c("Always", "Frequently") ~ "high",
Shadowbann_expefeel == "Sometimes" ~ "medium",
Shadowbann_expefeel %in% c("Never", "Rarely") ~ "low",
TRUE ~ NA_character_
),
Shadowbann_feature_group = case_when(
Shadowbann_feature %in% c("Always", "Frequently") ~ "high",
Shadowbann_feature == "Sometimes" ~ "medium",
Shadowbann_feature %in% c("Never", "Rarely") ~ "low",
TRUE ~ NA_character_
),
Shadowbann_search_group= case_when(
Shadowbann_search %in% c("Always", "Frequently") ~ "high",
Shadowbann_search == "Sometimes" ~ "medium",
Shadowbann_search %in% c("Never", "Rarely") ~ "low",
TRUE ~ NA_character_
))
#shadowaverage
weights <- c("low" = 1, "medium" = 2, "high" = 3)
cj_data <- cj_data %>%
mutate(across(ends_with("_group"), ~ifelse(is.na(.), NA, weights[.])))
cj_data$shadowaverage <- rowMeans(cj_data[, c("Shadowbann_expewarn_group", "Shadowbann_expefeel_group", "Shadowbann_feature_group", "Shadowbann_search_group")], na.rm = TRUE)
#split in 2 groups
cj_data$shadowgroup <- ifelse(cj_data$shadowaverage >= 2, 1, 0)
cj_data$shadowgroup <- factor(cj_data$shadowgroup)
#marginal means by shadowgroup
mm1_by <- cj(
cj_data,
SenseofAgency ~ Timing + Scale + Inquiry,
id = ~ResponseID,
estimate = "mm",
by = ~ shadowgroup)
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
mm2_by <- cj(
cj_data,
LearnedHelplessness ~ Timing + Scale + Inquiry,
id = ~ResponseID,
estimate = "mm",
by = ~ shadowgroup)
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
mm3_by <- cj(
cj_data,
Understanding ~ Timing + Scale + Inquiry,
id = ~ResponseID,
estimate = "mm",
by = ~ shadowgroup)
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
mm4_by <- cj(
cj_data,
Action ~ Timing + Scale + Inquiry,
id = ~ResponseID,
estimate = "mm",
by = ~ shadowgroup)
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
## Warning in logLik.svyglm(x): svyglm not fitted by maximum likelihood.
#plot
ggplot(mm1_by, aes(x = estimate, y = level, color = shadowgroup)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Sense of Agency by Shadow Banning", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
ggplot(mm2_by, aes(x = estimate, y = level, color = shadowgroup)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Learned Helplessness by Shadow Banning", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
ggplot(mm3_by, aes(x = estimate, y = level, color = shadowgroup)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Understanding by Shadow Banning", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
ggplot(mm4_by, aes(x = estimate, y = level, color = shadowgroup)) +
geom_point(position = position_dodge(width = 0.5), size = 2) + # Dot plot
geom_errorbar(aes(xmin = lower, xmax = upper), position = position_dodge(width = 0.5), width = .0, alpha = .7) +
theme_minimal() +
labs(x = "Marginal Mean for Action by Shadow Banning", y = "Attribute Level") +
theme(legend.position = "bottom") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "darkgrey") +
scale_x_continuous(breaks = c(1, 2, 3, 4, 5),
labels = c("Strongly disagree", "Somewhat disagree", "Neither agree nor disagree", "Somewhat agree", "Strongly agree")) +
theme(legend.position = "none")
##AMCE?