---
title: "Orthogonality Study 6"
author: "Jim A.C. Everett & Simon Myers"
date: "`r format(Sys.time(), '%B %d, %Y')`"
output:
  html_document:
    theme: flatly
    code_folding: hide
    toc: true
    toc_depth: 3
    toc_float: 
      collapsed: TRUE
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
options(knitr.kable.NA = '')
```

***

# Description

***

In this study, participants first saw a vignette about an AI (vs a Human) that was very low in intelligence (described in terms of instrumental rationality), and answered to questions about how intelligent, moral (decomposed into moral competence and moral motivation index questions), dangerous and trustworthy the agent was. Participants then read vignettes stating that the agent, due to a new technique, has either rapidly increased in intelligence or morality.  Finally, participants once again answered the same questions, given that the agent has now been augmented. This meant we had a 2x2 mixed design: Intelligence Augmentation (Pre vs Post - Within Subjects) and Agent (AI vs Humans - Between Subjects). 

***

# Setup

***

Before doing any analyses, we just need to load the data file and do some initial basis preparation.

```{r, results='hide', message=FALSE, warning=FALSE}
library(readr)
library(psych)
library(car)
library(tidyverse)
library(knitr)
library(kableExtra)
library(jmv)
library(BayesFactor)
library(effectsize)
library(gtsummary)
library(rempsyc)
library(see)
library(correlation)
library(lavaan)
library(emmeans)
library(ggnewscale)
library(patchwork)
library(lme4)
library(lmerTest)
library(broom)
library(broom.mixed)
library(ggeffects)
```

***

We'll load the data and make sure the conditions are set as factors.

```{r}
# Load in data
df <- read.csv("Study_6_Data.csv", header=TRUE, stringsAsFactors=FALSE)

# set conditions as factors
df$Agent <- as.factor(df$Agent)

# relevel factors
df$Agent <- 
  factor(df$Agent, 
         levels = c("Human", "AI"))

```

***

We can just see the numbers per condition. In total, we have `r nrow(df)` participants.

```{r}
condition_table <- df %>%
  count(Agent) %>%
  arrange(Agent)


kable(condition_table, format = "html",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

***

Sometimes we'll need to just look at participants in the morality conditions, or the intelligence conditions, so we'll create dataframes for this. We'll actually do this for different "levels" as well as the full 8 condition breakdown, which might be interesting for the correlations.

```{r}
# First we break down just whether it is a human or an AI condition.
df_human <- df  %>% filter(Agent == "Human")
df_AI <- df  %>% filter(Agent == "AI")
```

***

Because this is within-subjects, we'll also need to start reshaping the data for the analyses.

```{r}
df_long <- df %>%
  select(
    Participant = Participant,
    Agent,
    Familiarity,
    Pew_Correct,
    matches("^(Pre|Post)_.+")
  ) %>%
  pivot_longer(
    cols = matches("^(Pre|Post)_.+"),  # Only pivot actual rating variables
    names_to = c("Time", "Outcome"),
    names_pattern = "^(Pre|Post)_(.+)$",
    values_to = "Rating"
  ) %>%
  mutate(
    Time = factor(Time, levels = c("Pre", "Post")),
    Outcome = factor(Outcome),
    Agent = factor(Agent),
  )


# set condition as factor & relevel
df_long$Agent <- as.factor(df_long$Agent)

df_long$Agent <- 
  factor(df_long$Agent, 
         levels = c("Human", "AI"))

```

As outlined in the pre-reg, three of the items were about moral competence and three were about moral motivation, so we can report the Cronbach's alpha reliability. We'll do this first for the Pre measures, then for the Post.

```{r}
# Moral Competence (Pre)
alpha_pre_competence <- psych::alpha(df %>% select(
  Pre_Moral_Knowledge, Pre_Moral_Predict, Pre_Moral_Explain
))

# Moral Competence (Pre Comparison)
alpha_pre_competence_comp <- psych::alpha(df %>% select(
  Pre_Moral_Knowledge_Comparison, Pre_Moral_Predict_Comparison, Pre_Moral_Explain_Comparison
))

# Moral Motivation (Pre)
alpha_pre_motivation <- psych::alpha(df %>% select(
  Pre_Moral_Help, Pre_Moral_Harm, Pre_Moral_Fair
))

# Moral Motivation (Pre Comparison)
alpha_pre_motivation_comp <- psych::alpha(df %>% select(
  Pre_Moral_Help_Comparison, Pre_Moral_Harm_Comparison, Pre_Moral_Fair_Comparison
))

# Combine into summary table
alpha_pre_table <- tibble(
  Scale = c(
    "Pre_Moral_Competence",
    "Pre_Moral_Competence_Comparison",
    "Pre_Moral_Motivation",
    "Pre_Moral_Motivation_Comparison"
  ),
  Cronbach_Alpha = c(
    alpha_pre_competence$total$raw_alpha,
    alpha_pre_competence_comp$total$raw_alpha,
    alpha_pre_motivation$total$raw_alpha,
    alpha_pre_motivation_comp$total$raw_alpha
  )
)

# Display
kable(alpha_pre_table, format = "html", digits = 3, row.names = FALSE) %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")

```

And this is for the post.

```{r}
# Moral Competence (Post)
alpha_post_competence <- psych::alpha(df %>% select(
  Post_Moral_Knowledge, Post_Moral_Predict, Post_Moral_Explain
))

# Moral Competence (Post Comparison)
alpha_post_competence_comp <- psych::alpha(df %>% select(
  Post_Moral_Knowledge_Comparison, Post_Moral_Predict_Comparison, Post_Moral_Explain_Comparison
))

# Moral Motivation (Post)
alpha_post_motivation <- psych::alpha(df %>% select(
  Post_Moral_Help, Post_Moral_Harm, Post_Moral_Fair
))

# Moral Motivation (Post Comparison)
alpha_post_motivation_comp <- psych::alpha(df %>% select(
  Post_Moral_Help_Comparison, Post_Moral_Harm_Comparison, Post_Moral_Fair_Comparison
))

# Combine into summary table
alpha_post_table <- tibble(
  Scale = c(
    "Post_Moral_Competence",
    "Post_Moral_Competence_Comparison",
    "Post_Moral_Motivation",
    "Post_Moral_Motivation_Comparison"
  ),
  Cronbach_Alpha = c(
    alpha_post_competence$total$raw_alpha,
    alpha_post_competence_comp$total$raw_alpha,
    alpha_post_motivation$total$raw_alpha,
    alpha_post_motivation_comp$total$raw_alpha
  )
)

# Display
kable(alpha_post_table, format = "html", digits = 3, row.names = FALSE) %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")

```

***

We can get participant age for the reporting.

```{r}
# Summarize age
age_table <- df %>%
  summarise(
    mean_age = mean(Age, na.rm = TRUE),
    sd_age = sd(Age, na.rm = TRUE),
    min_age = min(Age, na.rm = TRUE),
    max_age = max(Age, na.rm = TRUE)
  )

kable(age_table, format = "html",
            row.names = FALSE, digits = 2) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

***

And report gender.

```{r}
df$Gender <- as.factor(df$Gender)

kable(table(df$Gender), format = "html",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

***

# Manipulation Check

We start looking at our manipulation checks - is there an increase from baseline intelligence judgments to post-augmentation intelligence ratings for the intelligence condition, and does this depends on the type of Agent.

***

```{r, message=FALSE}
# subset the data so only people in intelligence condition and ratings of intelligence, in long format
df_long_manip_check <- df_long %>%
  filter(
    Outcome == "Intelligent"
  )

# set conditions as factors
df_long_manip_check$Agent <- as.factor(df_long_manip_check$Agent)
df_long_manip_check$Time <- as.factor(df_long_manip_check$Time)

# relevel factors
df_long_manip_check$Time <- 
  factor(df_long_manip_check$Time, 
         levels = c("Pre", "Post"))

df_long_manip_check$Agent <- 
  factor(df_long_manip_check$Agent, 
         levels = c("Human", "AI"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = df_long_manip_check,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
      TRUE ~ term  # fallback for unexpected terms
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the formatted results table
kable(formatted_table, format = "html", row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

```{r}
# Get descriptives
df_long_manip_check_table <- df_long_manip_check %>%
  group_by(Time, Agent) %>%
  summarise(
    Mean = round(mean(Rating, na.rm = TRUE), 2),
    SD = round(sd(Rating, na.rm = TRUE), 2),
    n = n(),
    .groups = "drop"
  )

# Display the formatted results table
kable(df_long_manip_check_table, format = "html", row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```


***

# Simple Effects by Condition

***

## Descriptives & Simple Effects

Now we will turn to look at different effects by condition. First, we will look at descriptives and the simple effects of augmentation (pre vs post), and we'll do this seperately for the different conditions by agent (human vs AI). 

***

### AI + Increased Intelligence

We'll look at the outcome variables as a function of time (pre vs post) looking only at participants who read about an *AI* being increased in intelligence, operationalised here as instrumental rationality.

```{r}
summary_table_AI <- df_long %>%
  filter(
    Agent == "AI",
    Outcome %in% c("Intelligent", "Intelligent_Comparison", 
                   "Moral_Competence", "Moral_Competence_Comparison", 
                   "Moral_Motivation", "Moral_Motivation_Comparison",
                   "Trust", "Danger")
  ) %>%
  mutate(
  Outcome = factor(Outcome, levels = c(
    "Intelligent", "Intelligent_Comparison", 
     "Moral_Competence", "Moral_Competence_Comparison", 
     "Moral_Motivation", "Moral_Motivation_Comparison",
     "Trust", "Danger"
  ))
) %>%
  group_by(Outcome, Time) %>%
  summarise(
    min = min(Rating, na.rm = TRUE),
    max = max(Rating, na.rm = TRUE),
    mean = round(mean(Rating, na.rm = TRUE), 2),
    sd = round(sd(Rating, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(
    Outcome = dplyr::recode(
      Outcome,
      "Intelligent" = "Intelligence",
      "Intelligent_Comparison" = "Intelligence (Compared to Average Person)",
      "Moral_Competence" = "Moral Competence",
      "Moral_Competence_Comparison" = "Moral Competence (Compared to Average Person)",
      "Moral_Motivation" = "Moral Motivation",
      "Moral_Motivation_Comparison" = "Moral Motivation (Compared to Average Person)")
  )

kable(summary_table_AI, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence (AI Only)</span>",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

***

Like in previous studies, we'll then follow this with paired-sample t-tests.

```{r, message=FALSE}
# Paired t-test
results <- t.test(df_AI$Post_Intelligent, df_AI$Pre_Intelligent, paired = TRUE)

# Rounding
t_val <- round(results$statistic, 2)
df_val <- as.integer(round(results$parameter))
p_val <- if (results$p.value < 0.001) "<0.001" else sprintf("%.3f", results$p.value)

# Effect size
effect_size <- cohens_d(df_AI$Post_Intelligent, df_AI$Pre_Intelligent, paired = TRUE)
d_val <- round(effect_size$Cohens_d, 2)

# Bayes Factor
bf_result <- ttestBF(x = df_AI$Post_Intelligent, y = df_AI$Pre_Intelligent, paired = TRUE)
bf_numeric <- as.numeric(exp(bf_result@bayesFactor$bf))
bf_exponent <- floor(log10(bf_numeric))
bf_mantissa <- bf_numeric / (10^bf_exponent)
bf_apa <- paste0(sprintf("%.2f", bf_mantissa), " × 10^", bf_exponent)

# Combine into a table
final_table <- data.frame(
  `_t_` = t_val,
  `df` = df_val,
  `_p_` = p_val,
  `Bayes Factor` = bf_numeric,
  `Bayes Factor APA` = bf_apa,
  `Cohen's _d_` = d_val,
  check.names = FALSE
)

# Display nicely
kable(final_table, format = "html", row.names = FALSE) %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")
```

***

To save time for other analyses we create a function to do produce the output for the variables which we then pull into a table.

```{r}
paired.t.test.bf <- function(var1, var2, data, labeldv = "DV") {

  # Clean the data: remove rows with NA or Inf
  clean_data <- data[complete.cases(data[[var1]], data[[var2]]) &
                       is.finite(data[[var1]]) &
                       is.finite(data[[var2]]), ]

  # Paired t-test
  results <- t.test(clean_data[[var2]], clean_data[[var1]], paired = TRUE)

  # Format t-test output
  t_val <- round(results$statistic, 2)
  df_val <- as.integer(round(results$parameter))
  p_val <- if (results$p.value < 0.001) "<0.001" else sprintf("%.3f", results$p.value)

  # Effect size (Cohen's d for paired samples)
  effect_size <- cohens_d(clean_data[[var2]], clean_data[[var1]], paired = TRUE)
  d_val <- round(effect_size$Cohens_d, 2)

  # Bayes Factor
  bf_result <- ttestBF(x = clean_data[[var2]], y = clean_data[[var1]], paired = TRUE)
  bf_numeric <- as.numeric(exp(bf_result@bayesFactor$bf))
  bf_exponent <- floor(log10(bf_numeric))
  bf_mantissa <- bf_numeric / (10^bf_exponent)
  bf_apa <- paste0(sprintf("%.2f", bf_mantissa), " × 10^", bf_exponent)

  # Combine into final table
  final_table <- data.frame(
    `_t_` = t_val,
    `df` = df_val,
    `_p_` = p_val,
    `Bayes Factor` = bf_numeric,
    `Bayes Factor APA` = bf_apa,
    `Cohen's _d_` = d_val,
    check.names = FALSE
  )

  return(final_table)
}
```

***

After creating the function we can check it shows the same results.

```{r, message=FALSE}
intelligence_AI <- paired.t.test.bf(data = df_AI, var1 = "Pre_Intelligent", var2 = "Post_Intelligent", labeldv = "Intelligence")
kable(intelligence_AI, format = "html",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

***

```{r, message=FALSE}
# Run the paired sample t-tests for each.
intelligence_AI <- paired.t.test.bf(data = df_AI,
                                    var1 = "Pre_Intelligent", 
                                    var2 = "Post_Intelligent", 
                                    labeldv = "Intelligence")

intelligence_comparison_AI <- paired.t.test.bf(data = df_AI, 
                                               var1 = "Pre_Intelligent_Comparison", 
                                               var2 = "Post_Intelligent_Comparison", 
                                               labeldv = "Intelligence (Comparison)")

moral_competence_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Competence", 
                                        var2 = "Post_Moral_Competence", 
                                        labeldv = "Moral Competence")

moral_competence_comparison_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Competence_Comparison", 
                                        var2 = "Post_Moral_Competence_Comparison", 
                                        labeldv = "Moral Competence (Comparison)")

moral_motivation_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Motivation", 
                                        var2 = "Post_Moral_Motivation", 
                                        labeldv = "Moral Motivation")

moral_motivation_comparison_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Motivation_Comparison", 
                                        var2 = "Post_Moral_Motivation_Comparison", 
                                        labeldv = "Moral Motivation (Comparison")

trust_AI <- paired.t.test.bf(data = df_AI, 
                             var1 = "Pre_Trust", 
                             var2 = "Post_Trust", 
                             labeldv = "Trust")

danger_AI <- paired.t.test.bf(data = df_AI, 
                              var1 = "Pre_Danger", 
                              var2 = "Post_Danger", 
                              labeldv = "Danger")

# Add a DV label column to each
intelligence_AI$DV <- "Intelligence"
intelligence_comparison_AI$DV <- "Intelligence (Compared to Average Person)"
moral_competence_AI$DV <- "Moral Competence"
moral_competence_comparison_AI$DV <- "Moral Competence (Compared to Average Person)"
moral_motivation_AI$DV <- "Moral Motivation"
moral_motivation_comparison_AI$DV <- "Moral Motivation (Compared to Average Person)"
trust_AI$DV <- "Trust"
danger_AI$DV <- "Danger"

# Combine into a single data frame
combined_results <- rbind(intelligence_AI,
                          intelligence_comparison_AI,
                          moral_competence_AI,
                          moral_competence_comparison_AI,
                          moral_motivation_AI,
                          moral_motivation_comparison_AI,
                          trust_AI,
                          danger_AI)

# Move DV column to the front
combined_results <- combined_results[, c("DV", setdiff(names(combined_results), "DV"))]

kable(combined_results,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence (AI Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

```

***

### Human + Increased Intelligence Conditions

We'll look at the outcome variables as a function of time (pre vs post) looking only at participants who read about an *human* being increased in intelligence, operationalised here as instrumental rationality.

```{r}
summary_table_human <- df_long %>%
  filter(
    Agent == "Human",
    Outcome %in% c("Intelligent", "Intelligent_Comparison", 
                   "Moral_Competence", "Moral_Competence_Comparison", 
                   "Moral_Motivation", "Moral_Motivation_Comparison",
                   "Trust", "Danger")
  ) %>%
  mutate(
  Outcome = factor(Outcome, levels = c(
    "Intelligent", "Intelligent_Comparison", 
     "Moral_Competence", "Moral_Competence_Comparison", 
     "Moral_Motivation", "Moral_Motivation_Comparison",
     "Trust", "Danger"
  ))
) %>%
  group_by(Outcome, Time) %>%
  summarise(
    min = min(Rating, na.rm = TRUE),
    max = max(Rating, na.rm = TRUE),
    mean = round(mean(Rating, na.rm = TRUE), 2),
    sd = round(sd(Rating, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(
    Outcome = dplyr::recode(
      Outcome,
      "Intelligent" = "Intelligence",
      "Intelligent_Comparison" = "Intelligence (Compared to Average Person)",
      "Moral_Competence" = "Moral Competence",
      "Moral_Competence_Comparison" = "Moral Competence (Compared to Average Person)",
      "Moral_Motivation" = "Moral Motivation",
      "Moral_Motivation_Comparison" = "Moral Motivation (Compared to Average Person)")
  )

kable(summary_table_human, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence (Human Only)</span>",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```


***

We'll then follow this with paired-sample t-tests.

```{r, message=FALSE}
# Run the paired sample t-tests for each.
intelligence_human <- paired.t.test.bf(data = df_human,
                                    var1 = "Pre_Intelligent", 
                                    var2 = "Post_Intelligent", 
                                    labeldv = "Intelligence")

intelligence_comparison_human <- paired.t.test.bf(data = df_human, 
                                               var1 = "Pre_Intelligent_Comparison", 
                                               var2 = "Post_Intelligent_Comparison", 
                                               labeldv = "Intelligence (Comparison)")

moral_competence_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Competence", 
                                        var2 = "Post_Moral_Competence", 
                                        labeldv = "Moral Competence")

moral_competence_comparison_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Competence_Comparison", 
                                        var2 = "Post_Moral_Competence_Comparison", 
                                        labeldv = "Moral Competence (Comparison)")

moral_motivation_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Motivation", 
                                        var2 = "Post_Moral_Motivation", 
                                        labeldv = "Moral Motivation")

moral_motivation_comparison_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Motivation_Comparison", 
                                        var2 = "Post_Moral_Motivation_Comparison", 
                                        labeldv = "Moral Motivation (Comparison")

trust_human <- paired.t.test.bf(data = df_human, 
                             var1 = "Pre_Trust", 
                             var2 = "Post_Trust", 
                             labeldv = "Trust")

danger_human <- paired.t.test.bf(data = df_human, 
                              var1 = "Pre_Danger", 
                              var2 = "Post_Danger", 
                              labeldv = "Danger")

# Add a DV label column to each
intelligence_human$DV <- "Intelligence"
intelligence_comparison_human$DV <- "Intelligence (Compared to Average Person)"
moral_competence_human$DV <- "Moral Competence"
moral_competence_comparison_human$DV <- "Moral Competence (Compared to Average Person)"
moral_motivation_human$DV <- "Moral Motivation"
moral_motivation_comparison_human$DV <- "Moral Motivation (Compared to Average Person)"
trust_human$DV <- "Trust"
danger_human$DV <- "Danger"

# Combine into a single data frame
combined_results <- rbind(intelligence_human,
                          intelligence_comparison_human,
                          moral_competence_human,
                          moral_competence_comparison_human,
                          moral_motivation_human,
                          moral_motivation_comparison_human,
                          trust_human,
                          danger_human)

# Move DV column to the front
combined_results <- combined_results[, c("DV", setdiff(names(combined_results), "DV"))]

kable(combined_results,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence (Human Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

```

***

# Mixed Models of Conditions

***

## Moral Competence

First, we ask whether the intelligence augmentation (pre vs post) predicts rated moral competence, and whether this is different for humans and AI. 

***

### General Ratings

```{r}
# Create long dataframe 
model_df <- df_long %>%
  filter(
    Outcome == "Moral_Competence" 
  )

# set conditions as factors
model_df$Agent <- as.factor(model_df$Agent)
model_df$Time <- as.factor(model_df$Time)

# relevel factors
model_df$Time <- 
  factor(model_df$Time, 
         levels = c("Pre", "Post"))

model_df$Agent <- 
  factor(model_df$Agent, 
         levels = c("Human", "AI"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = model_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
      TRUE ~ term  # fallback for unexpected terms
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Competence</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And we'll get some descriptives.

```{r}
# Get descriptives
model_df_table <- model_df %>%
  group_by(Time, Agent) %>%
  summarise(
    n = n(),
    Mean = round(mean(Rating, na.rm = TRUE), 2),
    SD = round(sd(Rating, na.rm = TRUE), 2),
    SE = SD / sqrt(n),
    Lower_CI = round(Mean - 1.96 * SE, 2),
    Upper_CI = round(Mean + 1.96 * SE, 2),
    .groups = "drop"
  )

# Display the formatted results table
kable(model_df_table, 
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Competence</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll look at simple effects of pre-post (within-subjects), for humans and AI separately. (We have done this above but repeat so it's in one place)

```{r}
moral_competence_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Competence", 
                                        var2 = "Post_Moral_Competence", 
                                        labeldv = "Moral Competence")

moral_competence_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Competence", 
                                        var2 = "Post_Moral_Competence", 
                                        labeldv = "Moral Competence")

kable(moral_competence_AI,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Competence (AI Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

kable(moral_competence_human,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Competence (Human Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```


***

```{r, fig.width=4, fig.height=4}
fill_colors <- c("Human" = "#E69F00", "AI" = "#56B4E9")
line_colors <- fill_colors

moral_competence_plot <- ggplot(model_df %>% filter(Outcome == "Moral_Competence"),
       aes(x = Time, y = Rating)) +

  # Jittered raw data points
  geom_jitter(
    aes(fill = Agent),
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.35, jitter.height = 0.35)
  ) +

  # Summary lines connecting group means only
  stat_summary(
    aes(group = Agent, color = Agent),
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    position = position_dodge(width = 0.7)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    aes(group = Agent, fill = Agent, color = Agent),
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    position = position_dodge(width = 0.7)
  ) +

  # Color scales
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Axis labels and limits
  labs(
    title = "Perceived Moral Competence\nAfter Intelligence Augmentation",
    x = "Time",
    y = "Moral Competence",
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(1, 7)) +
  scale_y_continuous(breaks = 1:7) +

  # Theme and legend styling
  theme_classic() +
  theme(
    text = element_text(size = 12),
    axis.title = element_text(size = 13),
    axis.text = element_text(size = 12),
    axis.title.y = element_text(margin = margin(r = 10)),
    axis.title.x = element_blank(),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10)),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.justification = "center",
    legend.box.margin = margin(t = -5),
    legend.key.height = unit(1.2, "lines"),
    legend.key.width = unit(1.2, "lines"),
    legend.text = element_text(size = 12)
  )

moral_competence_plot
```

***

### Comparison Question

```{r}
# Create long dataframe 
model_df <- df_long %>%
  filter(
    Outcome == "Moral_Competence_Comparison" 
  )

# set conditions as factors
model_df$Agent <- as.factor(model_df$Agent)
model_df$Time <- as.factor(model_df$Time)

# relevel factors
model_df$Time <- 
  factor(model_df$Time, 
         levels = c("Pre", "Post"))

model_df$Agent <- 
  factor(model_df$Agent, 
         levels = c("Human", "AI"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = model_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
      TRUE ~ term  # fallback for unexpected terms
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Competence (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And we'll get some descriptives.

```{r}
# Get descriptives
model_df_table <- model_df %>%
  group_by(Time, Agent) %>%
  summarise(
    n = n(),
    Mean = round(mean(Rating, na.rm = TRUE), 2),
    SD = round(sd(Rating, na.rm = TRUE), 2),
    SE = SD / sqrt(n),
    Lower_CI = round(Mean - 1.96 * SE, 2),
    Upper_CI = round(Mean + 1.96 * SE, 2),
    .groups = "drop"
  )

# Display the formatted results table
kable(model_df_table, 
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Competence (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll look at simple effects of pre-post (within-subjects), for humans and AI separately. (We have done this above but repeat so it's in one place)

```{r}
moral_competence_comparison_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Competence_Comparison", 
                                        var2 = "Post_Moral_Competence_Comparison", 
                                        labeldv = "Moral Competence (Comparison)")

moral_competence_comparison_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Competence_Comparison", 
                                        var2 = "Post_Moral_Competence_Comparison", 
                                        labeldv = "Moral Competence (Comparison)")

kable(moral_competence_comparison_AI,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Competence (Comparison) (AI Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

kable(moral_competence_comparison_human,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Competence (Comparison) (Human Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

***

```{r, fig.width=4, fig.height=4}
fill_colors <- c("Human" = "#E69F00", "AI" = "#56B4E9")
line_colors <- fill_colors

moral_competence_comparison_plot <- ggplot(model_df %>% filter(Outcome == "Moral_Competence_Comparison"),
       aes(x = Time, y = Rating)) +

  # Jittered raw data points
  geom_jitter(
    aes(fill = Agent),
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.35, jitter.height = 0.35)
  ) +
  
  # Reference line for comparison baseline
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray60", linewidth = 0.7) +

  # Summary lines connecting group means only
  stat_summary(
    aes(group = Agent, color = Agent),
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    position = position_dodge(width = 0.7)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    aes(group = Agent, fill = Agent, color = Agent),
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    position = position_dodge(width = 0.7)
  ) +

  # Color scales
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Axis labels and limits
  labs(
    title = "Perceived Moral Competence\nAfter Intelligence Augmentation",
    x = "Time",
    y = expression(atop("Moral Competence", "(Comparison to Average Person)")),
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(-3, 3)) +
  scale_y_continuous(breaks = -3:3) +

  # Theme and legend styling
  theme_classic() +
  theme(
    text = element_text(size = 12),
    axis.title = element_text(size = 13),
    axis.text = element_text(size = 12),
    axis.title.y = element_text(margin = margin(r = 10)),
    axis.title.x = element_text(margin = margin(t = 10)),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10)),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.justification = "center",
    legend.box.margin = margin(t = -5),
    legend.key.height = unit(1.2, "lines"),
    legend.key.width = unit(1.2, "lines"),
    legend.text = element_text(size = 12)
  )

moral_competence_comparison_plot
```

***

## Moral Motivation

Second, we ask whether increased intelligence predicts rated moral motivation, and whether this is different for humans and AI. 

***

### General Ratings

```{r}
# Create long dataframe 
model_df <- df_long %>%
  filter(
    Outcome == "Moral_Motivation" 
  )

# set conditions as factors
model_df$Agent <- as.factor(model_df$Agent)
model_df$Time <- as.factor(model_df$Time)

# relevel factors
model_df$Time <- 
  factor(model_df$Time, 
         levels = c("Pre", "Post"))

model_df$Agent <- 
  factor(model_df$Agent, 
         levels = c("Human", "AI"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = model_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
      TRUE ~ term  # fallback for unexpected terms
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Motivation</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And we'll get some descriptives.

```{r}
# Get descriptives
model_df_table <- model_df %>%
  group_by(Time, Agent) %>%
  summarise(
    n = n(),
    Mean = round(mean(Rating, na.rm = TRUE), 2),
    SD = round(sd(Rating, na.rm = TRUE), 2),
    SE = SD / sqrt(n),
    Lower_CI = round(Mean - 1.96 * SE, 2),
    Upper_CI = round(Mean + 1.96 * SE, 2),
    .groups = "drop"
  )

# Display the formatted results table
kable(model_df_table, 
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Motivation</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll look at simple effects of pre-post (within-subjects), for humans and AI separately. (We have done this above but repeat so it's in one place)

```{r}
moral_motivation_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Motivation", 
                                        var2 = "Post_Moral_Motivation", 
                                        labeldv = "Moral Motivation")

moral_motivation_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Motivation", 
                                        var2 = "Post_Moral_Motivation", 
                                        labeldv = "Moral Motivation")

kable(moral_motivation_AI,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Motivation (AI Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

kable(moral_motivation_human,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Motivation (Human Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

***

```{r, fig.width=4, fig.height=4}
fill_colors <- c("Human" = "#E69F00", "AI" = "#56B4E9")
line_colors <- fill_colors

moral_motivation_plot <- ggplot(model_df %>% filter(Outcome == "Moral_Motivation"),
       aes(x = Time, y = Rating)) +

  # Jittered raw data points
  geom_jitter(
    aes(fill = Agent),
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.35, jitter.height = 0.35)
  ) +

  # Summary lines connecting group means only
  stat_summary(
    aes(group = Agent, color = Agent),
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    position = position_dodge(width = 0.7)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    aes(group = Agent, fill = Agent, color = Agent),
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    position = position_dodge(width = 0.7)
  ) +

  # Color scales
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Axis labels and limits
  labs(
    title = "Perceived Moral Motivation\nAfter Intelligence Augmentation",
    x = "Time",
    y = "Moral Motivation",
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(1, 7)) +
  scale_y_continuous(breaks = 1:7) +

  # Theme and legend styling
  theme_classic() +
  theme(
    text = element_text(size = 12),
    axis.title = element_text(size = 13),
    axis.text = element_text(size = 12),
    axis.title.y = element_text(margin = margin(r = 10)),
    axis.title.x = element_blank(),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10)),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.justification = "center",
    legend.box.margin = margin(t = -5),
    legend.key.height = unit(1.2, "lines"),
    legend.key.width = unit(1.2, "lines"),
    legend.text = element_text(size = 12)
  )

moral_motivation_plot
```

***

### Comparison Question

```{r}
# Create long dataframe 
model_df <- df_long %>%
  filter(
    Outcome == "Moral_Motivation_Comparison" 
  )

# set conditions as factors
model_df$Agent <- as.factor(model_df$Agent)
model_df$Time <- as.factor(model_df$Time)

# relevel factors
model_df$Time <- 
  factor(model_df$Time, 
         levels = c("Pre", "Post"))

model_df$Agent <- 
  factor(model_df$Agent, 
         levels = c("Human", "AI"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = model_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
      TRUE ~ term  # fallback for unexpected terms
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Motivation (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And we'll get some descriptives.

```{r}
# Get descriptives
model_df_table <- model_df %>%
  group_by(Time, Agent) %>%
  summarise(
    n = n(),
    Mean = round(mean(Rating, na.rm = TRUE), 2),
    SD = round(sd(Rating, na.rm = TRUE), 2),
    SE = SD / sqrt(n),
    Lower_CI = round(Mean - 1.96 * SE, 2),
    Upper_CI = round(Mean + 1.96 * SE, 2),
    .groups = "drop"
  )

# Display the formatted results table
kable(model_df_table, 
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Perceived Moral Motivation (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll look at simple effects of pre-post (within-subjects), for humans and AI separately. (We have done this above but repeat so it's in one place)

```{r}
moral_motivation_comparison_AI <- paired.t.test.bf(data = df_AI, 
                                        var1 = "Pre_Moral_Motivation_Comparison", 
                                        var2 = "Post_Moral_Motivation_Comparison", 
                                        labeldv = "Moral Motivation (Comparison)")

moral_motivation_comparison_human <- paired.t.test.bf(data = df_human, 
                                        var1 = "Pre_Moral_Motivation_Comparison", 
                                        var2 = "Post_Moral_Motivation_Comparison", 
                                        labeldv = "Moral Motivation (Comparison)")

kable(moral_motivation_comparison_AI,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Motivation (Comparison) (AI Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

kable(moral_motivation_comparison_human,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Moral Motivation (Comparison) (Human Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

***

```{r, fig.width=4, fig.height=4}
fill_colors <- c("Human" = "#E69F00", "AI" = "#56B4E9")
line_colors <- fill_colors

moral_motivation_comparison_plot <- ggplot(model_df %>% filter(Outcome == "Moral_Motivation_Comparison"),
       aes(x = Time, y = Rating)) +

  # Jittered raw data points
  geom_jitter(
    aes(fill = Agent),
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.35, jitter.height = 0.35)
  ) +
  
  # Reference line for comparison baseline
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray60", linewidth = 0.7) +

  # Summary lines connecting group means only
  stat_summary(
    aes(group = Agent, color = Agent),
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    position = position_dodge(width = 0.7)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    aes(group = Agent, fill = Agent, color = Agent),
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    position = position_dodge(width = 0.7)
  ) +

  # Color scales
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Axis labels and limits
  labs(
    title = "Perceived Moral Motivation\nAfter Intelligence Augmentation",
    x = "Time",
    y = expression(atop("Moral Motivation", "(Comparison to Average Person)")),
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(-3, 3)) +
  scale_y_continuous(breaks = -3:3) +

  # Theme and legend styling
  theme_classic() +
  theme(
    text = element_text(size = 12),
    axis.title = element_text(size = 13),
    axis.text = element_text(size = 12),
    axis.title.y = element_text(margin = margin(r = 10)),
    axis.title.x = element_text(margin = margin(t = 10)),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10)),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.justification = "center",
    legend.box.margin = margin(t = -5),
    legend.key.height = unit(1.2, "lines"),
    legend.key.width = unit(1.2, "lines"),
    legend.text = element_text(size = 12)
  )

moral_motivation_comparison_plot
```

***

## Trust

Now we'll look at trust.

```{r}
# Create long dataframe 
model_df <- df_long %>%
  filter(
    Outcome == "Trust" 
  )

# set conditions as factors
model_df$Agent <- as.factor(model_df$Agent)
model_df$Time <- as.factor(model_df$Time)

# relevel factors
model_df$Time <- 
  factor(model_df$Time, 
         levels = c("Pre", "Post"))

model_df$Agent <- 
  factor(model_df$Agent, 
         levels = c("Human", "AI"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = model_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
      TRUE ~ term  # fallback for unexpected terms
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Trust</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll get descriptives.

```{r}
# Get descriptives
model_df_table <- model_df %>%
  group_by(Time, Agent) %>%
  summarise(
    n = n(),
    Mean = round(mean(Rating, na.rm = TRUE), 2),
    SD = round(sd(Rating, na.rm = TRUE), 2),
    SE = SD / sqrt(n),
    Lower_CI = round(Mean - 1.96 * SE, 2),
    Upper_CI = round(Mean + 1.96 * SE, 2),
    .groups = "drop"
  )

# Display the formatted results table
kable(model_df_table, 
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Trust</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll look at simple effects of pre-post (within-subjects), for humans and AI separately. (We have done this above but repeat so it's in one place)

```{r}
trust_AI <- paired.t.test.bf(data = df_AI, 
                             var1 = "Pre_Trust", 
                             var2 = "Post_Trust", 
                             labeldv = "Trust")

trust_human <- paired.t.test.bf(data = df_human, 
                             var1 = "Pre_Trust", 
                             var2 = "Post_Trust", 
                             labeldv = "Trust")

kable(trust_AI,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Trust (AI Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

kable(trust_human,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Trust (Human Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

***

```{r, fig.width=4, fig.height=4}
fill_colors <- c("Human" = "#E69F00", "AI" = "#56B4E9")
line_colors <- fill_colors

trust_plot <- ggplot(model_df %>% filter(Outcome == "Trust"),
       aes(x = Time, y = Rating)) +

  # Jittered raw data points
  geom_jitter(
    aes(fill = Agent),
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.35, jitter.height = 0.35)
  ) +

  # Summary lines connecting group means only
  stat_summary(
    aes(group = Agent, color = Agent),
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    position = position_dodge(width = 0.7)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    aes(group = Agent, fill = Agent, color = Agent),
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    position = position_dodge(width = 0.7)
  ) +

  # Color scales
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Axis labels and limits
  labs(
    title = "Perceived Trustworthiness\nAfter Intelligence Augmentation",
    x = "Time",
    y = "Trustworthiness",
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(1, 7)) +
  scale_y_continuous(breaks = 1:7) +

  # Theme and legend styling
  theme_classic() +
  theme(
    text = element_text(size = 12),
    axis.title = element_text(size = 13),
    axis.text = element_text(size = 12),
    axis.title.y = element_text(margin = margin(r = 10)),
    axis.title.x = element_blank(),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10)),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.justification = "center",
    legend.box.margin = margin(t = -5),
    legend.key.height = unit(1.2, "lines"),
    legend.key.width = unit(1.2, "lines"),
    legend.text = element_text(size = 12)
  )


# Define the subfolder name for saving
folder <- "figures"

# Create the folder if it doesn't already exist
if (!dir.exists(folder)) {
  dir.create(folder)
}

# Save the figure
ggsave((file.path(folder, "Study 6 Trust.png")), plot = trust_plot,
       width = 4, height = 4, units = "in", dpi = 300)

# Print figure in markdown
trust_plot
```


***

## Danger

Now we'll look at danger.

```{r}
# Create long dataframe 
model_df <- df_long %>%
  filter(
    Outcome == "Danger" 
  )

# set conditions as factors
model_df$Agent <- as.factor(model_df$Agent)
model_df$Time <- as.factor(model_df$Time)

# relevel factors
model_df$Time <- 
  factor(model_df$Time, 
         levels = c("Pre", "Post"))

model_df$Agent <- 
  factor(model_df$Agent, 
         levels = c("Human", "AI"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = model_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
      TRUE ~ term  # fallback for unexpected terms
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Trust</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll get descriptives.

```{r}
# Get descriptives
model_df_table <- model_df %>%
  group_by(Time, Agent) %>%
  summarise(
    n = n(),
    Mean = round(mean(Rating, na.rm = TRUE), 2),
    SD = round(sd(Rating, na.rm = TRUE), 2),
    SE = SD / sqrt(n),
    Lower_CI = round(Mean - 1.96 * SE, 2),
    Upper_CI = round(Mean + 1.96 * SE, 2),
    .groups = "drop"
  )

# Display the formatted results table
kable(model_df_table, 
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Danger</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We'll look at simple effects of pre-post (within-subjects), for humans and AI separately. (We have done this above but repeat so it's in one place)

```{r}
danger_AI <- paired.t.test.bf(data = df_AI, 
                             var1 = "Pre_Danger", 
                             var2 = "Post_Danger", 
                             labeldv = "Danger")

danger_human <- paired.t.test.bf(data = df_human, 
                             var1 = "Pre_Danger", 
                             var2 = "Post_Danger", 
                             labeldv = "Danger")

kable(danger_AI,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Danger (AI Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")

kable(danger_human,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Intelligence on Danger (Human Only)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

***

```{r, fig.width=4, fig.height=4}
fill_colors <- c("Human" = "#E69F00", "AI" = "#56B4E9")
line_colors <- fill_colors

danger_plot <- ggplot(model_df %>% filter(Outcome == "Danger"),
       aes(x = Time, y = Rating)) +

  # Jittered raw data points
  geom_jitter(
    aes(fill = Agent),
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    position = position_jitterdodge(dodge.width = 0.7, jitter.width = 0.35, jitter.height = 0.35)
  ) +

  # Summary lines connecting group means only
  stat_summary(
    aes(group = Agent, color = Agent),
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    position = position_dodge(width = 0.7)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    aes(group = Agent, fill = Agent, color = Agent),
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    position = position_dodge(width = 0.7)
  ) +

  # Color scales
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Axis labels and limits
  labs(
    title = "Perceived Danger\nAfter Intelligence Augmentation",
    x = "Time",
    y = "Danger",
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(1, 7)) +
  scale_y_continuous(breaks = 1:7) +

  # Theme and legend styling
  theme_classic() +
  theme(
    text = element_text(size = 12),
    axis.title = element_text(size = 13),
    axis.text = element_text(size = 12),
    axis.title.y = element_text(margin = margin(r = 10)),
    axis.title.x = element_blank(),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10)),
    legend.position = "bottom",
    legend.direction = "horizontal",
    legend.justification = "center",
    legend.box.margin = margin(t = -5),
    legend.key.height = unit(1.2, "lines"),
    legend.key.width = unit(1.2, "lines"),
    legend.text = element_text(size = 12)
  )


# Define the subfolder name for saving
folder <- "figures"

# Create the folder if it doesn't already exist
if (!dir.exists(folder)) {
  dir.create(folder)
}

# Save the figure
ggsave((file.path(folder, "Study 6 Danger.png")), plot = danger_plot,
       width = 4, height = 4, units = "in", dpi = 300)

# Print figure in markdown
danger_plot
```

```{r, fig.height=4, fig.width=7}
# Remove legend from the first plot
trust_plot_clean <- trust_plot +
  theme(legend.position = "none")

# Combine
combined_trust_danger_plot <- trust_plot_clean + danger_plot +
  plot_layout(ncol = 2, guides = "collect") &
  theme(legend.position = "bottom")

# Define the subfolder name
folder <- "figures"

# Create the folder if it doesn't already exist
if (!dir.exists(folder)) {
  dir.create(folder)
}

# Save both versions
ggsave((file.path(folder, "Study 6 Trust and Danger.png")), plot = combined_trust_danger_plot,
       width = 7, height = 4, units = "in", dpi = 300)

combined_trust_danger_plot
```

***

# Mixed Model with Moral Motivation and Competence

We have measured both moral motivation and moral competence, and we can plot both side-by-side here below. Then, as an exploratory question we'll ask whether intelligence augmentation changes moral competence more than moral motivation, or vice versa — and whether  differs by agent?.

***

## General Ratings

```{r, fig.height=4, fig.width=7}
# Remove legend from the first plot
moral_competence_plot_clean <- moral_competence_plot +
  theme(legend.position = "none")

# Combine
combined_morality_plot <- moral_competence_plot_clean + moral_motivation_plot +
  plot_layout(ncol = 2, guides = "collect") &
  theme(legend.position = "bottom")

# Define the subfolder name
folder <- "figures"

# Create the folder if it doesn't already exist
if (!dir.exists(folder)) {
  dir.create(folder)
}

# Save both versions
ggsave((file.path(folder, "Study 6 Moral Competence and Motivation.png")), plot = combined_morality_plot,
       width = 7, height = 4, units = "in", dpi = 300)

combined_morality_plot

```

```{r}
# Filter only moral motivation and moral competence variables
df_subset <- df_long %>%
  filter(Outcome %in% c("Moral_Competence", "Moral_Motivation"))


# Make factors
df_subset <- df_subset %>%
  mutate(
    Outcome = factor(Outcome),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI"))
  )

model_outcome_interaction <- lmer(
  Rating ~ Time * Agent * Outcome + (1 | Participant),
  data = df_subset,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model_outcome_interaction, effects = "fixed") %>%
  mutate(
    Term = case_when(
      # Intercept
      term == "(Intercept)" ~ "Intercept",

      # Main effects
      term == "OutcomeMoral_Motivation" ~ "Moral Motivation vs Competence [Motivation]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost" ~ "Time [Post]",

      # Two-way interactions
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TimePost:OutcomeMoral_Motivation" ~ "Time × Moral Outcome",
      term == "AgentAI:OutcomeMoral_Motivation" ~ "Agent × Moral Outcome",

      # Three-way interactions
      term == "TimePost:AgentAI:OutcomeMoral_Motivation" ~ "Time × Agent × Moral Outcome",

      # Fallback
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

kable(formatted_table,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>The interactive effect of augmentation, agent type, and trait type (moral motivation vs moral competence) on expected change in morality</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

```{r}
emm_df <- emmeans(model_outcome_interaction, ~ Time * Agent * Outcome) %>%
  as.data.frame() %>%
  mutate(
    emmean = round(emmean, 2),
    SE = round(SE, 3),
    lower.CL = round(lower.CL, 2),
    upper.CL = round(upper.CL, 2)
  ) %>%
  rename(
    `Estimated Mean` = emmean,
    `SE` = SE,
    `Lower 95% CI` = lower.CL,
    `Upper 95% CI` = upper.CL
  ) %>%
  select(Outcome, Agent, Time, `Estimated Mean`, SE, `Lower 95% CI`, `Upper 95% CI`)

kable(emm_df,
      format = "html",
      caption = "<strong>Estimated Marginal Means of Moral Ratings by Time and Agent</strong>",
      align = "lccc") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")

```
```{r}

# Get estimated marginal means
emm <- emmeans(model_outcome_interaction, ~ Time * Agent * Outcome)

# Compare Time × Agent interactions across Outcome (contrasts between 2-way interactions, by Outcome)
model_contrasts <- contrast(emm, interaction = "pairwise", by = "Outcome")

# Convert the contrast object to a data frame and format
contrast_table <- as.data.frame(model_contrasts) %>%
  mutate(
    Estimate = round(estimate, 2),
    SE = round(SE, 3),
    t = round(t.ratio, 2),
    p = ifelse(p.value < .001, "< .001", paste0("= ", sprintf("%.3f", p.value)))
  ) %>%
  select(
    Outcome,
    `Time Comparison` = Time_pairwise,
    `Agent Comparison` = Agent_pairwise,
    Estimate, SE, t, p
  )
    
kable(contrast_table,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Contrasts",
      digits = 2,
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

***

## Comparison Question

```{r, fig.height=4, fig.width=8}
# Remove legend from the first plot
moral_competence_comparison_plot_clean <- moral_competence_comparison_plot +
  theme(legend.position = "none")

# Combine
combined_morality_comparison_plot <- moral_competence_comparison_plot_clean + moral_motivation_comparison_plot +
  plot_layout(ncol = 2, guides = "collect") &
  theme(legend.position = "bottom")

# Define the subfolder name
folder <- "figures"

# Create the folder if it doesn't already exist
if (!dir.exists(folder)) {
  dir.create(folder)
}

# Save both versions
ggsave((file.path(folder, "Study 6 Moral Competence and Motivation Comparison.png")), plot = combined_morality_comparison_plot,
       width = 8, height = 4, units = "in", dpi = 300)

combined_morality_comparison_plot

```

***

```{r}
# Filter only moral motivation and moral competence variables
df_subset <- df_long %>%
  filter(Outcome %in% c("Moral_Competence_Comparison", "Moral_Motivation_Comparison"))


# Make factors
df_subset <- df_subset %>%
  mutate(
    Outcome = factor(Outcome),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI"))
  )

model_outcome_interaction <- lmer(
  Rating ~ Time * Agent * Outcome + (1 | Participant),
  data = df_subset,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model_outcome_interaction, effects = "fixed") %>%
  mutate(
    Term = case_when(
      # Intercept
      term == "(Intercept)" ~ "Intercept",

      # Main effects
      term == "OutcomeMoral_Motivation_Comparison" ~ "Moral Motivation vs Competence (Comparison) [Motivation]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost" ~ "Time [Post]",

      # Two-way interactions
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TimePost:OutcomeMoral_Motivation_Comparison" ~ "Time × Moral Outcome (Comparison)",
      term == "AgentAI:OutcomeMoral_Motivation_Comparison" ~ "Agent × Moral Outcome (Comparison)",

      # Three-way interactions
      term == "TimePost:AgentAI:OutcomeMoral_Motivation_Comparison" ~ "Time × Agent × Moral Outcome (Comparison)",

      # Fallback
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

kable(formatted_table,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>The interactive effect of augmentation, agent type, and trait type (moral motivation vs moral competence) on expected change in morality (comparison question)</span>",
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

```{r}
emm_df <- emmeans(model_outcome_interaction, ~ Time * Agent * Outcome) %>%
  as.data.frame() %>%
  mutate(
    emmean = round(emmean, 2),
    SE = round(SE, 3),
    lower.CL = round(lower.CL, 2),
    upper.CL = round(upper.CL, 2)
  ) %>%
  rename(
    `Estimated Mean` = emmean,
    `SE` = SE,
    `Lower 95% CI` = lower.CL,
    `Upper 95% CI` = upper.CL
  ) %>%
  select(Outcome, Agent, Time, `Estimated Mean`, SE, `Lower 95% CI`, `Upper 95% CI`)

kable(emm_df,
      format = "html",
      caption = "<strong>Estimated Marginal Means of Moral Ratings (Comparison) by Time and Agent</strong>",
      align = "lccc") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")

```

```{r}

# Get estimated marginal means
emm <- emmeans(model_outcome_interaction, ~ Time * Agent * Outcome)

# Compare Time × Agent interactions across Outcome (contrasts between 2-way interactions, by Outcome)
model_contrasts <- contrast(emm, interaction = "pairwise", by = "Outcome")

# Convert the contrast object to a data frame and format
contrast_table <- as.data.frame(model_contrasts) %>%
  mutate(
    Estimate = round(estimate, 2),
    SE = round(SE, 3),
    t = round(t.ratio, 2),
    p = ifelse(p.value < .001, "< .001", paste0("= ", sprintf("%.3f", p.value)))
  ) %>%
  select(
    Outcome,
    `Time Comparison` = Time_pairwise,
    `Agent Comparison` = Agent_pairwise,
    Estimate, SE, t, p
  )
    
kable(contrast_table,       
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Contrasts",
      digits = 2,
      row.names = FALSE) %>%
      kable_styling(bootstrap_options = "striped",full_width = FALSE, position = "left")
```

***

# Predictors of Trust and Danger

As an exploratory question, we can ask whether trust is shaped by ratings of moral competence and moral motivation, and whether these relationships depend on Agent or change after augmentation.

***

## Trust

```{r}
# Reshape data
model_df <- df_long %>%
  filter(Outcome %in% c("Moral_Competence", "Moral_Motivation", "Trust"))  %>%
  pivot_wider(names_from = Outcome, values_from = Rating)


# Centre the predictors
model_df <- model_df %>%
  mutate(
    Moral_Competence_c = scale(Moral_Competence, center = TRUE, scale = FALSE) %>% as.numeric(),
    Moral_Motivation_c = scale(Moral_Motivation, center = TRUE, scale = FALSE) %>% as.numeric()
  )

model_df$Agent <- factor(model_df$Agent, levels = c("Human", "AI"))
model_df$Time <- factor(model_df$Time, levels = c("Pre", "Post"))

# Do the model
model <- lmer(
  Trust ~ Agent * Time +
          Moral_Competence_c * Agent * Time +
          Moral_Motivation_c * Agent * Time +
          (1 | Participant),
  data = model_df
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      # Intercept
      term == "(Intercept)" ~ "Intercept",

      # Main effects
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost" ~ "Time [Post]",
      term == "Moral_Competence_c" ~ "Moral Competence (Centered)",
      term == "Moral_Motivation_c" ~ "Moral Motivation (Centered)",

      # Two-way interactions
      term == "AgentAI:TimePost" ~ "Agent × Time",
      term == "AgentAI:Moral_Competence_c" ~ "Agent × Moral Competence",
      term == "TimePost:Moral_Competence_c" ~ "Time × Moral Competence",
      term == "AgentAI:Moral_Motivation_c" ~ "Agent × Moral Motivation",
      term == "TimePost:Moral_Motivation_c" ~ "Time × Moral Motivation",

      # Three-way interactions
      term == "AgentAI:TimePost:Moral_Competence_c" ~ "Agent × Time × Moral Competence",
      term == "AgentAI:TimePost:Moral_Motivation_c" ~ "Agent × Time × Moral Motivation",

      # Fallback
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  # Reorder terms
  mutate(order = factor(Term, levels = c(
    # Intercept
    "Intercept",

    # Main effects
    "Moral Competence (Centered)", "Moral Motivation (Centered)", "Agent [AI]", "Time [Post]",

    # 2-way interactions
    "Agent × Time",
    "Agent × Moral Competence", "Time × Moral Competence",
    "Agent × Moral Motivation", "Time × Moral Motivation",

    # 3-way interactions
    "Agent × Time × Moral Competence",
    "Agent × Time × Moral Motivation"
  ))) %>%
  arrange(order) %>%
  select(Term, Estimate, SE, df, t, p)


# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Interactive Effects of Moral Competence and Moral Motivation on Trust</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

## Danger

```{r}
# Reshape data
model_df <- df_long %>%
  filter(Outcome %in% c("Moral_Competence", "Moral_Motivation", "Danger"))  %>%
  pivot_wider(names_from = Outcome, values_from = Rating)


# Centre the predictors
model_df <- model_df %>%
  mutate(
    Moral_Competence_c = scale(Moral_Competence, center = TRUE, scale = FALSE) %>% as.numeric(),
    Moral_Motivation_c = scale(Moral_Motivation, center = TRUE, scale = FALSE) %>% as.numeric()
  )

model_df$Agent <- factor(model_df$Agent, levels = c("Human", "AI"))
model_df$Time <- factor(model_df$Time, levels = c("Pre", "Post"))

# Do the model
model <- lmer(
  Danger ~ Agent * Time +
          Moral_Competence_c * Agent * Time +
          Moral_Motivation_c * Agent * Time +
          (1 | Participant),
  data = model_df
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      # Intercept
      term == "(Intercept)" ~ "Intercept",

      # Main effects
      term == "AgentAI" ~ "Agent [AI]",
      term == "TimePost" ~ "Time [Post]",
      term == "Moral_Competence_c" ~ "Moral Competence (Centered)",
      term == "Moral_Motivation_c" ~ "Moral Motivation (Centered)",

      # Two-way interactions
      term == "AgentAI:TimePost" ~ "Agent × Time",
      term == "AgentAI:Moral_Competence_c" ~ "Agent × Moral Competence",
      term == "TimePost:Moral_Competence_c" ~ "Time × Moral Competence",
      term == "AgentAI:Moral_Motivation_c" ~ "Agent × Moral Motivation",
      term == "TimePost:Moral_Motivation_c" ~ "Time × Moral Motivation",

      # Three-way interactions
      term == "AgentAI:TimePost:Moral_Competence_c" ~ "Agent × Time × Moral Competence",
      term == "AgentAI:TimePost:Moral_Motivation_c" ~ "Agent × Time × Moral Motivation",

      # Fallback
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  # Reorder terms
  mutate(order = factor(Term, levels = c(
    # Intercept
    "Intercept",

    # Main effects
    "Moral Competence (Centered)", "Moral Motivation (Centered)", "Agent [AI]", "Time [Post]",

    # 2-way interactions
    "Agent × Time",
    "Agent × Moral Competence", "Time × Moral Competence",
    "Agent × Moral Motivation", "Time × Moral Motivation",

    # 3-way interactions
    "Agent × Time × Moral Competence",
    "Agent × Time × Moral Motivation"
  ))) %>%
  arrange(order) %>%
  select(Term, Estimate, SE, df, t, p)


# Display the formatted results table
kable(formatted_table,      
      format = "html", 
      caption = "<span style='color:black; font-weight:bold;
      '>Interactive Effects of Moral Competence and Moral Motivation on Perceived Danger</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

# Correlations

We'll look at the correlation between participants ratings of intelligence and morality. We can use a quick custom function to make this easy.

```{r}
# Individual correlation 
jim.correlation <- function(DV_A, DV_B, Item) {
  
test <- cor.test(DV_A, DV_B, method = "pearson")

correlation <- test$estimate
correlation <- round(correlation, digits = 2)
df_val <- sprintf("%.0f", test$parameter)  # APA style: no decimals for df

p_raw <- test$p.value
p_formatted <- p_raw <- if (test$p.value < 0.001) "<0.001" else sprintf("%.3f", test$p.value)

combined <- data.frame(
    df = df_val,
    r = correlation,
    p = p_formatted,
    row.names = Item,
    check.names = FALSE
  )

  return(combined)
}

```

***

## Prior to Augmentation.

We first look at the correlation between baseline judgments of intelligence, moral competence, and moral motivation prior to the augmentation. This is overall, across AI and human.

```{r}
pre_intelligence_moral_competence_corr <- jim.correlation(DV_A = df$Pre_Intelligent, 
                                              DV_B = df$Pre_Moral_Competence,
                                              Item = "Intelligence + Moral Competence (Pre)")

pre_intelligence_moral_motivation_corr <- jim.correlation(DV_A = df$Pre_Intelligent, 
                                              DV_B = df$Pre_Moral_Motivation,
                                              Item = "Intelligence + Moral Motivation (Pre)")

# Bind together
correlation_summary <- bind_rows(
  pre_intelligence_moral_competence_corr,
  pre_intelligence_moral_motivation_corr
)

kable(correlation_summary, format = "html",
            row.names = TRUE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

We'll then break down for human and AI seperately.

```{r}
pre_intelligence_moral_competence_AI_corr <- jim.correlation(DV_A = df_AI$Pre_Intelligent, 
                                              DV_B = df_AI$Pre_Moral_Competence,
                                              Item = "Intelligence + Moral Competence (Pre + AI Only)")

pre_intelligence_moral_competence_human_corr <- jim.correlation(DV_A = df_human$Pre_Intelligent, 
                                              DV_B = df_human$Pre_Moral_Competence,
                                              Item = "Intelligence + Moral Competence (Pre + Human Only)")

pre_intelligence_moral_motivation_AI_corr <- jim.correlation(DV_A = df_AI$Pre_Intelligent, 
                                              DV_B = df_AI$Pre_Moral_Motivation,
                                              Item = "Intelligence + Moral Motivation (Pre + AI Only)")

pre_intelligence_moral_motivation_human_corr <- jim.correlation(DV_A = df_human$Pre_Intelligent, 
                                              DV_B = df_human$Pre_Moral_Motivation,
                                              Item = "Intelligence + Moral Motivation (Pre + Human Only)")


# Bind together
correlation_summary <- bind_rows(
  pre_intelligence_moral_competence_AI_corr,
  pre_intelligence_moral_competence_human_corr,
  pre_intelligence_moral_motivation_AI_corr,
  pre_intelligence_moral_motivation_human_corr
)

kable(correlation_summary, format = "html",
            row.names = TRUE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

***


## After Augmentation.

We then look at the correlation between post-augmentation judgments of intelligence, moral competence, and moral motivation prior to the augmentation. This is overall, across AI and human.

```{r}
post_intelligence_moral_competence_corr <- jim.correlation(DV_A = df$Post_Intelligent, 
                                              DV_B = df$Post_Moral_Competence,
                                              Item = "Intelligence + Moral Competence (Post)")

post_intelligence_moral_motivation_corr <- jim.correlation(DV_A = df$Post_Intelligent, 
                                              DV_B = df$Post_Moral_Motivation,
                                              Item = "Intelligence + Moral Motivation (Post)")

# Bind together
correlation_summary <- bind_rows(
  post_intelligence_moral_competence_corr,
  post_intelligence_moral_motivation_corr
)

kable(correlation_summary, format = "html",
            row.names = TRUE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

We'll then break down for human and AI seperately.

```{r}
post_intelligence_moral_competence_AI_corr <- jim.correlation(DV_A = df_AI$Post_Intelligent, 
                                              DV_B = df_AI$Post_Moral_Competence,
                                              Item = "Intelligence + Moral Competence (Post + AI Only)")

post_intelligence_moral_competence_human_corr <- jim.correlation(DV_A = df_human$Post_Intelligent, 
                                              DV_B = df_human$Post_Moral_Competence,
                                              Item = "Intelligence + Moral Competence (Post + Human Only)")

post_intelligence_moral_motivation_AI_corr <- jim.correlation(DV_A = df_AI$Post_Intelligent, 
                                              DV_B = df_AI$Post_Moral_Motivation,
                                              Item = "Intelligence + Moral Motivation (Post + AI Only)")

post_intelligence_moral_motivation_human_corr <- jim.correlation(DV_A = df_human$Post_Intelligent, 
                                              DV_B = df_human$Post_Moral_Motivation,
                                              Item = "Intelligence + Moral Motivation (Post + Human Only)")


# Bind together
correlation_summary <- bind_rows(
  post_intelligence_moral_competence_AI_corr,
  post_intelligence_moral_competence_human_corr,
  post_intelligence_moral_motivation_AI_corr,
  post_intelligence_moral_motivation_human_corr
)

kable(correlation_summary, format = "html",
            row.names = TRUE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

***

# Familiarity

Just as an exploratory test, we can look at whether familiarity influences these results. 

```{r, fig.width=4, fig.height=4}
ggplot(df, aes(x = Familiarity)) +
  geom_histogram(binwidth = 1, fill = "#0072B2", color = "white") +
  scale_x_continuous(breaks = 0:6) +
  labs(
    title = "Distribution of Familiarity Ratings",
    x = "Familiarity",
    y = "Number of Participants"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5)
  )
```

***

## Intelligence 

We'll first look at the effect of self-reported familiarity with AI with pre-post judgments and agent type on ratings of moral competence, on the general measure first then the question asking in comparison to average person.

```{r}
# Prepare long-format data and center Familiarity
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Intelligent, Post_Intelligent),
    names_to = "Time",
    values_to = "Intelligent"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent = "Pre",
                  Post_Intelligent = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Intelligent ~ Familiarity_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Agent [AI]",
    "Familiarity × Time",
    "Familiarity × Agent",
    "Time × Agent",
    "Familiarity × Time × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with Familiarity on Ratings of Intelligence</span>",
      row.names = FALSE
      ) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And for the comparison variable.

```{r}
# Prepare long-format data and center Familiarity
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Intelligent_Comparison, Post_Intelligent_Comparison),
    names_to = "Time",
    values_to = "Intelligent_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent_Comparison = "Pre",
                  Post_Intelligent_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Intelligent_Comparison ~ Familiarity_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Agent [AI]",
    "Familiarity × Time",
    "Familiarity × Agent",
    "Time × Agent",
    "Familiarity × Time × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with Familiarity on Ratings of Intelligence (Comparison)</span>",
      row.names = FALSE
      ) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

****

## Moral Competence 

We'll look at the effect of self-reported familiarity with AI with pre-post judgments and agent type on ratings of moral competence, on the general measure first then the question asking in comparison to average person.

```{r}
# Prepare long-format data and center Familiarity
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Competence, Post_Moral_Competence),
    names_to = "Time",
    values_to = "Moral_Competence"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Competence = "Pre",
                  Post_Moral_Competence = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Competence ~ Familiarity_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Agent [AI]",
    "Familiarity × Time",
    "Familiarity × Agent",
    "Time × Agent",
    "Familiarity × Time × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with Familiarity on Ratings of Moral Competence</span>",
      row.names = FALSE
      ) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And for the comparison variable.

```{r}
# Prepare long-format data and center Familiarity
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Competence_Comparison, Post_Moral_Competence_Comparison),
    names_to = "Time",
    values_to = "Moral_Competence_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Competence_Comparison = "Pre",
                  Post_Moral_Competence_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Competence_Comparison ~ Familiarity_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Agent [AI]",
    "Familiarity × Time",
    "Familiarity × Agent",
    "Time × Agent",
    "Familiarity × Time × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with Familiarity on Ratings of Moral Competence (Comparison)</span>",
      row.names = FALSE
      ) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

## Moral Motivation 

We'll look at the effect of self-reported familiarity with AI with pre-post judgments and agent type on ratings of moral competence, on the general measure first then the question asking in comparison to average person.

```{r}
# Prepare long-format data and center Familiarity
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Motivation, Post_Moral_Motivation),
    names_to = "Time",
    values_to = "Moral_Motivation"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Motivation = "Pre",
                  Post_Moral_Motivation = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Motivation ~ Familiarity_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Agent [AI]",
    "Familiarity × Time",
    "Familiarity × Agent",
    "Time × Agent",
    "Familiarity × Time × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with Familiarity on Ratings of Moral Motivation</span>",
      row.names = FALSE
      ) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And for the comparison variable.

```{r}
# Prepare long-format data and center Familiarity
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Motivation_Comparison, Post_Moral_Motivation_Comparison),
    names_to = "Time",
    values_to = "Moral_Motivation_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Motivation_Comparison = "Pre",
                  Post_Moral_Motivation_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Motivation_Comparison ~ Familiarity_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Agent [AI]",
    "Familiarity × Time",
    "Familiarity × Agent",
    "Time × Agent",
    "Familiarity × Time × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with Familiarity on Ratings of Moral Motivation (Comparison)</span>",
      row.names = FALSE
      ) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

# AI Accuracy (PEW)

Now we look at the questions where participants were given different questions about AI taken from PEW, to get a more "objective" measure of AI knowledge to complement the self-report familiarity measure. 

***

We can first just look at the distributions.

```{r}
pew_summary <- df %>%
  distinct(Participant, Pew_Correct) %>%  # Ensure one row per participant
  count(Pew_Correct) %>%
  mutate(
    Percent = round(100 * n / sum(n), 1)
  )

# Show summary
kable(pew_summary, format = "html", col.names = c("Pew_Correct Score", "Count", "Percent")) %>%
  kable_styling(
    bootstrap_options = c("striped"),
    full_width = FALSE,
    position = "left"
  )
```

***

```{r, fig.width=4, fig.height=4}
ggplot(df, aes(x = Pew_Correct)) +
  geom_histogram(binwidth = 1, fill = "#0072B2", color = "white") +
  scale_x_continuous(breaks = 0:6) +
  labs(
    title = "Distribution of Pew AI Knowledge Scores",
    x = "Pew_Correct Score (0–6)",
    y = "Number of Participants"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5)
  )
```

***

We can see that actually the majority of our participants are getting most of them right, and so while we can run the analyses below it can lead to singularity issues when we're centering and doing the analyses. We'll can do an exploratory analysis looking at how these scores relate to our effects for intelligence and morality, but it's not be as informative as we'd like.

For our key variables we will look at the effect of number of correct answers on the PEW AI questions with pre-post judgments and agent type on ratings, on the general measure first then the question asking in comparison to average person.

***

## Intelligence

***

We'll first look at the effect of number of correct answers on the PEW AI questions with pre-post judgments and agent type on ratings of intelligence, on the general measure first then the question asking in comparison to average person.

***

First we look at the general ratings.

```{r}
# Prepare long-format data and center Pew_Correct
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Intelligent, Post_Intelligent),
    names_to = "Time",
    values_to = "Intelligent"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent = "Pre",
                  Post_Intelligent = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Intelligent ~ Pew_Correct_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table 
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Trait × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the table
kable(formatted_table, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with PEW AI Knowledge on Ratings of Intelligence</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

****

And then for the comparison question.

```{r}
# Prepare long-format data and center Pew_Correct
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Intelligent_Comparison, Post_Intelligent_Comparison),
    names_to = "Time",
    values_to = "Intelligent_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent_Comparison = "Pre",
                  Post_Intelligent_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Intelligent_Comparison ~ Pew_Correct_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table 
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Trait × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the table
kable(formatted_table, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with PEW AI Knowledge on Ratings of Intelligence (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

## Moral Competence

***

We'll then look at the effect of number of correct answers on the PEW AI questions with pre-post judgments and agent type on ratings of moral competence on the general measure.


```{r}
# Prepare long-format data and center Pew_Correct
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Competence, Post_Moral_Competence),
    names_to = "Time",
    values_to = "Moral_Competence"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Competence = "Pre",
                  Post_Moral_Competence = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Competence ~ Pew_Correct_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table 
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Trait × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the table
kable(formatted_table, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with PEW AI Knowledge on Ratings of Moral Competence</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

****

And then for the comparison question.

```{r}
# Prepare long-format data and center Pew_Correct
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Competence_Comparison, Post_Moral_Competence_Comparison),
    names_to = "Time",
    values_to = "Moral_Competence_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Competence_Comparison = "Pre",
                  Post_Moral_Competence_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Competence_Comparison ~ Pew_Correct_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table 
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Trait × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the table
kable(formatted_table, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with PEW AI Knowledge on Ratings of Moral Competence (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

## Moral Motivation

***

We'll then look at the effect of number of correct answers on the PEW AI questions with pre-post judgments and agent type on ratings of moral motivation on the general measure.

```{r}
# Prepare long-format data and center Pew_Correct
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Motivation, Post_Moral_Motivation),
    names_to = "Time",
    values_to = "Moral_Motivation"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Motivation = "Pre",
                  Post_Moral_Motivation = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Motivation ~ Pew_Correct_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table 
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Trait × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the table
kable(formatted_table, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with PEW AI Knowledge on Ratings of Moral Motivation</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

****

And then for the comparison question.

```{r}
# Prepare long-format data and center Pew_Correct
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Motivation_Comparison, Post_Moral_Motivation_Comparison),
    names_to = "Time",
    values_to = "Moral_Motivation_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Motivation_Comparison = "Pre",
                  Post_Moral_Motivation_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
model <- lmer(
  Moral_Motivation_Comparison ~ Pew_Correct_c * Time * Agent + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Format the table 
formatted_table <- broom.mixed::tidy(model, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Trait × Agent",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

# Display the table
kable(formatted_table, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model with PEW AI Knowledge on Ratings of Moral Motivation (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```
