---
title: "Orthogonality Study 4"
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 Study 4 we used a mixed design in which we used the within-subjects augmentation paradigm to get pre-post judgments, with a between-subjects condition of agent type (AI vs human) and trait that was augmented (intelligence vs morality). Participants first saw a vignette about an AI (vs a Human) that was described as very low in intelligence (vs morality), and indicated how intelligent, moral, safe and trustworthy they believe the target would be. Afterwards, participants read a second vignette describing how this hypothetical AI (through advancements in machine learning) or human (through a medical breakthrough) either led to a drastic increase in intelligence or morality. 

***

# 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_4_Data.csv", header=TRUE, stringsAsFactors=FALSE)

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

# relevel factors
df$Trait <- 
  factor(df$Trait, 
         levels = c("Increased Morality", "Increased Intelligence"))
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, Trait) %>%
  arrange(Agent, Trait)


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")

# Second we break down just whether it is a morality or intelligence condition.
df_morality <- df %>% filter(Trait == "Increased Morality")
df_intelligence <- df %>% filter(Trait == "Increased Intelligence")

# Third we break down by both agent AND trait
df_intelligence_AI <- df %>% filter(Trait == "Increased Intelligence" & Agent == "AI")
df_morality_AI <- df %>% filter(Trait == "Increased Morality" & Agent == "AI")
df_intelligence_human <- df %>% filter(Trait == "Increased Intelligence" & Agent == "Human")
df_morality_human <- df %>% filter(Trait == "Increased Morality" & Agent == "Human")

```

***

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,
    Trait,
    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),
    Trait = factor(Trait)
  )


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

# relevel factors

df_long$Trait <- 
  factor(df_long$Trait, 
         levels = c("Increased Morality", "Increased Intelligence"))

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

```

***

***

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 increase condition, and similar for the morality condition, and does this depends on the type of Agent.

***

## Intelligence Conditions

First we look at whether people in the intelligence conditions perceived higher intelligence after the augmentation, and whether this was affected by agent type. This is first for the general ratings.

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

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

# relevel factors

df_long_int_int_only$Time <- 
  factor(df_long_int_int_only$Time, 
         levels = c("Pre", "Post"))

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

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = df_long_int_int_only,
  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_int_int_only_table <- df_long_int_int_only %>%
  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_int_int_only_table, format = "html", row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

We then do the same for the average-person comparison question.

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

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

# relevel factors

df_long_int_comparison_int_only$Time <- 
  factor(df_long_int_comparison_int_only$Time, 
         levels = c("Pre", "Post"))

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

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = df_long_int_comparison_int_only,
  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_int_comparison_int_only_table <- df_long_int_comparison_int_only %>%
  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_int_comparison_int_only_table, format = "html", row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

## Morality Conditions

And now for people in the morality augmentation conditions, first on the general ratings.

```{r, message=FALSE}
# subset the data so only people in morality condition and ratings of morality, in long format
df_long_moral_moral_only <- df_long %>%
  filter(
    Trait == "Increased Morality",
    Outcome == "Moral"
  )

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

# relevel factors

df_long_moral_moral_only$Time <- 
  factor(df_long_moral_moral_only$Time, 
         levels = c("Pre", "Post"))

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

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = df_long_moral_moral_only,
  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_moral_moral_only_table <- df_long_moral_moral_only %>%
  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_moral_moral_only_table, format = "html", row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

And now for the ratings in comparison to the average person.

```{r, message=FALSE}
# subset the data so only people in morality condition and ratings of morality, in long format
df_long_moral_comparison_moral_only <- df_long %>%
  filter(
    Trait == "Increased Morality",
    Outcome == "Moral_Comparison"
  )

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

# relevel factors

df_long_moral_comparison_moral_only$Time <- 
  factor(df_long_moral_comparison_moral_only$Time, 
         levels = c("Pre", "Post"))

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

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Agent + (1 | Participant),
  data = df_long_moral_comparison_moral_only,
  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_moral_comparison_moral_only_table <- df_long_moral_comparison_moral_only %>%
  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_moral_comparison_moral_only_table, format = "html", row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

# Effects by Condition

***

## Descriptives & Simple Effects

Now we will turn to look at different effects by condition. First, we will look at descriptives, and we'll do this seperately for the different conditions by agent (human vs AI) and trait (morality vs intelligence). We'll also report here the simple effects of augmentation (pre vs post), since we'll need those.

***

### 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*.

```{r}
summary_table_intelligence_AI <- df_long %>%
  filter(
    Trait == "Increased Intelligence",
    Agent == "AI",
    Outcome %in% c("Intelligent", "Intelligent_Comparison", "Moral", "Moral_Comparison", "Trust", "Danger")
  ) %>%
  mutate(
  Outcome = factor(Outcome, levels = c(
    "Intelligent", "Intelligent_Comparison",
    "Moral", "Moral_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 Human)",
      "Moral" = "Morality",
      "Moral_Comparison" = "Morality (Compared to Human)"
    )
  )

kable(summary_table_intelligence_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 Studies 2a and 2b, we'll then follow this with paired-sample t-tests.

```{r, message=FALSE}
# Paired t-test
results <- t.test(df_intelligence_AI$Pre_Intelligent, df_intelligence_AI$Post_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_intelligence_AI$Post_Intelligent, df_intelligence_AI$Pre_Intelligent, paired = TRUE)
d_val <- round(effect_size$Cohens_d, 2)

# Bayes Factor
bf_result <- ttestBF(x = df_intelligence_AI$Post_Intelligent, y = df_intelligence_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[[var1]], clean_data[[var2]], 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_inc_intelligence <- paired.t.test.bf(data = df_intelligence_AI, var1 = "Pre_Intelligent", var2 = "Post_Intelligent", labeldv = "Intelligence")
kable(intelligence_inc_intelligence, 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_inc_intelligence <- paired.t.test.bf(data = df_intelligence_AI, 
                                                  var1 = "Pre_Intelligent", 
                                                  var2 = "Post_Intelligent", 
                                                  labeldv = "Intelligence")

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

morality_inc_intelligence <- paired.t.test.bf(data = df_intelligence_AI, 
                                              var1 = "Pre_Moral", 
                                              var2 = "Post_Moral", 
                                              labeldv = "Morality")

morality_comparison_inc_intelligence <- paired.t.test.bf(data = df_intelligence_AI, 
                                                         var1 = "Pre_Moral_Comparison", 
                                                         var2 = "Post_Moral_Comparison", 
                                                         labeldv = "Morality_Comparison")

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

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

# Add a DV label column to each
intelligence_inc_intelligence$DV <- "Intelligence"
intelligence_comparison_inc_intelligence$DV <- "Intelligence (Compared to Human)"
morality_inc_intelligence$DV <- "Morality"
morality_comparison_inc_intelligence$DV <- "Morality (Compared to Human)"
trust_inc_intelligence$DV <- "Trust"
danger_inc_intelligence$DV <- "Danger"

# Combine into a single data frame
combined_results <- rbind(intelligence_inc_intelligence,
                          intelligence_comparison_inc_intelligence,
                          morality_inc_intelligence,
                          morality_comparison_inc_intelligence,
                          trust_inc_intelligence,
                          danger_inc_intelligence)

# 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")

```

***

### AI + Morality Conditions

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 *morality*.

```{r}
summary_table_morality_AI <- df_long %>%
  filter(
    Trait == "Increased Morality",
    Agent == "AI",
    Outcome %in% c("Intelligent", "Intelligent_Comparison", "Moral", "Moral_Comparison", "Trust", "Danger")
  ) %>%
  mutate(
  Outcome = factor(Outcome, levels = c(
    "Intelligent", "Intelligent_Comparison",
    "Moral", "Moral_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 Human)",
      "Moral" = "Morality",
      "Moral_Comparison" = "Morality (Compared to Human)"
    )
  )

kable(summary_table_morality_AI, 
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Morality (AI 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_inc_morality <- paired.t.test.bf(data = df_morality_AI, 
                                                  var1 = "Pre_Intelligent", 
                                                  var2 = "Post_Intelligent", 
                                                  labeldv = "Intelligence")

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

morality_inc_morality <- paired.t.test.bf(data = df_morality_AI, 
                                              var1 = "Pre_Moral", 
                                              var2 = "Post_Moral", 
                                              labeldv = "Morality")

morality_comparison_inc_morality <- paired.t.test.bf(data = df_morality_AI, 
                                                         var1 = "Pre_Moral_Comparison", 
                                                         var2 = "Post_Moral_Comparison", 
                                                         labeldv = "Morality_Comparison")

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

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

# Add a DV label column to each
intelligence_inc_morality$DV <- "Intelligence"
intelligence_comparison_inc_morality$DV <- "Intelligence (Compared to Human)"
morality_inc_morality$DV <- "Morality"
morality_comparison_inc_morality$DV <- "Morality (Compared to Human)"
trust_inc_morality$DV <- "Trust"
danger_inc_morality$DV <- "Danger"

# Combine into a single data frame
combined_results <- rbind(intelligence_inc_morality,
                          intelligence_comparison_inc_morality,
                          morality_inc_morality,
                          morality_comparison_inc_morality,
                          trust_inc_morality,
                          danger_inc_morality)

# 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 Morality (AI Only)</span>",
      row.names = FALSE) %>% 
      kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")

```

***


### Human + 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*.

```{r}
summary_table_intelligence_human <- df_long %>%
  filter(
    Trait == "Increased Intelligence",
    Agent == "Human",
    Outcome %in% c("Intelligent", "Intelligent_Comparison", "Moral", "Moral_Comparison", "Trust", "Danger")
  ) %>%
  mutate(
  Outcome = factor(Outcome, levels = c(
    "Intelligent", "Intelligent_Comparison",
    "Moral", "Moral_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 Human)",
      "Moral" = "Morality",
      "Moral_Comparison" = "Morality (Compared to Human)"
    )
  )

kable(summary_table_intelligence_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")
      
```

***

```{r, message=FALSE}

# Run the paired sample t-tests for each.
intelligence_inc_intelligence <- paired.t.test.bf(data = df_intelligence_human, 
                                                  var1 = "Pre_Intelligent", 
                                                  var2 = "Post_Intelligent", 
                                                  labeldv = "Intelligence")

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

morality_inc_intelligence <- paired.t.test.bf(data = df_intelligence_human, 
                                              var1 = "Pre_Moral", 
                                              var2 = "Post_Moral", 
                                              labeldv = "Morality")

morality_comparison_inc_intelligence <- paired.t.test.bf(data = df_intelligence_human, 
                                                         var1 = "Pre_Moral_Comparison", 
                                                         var2 = "Post_Moral_Comparison", 
                                                         labeldv = "Morality_Comparison")

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

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

# Add a DV label column to each
intelligence_inc_intelligence$DV <- "Intelligence"
intelligence_comparison_inc_intelligence$DV <- "Intelligence (Compared to Human)"
morality_inc_intelligence$DV <- "Morality"
morality_comparison_inc_intelligence$DV <- "Morality (Compared to Human)"
trust_inc_intelligence$DV <- "Trust"
danger_inc_intelligence$DV <- "Danger"

# Combine into a single data frame
combined_results <- rbind(intelligence_inc_intelligence,
                          intelligence_comparison_inc_intelligence,
                          morality_inc_intelligence,
                          morality_comparison_inc_intelligence,
                          trust_inc_intelligence,
                          danger_inc_intelligence)

# 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")

```

***

### Human + Morality 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 *morality*.

```{r}
summary_table_morality_human <- df_long %>%
  filter(
    Trait == "Increased Morality",
    Agent == "Human",
    Outcome %in% c("Intelligent", "Intelligent_Comparison", "Moral", "Moral_Comparison", "Trust", "Danger")
  ) %>%
  mutate(
  Outcome = factor(Outcome, levels = c(
    "Intelligent", "Intelligent_Comparison",
    "Moral", "Moral_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 Human)",
      "Moral" = "Morality",
      "Moral_Comparison" = "Morality (Compared to Human)"
    )
  )

kable(summary_table_morality_human,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Effects of Increased Morality (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_inc_morality <- paired.t.test.bf(data = df_morality_human, 
                                                  var1 = "Pre_Intelligent", 
                                                  var2 = "Post_Intelligent", 
                                                  labeldv = "Intelligence")

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

morality_inc_morality <- paired.t.test.bf(data = df_morality_human, 
                                              var1 = "Pre_Moral", 
                                              var2 = "Post_Moral", 
                                              labeldv = "Morality")

morality_comparison_inc_morality <- paired.t.test.bf(data = df_morality_human, 
                                                         var1 = "Pre_Moral_Comparison", 
                                                         var2 = "Post_Moral_Comparison", 
                                                         labeldv = "Morality_Comparison")

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

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

# Add a DV label column to each
intelligence_inc_morality$DV <- "Intelligence"
intelligence_comparison_inc_morality$DV <- "Intelligence (Compared to Human)"
morality_inc_morality$DV <- "Morality"
morality_comparison_inc_morality$DV <- "Morality (Compared to Human)"
trust_inc_morality$DV <- "Trust"
danger_inc_morality$DV <- "Danger"

# Combine into a single data frame
combined_results <- rbind(intelligence_inc_morality,
                          intelligence_comparison_inc_morality,
                          morality_inc_morality,
                          morality_comparison_inc_morality,
                          trust_inc_morality,
                          danger_inc_morality)

# 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 Morality (Human Only)</span>",
      row.names = FALSE) %>% 
      kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")


```

***

# Mixed Models

***

### General Intelligence & Morality

First, we ask whether increased morality predicts rated intelligence for humans and AI, and whether increased intelligence predicts rated morality, and whether this is different for humans and AI. We therefore look only at the conditions where morality was described, or only conditions where intelligence was described.

***

First we look at the conditions where *intelligence was manipulated*, and look at *ratings of morality*.

```{r}
# Create long dataframe with only the intelligence manipulation and the ratings of morality
model_df <- df_long %>%
  filter(
    Trait == "Increased Intelligence", # Only intelligence condition
    Outcome == "Moral" # Only morality ratings
  )

# 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 Morality</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 Morality</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

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

plot_morality_from_intelligence <- ggplot(model_df %>% filter(Outcome == "Moral"),
       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 Morality\nAfter Intelligence Augmentation",
    x = "Time",
    y = "Perceived Morality",
    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_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)
  )

plot_morality_from_intelligence
```

***

Second we look at the conditions where *morality was manipulated*, and look at *ratings of intelligence*.

```{r}
# Create long dataframe with only the intelligence manipulation and the ratings of morality
model_df <- df_long %>%
  filter(
    Trait == "Increased Morality", # Only morality condition
    Outcome == "Intelligent" # Only intelligence ratings
  )

# 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 Morality on Perceived Intelligence</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 Morality on Perceived Intelligence</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

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

plot_intelligence_from_morality <- ggplot(model_df %>% filter(Outcome == "Intelligent"),
       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 Intelligence\nAfter Morality Augmentation",
    x = "Time",
    y = "Perceived Intelligence",
    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_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)
  )

plot_intelligence_from_morality
```


***

We'll now just create a combined figure of both that makes these patterns clearer.

```{r, message=FALSE}
# Remove legend from the first plot
plot_morality_from_intelligence_clean <- plot_morality_from_intelligence +
  theme(legend.position = "none")

# Combine
combined_int_morality_plot <- plot_morality_from_intelligence_clean + plot_intelligence_from_morality +
  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 4 Intelligence and Morality.png")), plot = combined_int_morality_plot,
       width = 8, height = 5, units = "in", dpi = 300)

combined_int_morality_plot

```

***

### Intelligence & Morality Comparison

First, we ask whether increased morality predicts rated intelligence for humans and AI, and whether increased intelligence predicts rated morality, and whether this is different for humans and AI. We therefore look only at the conditions where morality was described, or only conditions where intelligence was described. Here we're looking at the question on in comparison to a typical person.

***

First we look at the conditions where *intelligence was manipulated*, and look at *ratings of morality*.

```{r}
# Create long dataframe with only the intelligence manipulation and the ratings of morality
model_df <- df_long %>%
  filter(
    Trait == "Increased Intelligence", # Only intelligence condition
    Outcome == "Moral_Comparison" # Only morality ratings
  )

# 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 Morality (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 Morality (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

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

plot_morality_comparison_from_intelligence <- ggplot(model_df %>% filter(Outcome == "Moral_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 Morality\nAfter Intelligence Augmentation",
    x = "Time",
    y = expression(atop("Morality", "(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)
  )

plot_morality_comparison_from_intelligence
```

***

Second we look at the conditions where *morality was manipulated*, and look at *ratings of intelligence*.

```{r}
# Create long dataframe with only the intelligence manipulation and the ratings of morality
model_df <- df_long %>%
  filter(
    Trait == "Increased Morality", # Only morality condition
    Outcome == "Intelligent_Comparison" # Only intelligence ratings
  )

# 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 Morality on Perceived Intelligence (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 Morality on Perceived Intelligence (Comparison)</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```

***

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

plot_intelligence_comparison_from_morality <- ggplot(model_df %>% filter(Outcome == "Intelligent_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 Intelligence\nAfter Morality Augmentation",
    x = "Time",
    y = expression(atop("Intelligence", "(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)
  )

plot_intelligence_comparison_from_morality
```


***

We'll now just create a combined figure of both that makes these patterns clearer.

```{r, message=FALSE, fig.width=8, fig.height=5}
# Remove legend from the first plot
plot_morality_comparison_from_intelligence_clean <- plot_morality_comparison_from_intelligence +
  theme(legend.position = "none")

# Combine
combined_int_morality_comparison_plot <- plot_morality_comparison_from_intelligence_clean + plot_intelligence_comparison_from_morality +
  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 4 Intelligence and Morality Comparison.png")), plot = combined_int_morality_comparison_plot,
       width = 8, height = 5, units = "in", dpi = 300)

combined_int_morality_comparison_plot

```

***

### Trust

Now we'll look at trust.

```{r}
# Create long dataframe with only the ratings of trust
model_df <- df_long %>%
  filter(
    Outcome == "Trust" # Only trust ratings
  )

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

# relevel factors

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

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

model_df$Trait <- 
  factor(model_df$Trait, 
         levels = c("Increased Morality", "Increased Intelligence"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Trait * 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 == "TraitIncreased Intelligence" ~ "Trait [Increased Intelligence]",
    term == "AgentAI" ~ "Agent [AI]",
    term == "TimePost:TraitIncreased Intelligence" ~ "Interaction [Time × Trait]",
    term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
    term == "TraitIncreased Intelligence:AgentAI" ~ "Interaction [Trait × Agent]",
    term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Interaction [Time × Trait × 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;
      '>Trust</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, Trait, 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;
      '>Trust</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```


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

model_df <- model_df %>% # just so the panels say augmentation
  mutate(Trait = case_when(
    Trait == "Increased Morality" ~ "Morality Augmentation",
    Trait == "Increased Intelligence" ~ "Intelligence Augmentation",
    TRUE ~ as.character(Trait)
  ))

trust_plot <- ggplot(model_df, aes(x = Time, y = Rating)) + # fit model

  # Jittered raw data
  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.20, jitter.height = 0.35)
  ) +

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

  # Mean + CI by Agent
  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 styling
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Facet by Trait (matching original design)
  facet_wrap(~ Trait) +

  # Axis and label styling
  labs(
    x = "Time",
    y = "Trustworthiness",
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(1, 7)) +
  scale_y_continuous(breaks = 1:7) +

  # Theme
  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),
    strip.text = element_text(size = 13)
  )

# 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 4 Trust.png")), plot = trust_plot,
       width = 6, height = 4, units = "in", dpi = 300)

# Print figure in markdown
trust_plot
```

***

### Danger

Now we'll look at danger.

```{r}
# Create long dataframe with only the ratings of morality
model_df <- df_long %>%
  filter(
    Outcome == "Danger" # Only morality ratings
  )

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

# relevel factors

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

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

model_df$Trait <- 
  factor(model_df$Trait, 
         levels = c("Increased Morality", "Increased Intelligence"))

# Fit the model with random intercept by participant
model <- lmer(
  Rating ~ Time * Trait * 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 == "TraitIncreased Intelligence" ~ "Trait [Increased Intelligence]",
    term == "AgentAI" ~ "Agent [AI]",
    term == "TimePost:TraitIncreased Intelligence" ~ "Interaction [Time × Trait]",
    term == "TimePost:AgentAI" ~ "Interaction [Time × Agent]",
    term == "TraitIncreased Intelligence:AgentAI" ~ "Interaction [Trait × Agent]",
    term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Interaction [Time × Trait × 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;
      '>Trust</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, Trait, 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;
      '>Danger</span>",
      row.names = FALSE) %>%
  kable_styling(
    bootstrap_options = "striped",
    full_width = FALSE,
    position = "left"
  )
```


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

model_df <- model_df %>% # just so the panels say augmentation
  mutate(Trait = case_when(
    Trait == "Increased Morality" ~ "Morality Augmentation",
    Trait == "Increased Intelligence" ~ "Intelligence Augmentation",
    TRUE ~ as.character(Trait)
  ))

danger_plot <- ggplot(model_df, aes(x = Time, y = Rating)) + # fit model

  # Jittered raw data
  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 by Agent
  stat_summary(
    aes(group = Agent, color = Agent),
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    position = position_dodge(width = 0.7)
  ) +

  # Mean + CI by Agent
  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 styling
  scale_color_manual(values = line_colors) +
  scale_fill_manual(values = fill_colors) +

  # Facet by Trait (matching original design)
  facet_wrap(~ Trait) +

  # Axis and label styling
  labs(
    x = "Time",
    y = "Danger",
    fill = NULL,
    colour = NULL
  ) +
  coord_cartesian(ylim = c(1, 7)) +
  scale_y_continuous(breaks = 1:7) +

  # Theme
  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),
    strip.text = element_text(size = 13)
  )

# 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 4 Danger.png")), plot = danger_plot,
       width = 6, height = 4, units = "in", dpi = 300)

# Print figure in markdown
danger_plot
```

***

# Crossed Effect of Conditions

Now we are testing the difference between pre and post-augmentation ratings (perceived morality for the augmented intelligence group and perceived intelligence for the augmented morality group). That is, we look at the effect of each manipulation on the dimension it did not directly target, and see which was stronger.

***

## Intelligence and Morality

We first do for the general ratings of intelligence and morality.

```{r}
# Create difference scores
df <- df %>%
  mutate(
    Morality_Diff = Post_Moral - Pre_Moral,
    Intelligence_Diff = Post_Intelligent - Pre_Intelligent
  )

# Create a cross variable of intelligence for the morality increase condition and vice versa
df_cross <- df %>%
  mutate(
    Cross_Target_Diff = case_when(
      Trait == "Increased Intelligence" ~ Morality_Diff,
      Trait == "Increased Morality" ~ Intelligence_Diff
    )
  )

# conduct a linear model and get df
model_obj <- lm(Cross_Target_Diff ~ Trait * Agent, data = df_cross)
df_resid <- df.residual(model_obj)

# tidy it up for formatting and get the df in the table
formatted_lm_table <- tidy(model_obj) %>%
  mutate(
    df = df_resid,
    term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TraitIncreased Intelligence" ~ "Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Interaction [Trait × Agent]",
      TRUE ~ term),  # fallback for unexpected terms
    estimate = round(estimate, 2),
    std.error = round(std.error, 2),
    statistic = round(statistic, 2),
    p.value = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  rename(
    Term = term,
    Estimate = estimate,
    SE = std.error,
    t = statistic,
    p = p.value,
    df = df
  ) %>%
  select(Term, Estimate, SE, t, df, p)

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

We'll then run descriptive statistics for this.

```{r}
desc_cross_target <- df_cross %>%
  group_by(Trait, Agent) %>%
  summarise(
    n = n(),
    min = min(Cross_Target_Diff, na.rm = TRUE),
    max = max(Cross_Target_Diff, na.rm = TRUE),
    mean = round(mean(Cross_Target_Diff, na.rm = TRUE), 2),
    sd = round(sd(Cross_Target_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(
    Trait = case_when(
      Trait == "Increased Intelligence" ~ "Increased Intelligence on Perceived Morality",
      Trait == "Increased Morality" ~ "Increased Morality on Perceived Intelligence",
      TRUE ~ Trait
    )
  )

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

```{r}
desc_cross_target <- df_cross %>%
  group_by(Trait) %>%
  summarise(
    n = n(),
    min = min(Cross_Target_Diff, na.rm = TRUE),
    max = max(Cross_Target_Diff, na.rm = TRUE),
    mean = round(mean(Cross_Target_Diff, na.rm = TRUE), 2),
    sd = round(sd(Cross_Target_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(
    Trait = case_when(
      Trait == "Increased Intelligence" ~ "Increased Intelligence on Perceived Morality",
      Trait == "Increased Morality" ~ "Increased Morality on Perceived Intelligence",
      TRUE ~ Trait
    )
  )

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

```{r}
desc_cross_target <- df_cross %>%
  group_by(Agent) %>%
  summarise(
    n = n(),
    min = min(Cross_Target_Diff, na.rm = TRUE),
    max = max(Cross_Target_Diff, na.rm = TRUE),
    mean = round(mean(Cross_Target_Diff, na.rm = TRUE), 2),
    sd = round(sd(Cross_Target_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  )

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

***

## Intelligence and Morality (Comparison)

We then do for the ratings of intelligence and morality in comparison to a human.

```{r}
# Create difference scores
df <- df %>%
  mutate(
    Morality_Diff = Post_Moral_Comparison - Pre_Moral_Comparison,
    Intelligence_Diff = Post_Intelligent_Comparison - Pre_Intelligent_Comparison
  )

# Create a cross variable of intelligence for the morality increase condition and vice versa
df_cross <- df %>%
  mutate(
    Cross_Target_Diff = case_when(
      Trait == "Increased Intelligence" ~ Morality_Diff,
      Trait == "Increased Morality" ~ Intelligence_Diff
    )
  )

# conduct a linear model and get df
model_obj <- lm(Cross_Target_Diff ~ Trait * Agent, data = df_cross)
df_resid <- df.residual(model_obj)

# tidy it up for formatting and get the df in the table
formatted_lm_table <- tidy(model_obj) %>%
  mutate(
    df = df_resid,
    term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "TraitIncreased Intelligence" ~ "Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [AI]",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Interaction [Trait × Agent]",
      TRUE ~ term),  # fallback for unexpected terms
    estimate = round(estimate, 2),
    std.error = round(std.error, 2),
    statistic = round(statistic, 2),
    p.value = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  rename(
    Term = term,
    Estimate = estimate,
    SE = std.error,
    t = statistic,
    p = p.value,
    df = df
  ) %>%
  select(Term, Estimate, SE, t, df, p)

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

We'll then run descriptive statistics for this.

```{r}
desc_cross_target <- df_cross %>%
  group_by(Trait, Agent) %>%
  summarise(
    n = n(),
    min = min(Cross_Target_Diff, na.rm = TRUE),
    max = max(Cross_Target_Diff, na.rm = TRUE),
    mean = round(mean(Cross_Target_Diff, na.rm = TRUE), 2),
    sd = round(sd(Cross_Target_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(
    Trait = case_when(
      Trait == "Increased Intelligence" ~ "Increased Intelligence on Perceived Morality",
      Trait == "Increased Morality" ~ "Increased Morality on Perceived Intelligence",
      TRUE ~ Trait
    )
  )

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

```{r}
desc_cross_target <- df_cross %>%
  group_by(Trait) %>%
  summarise(
    n = n(),
    min = min(Cross_Target_Diff, na.rm = TRUE),
    max = max(Cross_Target_Diff, na.rm = TRUE),
    mean = round(mean(Cross_Target_Diff, na.rm = TRUE), 2),
    sd = round(sd(Cross_Target_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(
    Trait = case_when(
      Trait == "Increased Intelligence" ~ "Increased Intelligence on Perceived Morality",
      Trait == "Increased Morality" ~ "Increased Morality on Perceived Intelligence",
      TRUE ~ Trait
    )
  )

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

```{r}
desc_cross_target <- df_cross %>%
  group_by(Agent) %>%
  summarise(
    n = n(),
    min = min(Cross_Target_Diff, na.rm = TRUE),
    max = max(Cross_Target_Diff, na.rm = TRUE),
    mean = round(mean(Cross_Target_Diff, na.rm = TRUE), 2),
    sd = round(sd(Cross_Target_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  )

kable(desc_cross_target, format = "html", 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 and morality prior to the augmentation. This is overall, across AI and human.

```{r}
pre_intelligence_morality_corr <- jim.correlation(DV_A = df$Pre_Moral, DV_B = df$Pre_Intelligent, Item = "Pre Intelligence + Pre Morality")

pre_intelligence_morality_comparison_corr <- jim.correlation(DV_A = df$Pre_Moral_Comparison, DV_B = df$Pre_Intelligent_Comparison, Item = "Pre Intelligence + Pre Morality (Comparison)")

pre_correlations <- rbind(pre_intelligence_morality_corr, pre_intelligence_morality_comparison_corr)

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

***

We can also look for human and AI seperately.

```{r}
pre_intelligence_morality_AI_corr <- jim.correlation(DV_A = df_AI$Pre_Moral, 
                                                     DV_B = df_AI$Pre_Intelligent, 
                                                     Item = "Pre Intelligence + Pre Morality (AI)")

pre_intelligence_morality_human_corr <- jim.correlation(DV_A = df_human$Pre_Moral, 
                                                        DV_B = df_human$Pre_Intelligent,
                                                        Item = "Pre Intelligence + Pre Morality (Human)")

pre_intelligence_morality_comparison_AI_corr <- jim.correlation(DV_A = df_AI$Pre_Moral_Comparison, 
                                                                DV_B = df_AI$Pre_Intelligent_Comparison,
                                                                Item = "Pre Intelligence + Pre Morality (AI) (Comparison)")

pre_intelligence_morality_human_comparison_corr <- jim.correlation(DV_A = df_human$Pre_Moral_Comparison, 
                                                                   DV_B = df_human$Pre_Intelligent_Comparison, 
                                                                   Item = "Pre Intelligence + Pre Morality (Human) (Comparison)")

pre_correlations <- rbind(pre_intelligence_morality_AI_corr, pre_intelligence_morality_human_corr,
                          pre_intelligence_morality_comparison_AI_corr, pre_intelligence_morality_human_comparison_corr)

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

## Post Augmentation.

We then look at the correlation between judgments of intelligence and morality after the augmentation. Given the between-subjects manipulation of the type of augmentation we look at this seperately for the increased intelligence and increased morality conditions.

```{r}
post_corr_increased_intelligence <- 
  jim.correlation(DV_A = df_intelligence$Post_Moral, 
                  DV_B = df_intelligence$Post_Intelligent,
                  Item = "Increased Intelligence: Post Intelligence + Post Morality")

post_comparison_corr_increased_intelligence <- 
  jim.correlation(DV_A = df_intelligence$Post_Moral_Comparison, 
                  DV_B = df_intelligence$Post_Intelligent_Comparison,
                  Item = "Increased Intelligence: Post Intelligence + Post Morality (Comparison)")

post_corr_increased_morality <- 
  jim.correlation(DV_A = df_morality$Post_Moral, 
                  DV_B = df_morality$Post_Intelligent,
                  Item = "Increased Morality: Post Intelligence + Post Morality")

post_comparison_corr_increased_morality <- 
  jim.correlation(DV_A = df_morality$Post_Moral_Comparison, 
                  DV_B = df_morality$Post_Intelligent_Comparison,
                  Item = "Increased Morality: Post Intelligence + Post Morality (Comparison)")

post_correlations <- rbind(post_corr_increased_intelligence,
                          post_comparison_corr_increased_intelligence,
                          post_corr_increased_morality,
                          post_comparison_corr_increased_morality)

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

***

And this is broken down by specific condition.

```{r}
post_corr_increased_intelligence_AI <- 
  jim.correlation(DV_A = df_intelligence_AI$Post_Moral, 
                  DV_B = df_intelligence_AI$Post_Intelligent,
                  Item = "Increased Intelligence + AI: Post Intelligence + Post Morality")

post_corr_increased_intelligence_human <- 
  jim.correlation(DV_A = df_morality_human$Post_Moral, 
                  DV_B = df_morality_human$Post_Intelligent,
                  Item = "Increased Intelligence + Human: Post Intelligence + Post Morality")

post_comparison_corr_increased_intelligence_AI <- 
  jim.correlation(DV_A = df_intelligence_AI$Post_Moral_Comparison, 
                  DV_B = df_intelligence_AI$Post_Intelligent_Comparison,
                  Item = "Increased Intelligence + AI: Post Intelligence + Post Morality (Comparison)")

post_comparison_corr_increased_intelligence_human <- 
  jim.correlation(DV_A = df_morality_human$Post_Moral_Comparison, 
                  DV_B = df_morality_human$Post_Intelligent_Comparison,
                  Item = "Increased Intelligence + Human: Post Intelligence + Post Morality (Comparison)")

post_corr_increased_morality_AI <- 
  jim.correlation(DV_A = df_morality_AI$Post_Moral, 
                  DV_B = df_morality_AI$Post_Intelligent,
                  Item = "Increased Morality + AI: Post Intelligence + Post Morality")

post_corr_increased_morality_human <- 
  jim.correlation(DV_A = df_morality_human$Post_Moral, 
                  DV_B = df_morality_human$Post_Intelligent,
                  Item = "Increased Morality + Human: Post Intelligence + Post Morality")

post_comparison_corr_increased_morality_AI <- 
  jim.correlation(DV_A = df_morality_AI$Post_Moral_Comparison, 
                  DV_B = df_morality_AI$Post_Intelligent_Comparison,
                  Item = "Increased Morality + AI: Post Intelligence + Post Morality (Comparison)")

post_comparison_corr_increased_morality_human <- 
  jim.correlation(DV_A = df_morality_human$Post_Moral_Comparison, 
                  DV_B = df_morality_human$Post_Intelligent_Comparison,
                  Item = "Increased Morality + Human: Post Intelligence + Post Morality (Comparison)")

post_correlations <- rbind(post_corr_increased_intelligence_AI,
                           post_corr_increased_intelligence_human,
                           post_comparison_corr_increased_intelligence_AI,
                           post_comparison_corr_increased_intelligence_human,
                           post_corr_increased_morality_AI,
                           post_corr_increased_morality_human,
                           post_comparison_corr_increased_morality_AI,
                           post_comparison_corr_increased_morality_human)

kable(post_correlations, 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 look first at ratings of intelligence.

```{r}
# Prepare long-format data and center Familiarity
long_df_intelligent <- 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")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

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

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(IntelligentModel_familiarity, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:TraitIncreased Intelligence" ~ "Familiarity × Trait",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Familiarity_c:TimePost:TraitIncreased Intelligence" ~ "Familiarity × Time × Trait",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      term == "Familiarity_c:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Familiarity_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "Familiarity × Time",
    "Familiarity × Trait",
    "Familiarity × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "Familiarity × Time × Trait",
    "Familiarity × Time × Agent",
    "Familiarity × Trait × Agent",
    "Time × Trait × Agent",
    "Familiarity × Time × Trait × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model of Augmentation, Augmented Trait Type, Agent, and Familiarity (Centered) 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_intelligent_comparison <- 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")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

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

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(IntelligentModel_comparison_familiarity, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:TraitIncreased Intelligence" ~ "Familiarity × Trait",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Familiarity_c:TimePost:TraitIncreased Intelligence" ~ "Familiarity × Time × Trait",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      term == "Familiarity_c:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Familiarity_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "Familiarity × Time",
    "Familiarity × Trait",
    "Familiarity × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "Familiarity × Time × Trait",
    "Familiarity × Time × Agent",
    "Familiarity × Trait × Agent",
    "Time × Trait × Agent",
    "Familiarity × Time × Trait × Agent"
  )))

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

****

## Morality 

We'll then first at ratings of morality

```{r}
# Prepare long-format data and center Familiarity
long_df_moral <- df %>%
  pivot_longer(
    cols = c(Pre_Moral, Post_Moral),
    names_to = "Time",
    values_to = "Moral"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral = "Pre",
                  Post_Moral = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
MoralModel_familiarity <- lmer(
  Moral ~ Familiarity_c * Time * Trait * Agent + 
    (1 | Participant),
  data = long_df_moral,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(MoralModel_familiarity, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:TraitIncreased Intelligence" ~ "Familiarity × Trait",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Familiarity_c:TimePost:TraitIncreased Intelligence" ~ "Familiarity × Time × Trait",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      term == "Familiarity_c:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Familiarity_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "Familiarity × Time",
    "Familiarity × Trait",
    "Familiarity × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "Familiarity × Time × Trait",
    "Familiarity × Time × Agent",
    "Familiarity × Trait × Agent",
    "Time × Trait × Agent",
    "Familiarity × Time × Trait × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model of Augmentation, Augmented Trait Type, Agent, and Familiarity (Centered) on Ratings of Morality</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_moral_comparison <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Comparison, Post_Moral_Comparison),
    names_to = "Time",
    values_to = "Moral_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Comparison = "Pre",
                  Post_Moral_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Familiarity_c = scale(Familiarity, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
MoralModel_comparison_familiarity <- lmer(
  Moral_Comparison ~ Familiarity_c * Time * Trait * Agent + 
    (1 | Participant),
  data = long_df_moral_comparison,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(MoralModel_comparison_familiarity, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Familiarity_c:TimePost" ~ "Familiarity × Time",
      term == "Familiarity_c:TraitIncreased Intelligence" ~ "Familiarity × Trait",
      term == "Familiarity_c:AgentAI" ~ "Familiarity × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Familiarity_c:TimePost:TraitIncreased Intelligence" ~ "Familiarity × Time × Trait",
      term == "Familiarity_c:TimePost:AgentAI" ~ "Familiarity × Time × Agent",
      term == "Familiarity_c:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Familiarity_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "Familiarity × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "Familiarity (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "Familiarity × Time",
    "Familiarity × Trait",
    "Familiarity × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "Familiarity × Time × Trait",
    "Familiarity × Time × Agent",
    "Familiarity × Trait × Agent",
    "Time × Trait × Agent",
    "Familiarity × Time × Trait × Agent"
  )))

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

***

# AI Knowledge (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.

***

## Intelligence

***

We'll look first at ratings of intelligence.

```{r}
# Prepare long-format data and center Familiarity
long_df_intelligent <- 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")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

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

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(IntelligentModel_pew, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:TraitIncreased Intelligence" ~ "PEW × Trait",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence" ~ "PEW × Time × Trait",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Time × Agent",
      term == "Pew_Correct_c:TraitIncreased Intelligence:AgentAI" ~ "PEW × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "PEW × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "PEW AI Knowledge (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "PEW × Time",
    "PEW × Trait",
    "PEW × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "PEW × Time × Trait",
    "PEW × Time × Agent",
    "PEW × Trait × Agent",
    "Time × Trait × Agent",
    "PEW × Time × Trait × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model of Augmentation, Augmented Trait Type, Agent, and PEW AI Knowledge (Centered) 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_intelligent_comparison <- df %>%
  pivot_longer(
    cols = c(Pre_Intelligent_Comparison, Post_Intelligent_Comparison),
    names_to = "Time",
    values_to = "Intelligent"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent_Comparison = "Pre",
                  Post_Intelligent_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

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

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(IntelligentModel_comparison_pew, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:TraitIncreased Intelligence" ~ "PEW × Trait",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence" ~ "PEW × Time × Trait",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Time × Agent",
      term == "Pew_Correct_c:TraitIncreased Intelligence:AgentAI" ~ "PEW × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "PEW × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "PEW AI Knowledge (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "PEW × Time",
    "PEW × Trait",
    "PEW × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "PEW × Time × Trait",
    "PEW × Time × Agent",
    "PEW × Trait × Agent",
    "Time × Trait × Agent",
    "PEW × Time × Trait × Agent"
  )))

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

***

## Morality

***

We'll then first at ratings of morality

```{r}
# Prepare long-format data and center Familiarity
long_df_moral <- df %>%
  pivot_longer(
    cols = c(Pre_Moral, Post_Moral),
    names_to = "Time",
    values_to = "Moral"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral = "Pre",
                  Post_Moral = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
MoralModel_pew <- lmer(
  Moral ~ Pew_Correct_c * Time * Trait * Agent + 
    (1 | Participant),
  data = long_df_moral,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(MoralModel_pew, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:TraitIncreased Intelligence" ~ "PEW × Trait",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence" ~ "PEW × Time × Trait",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Time × Agent",
      term == "Pew_Correct_c:TraitIncreased Intelligence:AgentAI" ~ "PEW × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "PEW × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "PEW AI Knowledge (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "PEW × Time",
    "PEW × Trait",
    "PEW × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "PEW × Time × Trait",
    "PEW × Time × Agent",
    "PEW × Trait × Agent",
    "Time × Trait × Agent",
    "PEW × Time × Trait × Agent"
  )))

# Display the table
kable(formatted_table,
      format = "html",
      caption = "<span style='color:black; font-weight:bold;
      '>Mixed Model of Augmentation, Augmented Trait Type, Agent, and PEW AI Knowledge (Centered) on Ratings of Morality</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_moral_comparison <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Comparison, Post_Moral_Comparison),
    names_to = "Time",
    values_to = "Moral"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Comparison = "Pre",
                  Post_Moral_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Trait = factor(Trait, levels = c("Increased Morality", "Increased Intelligence")),
    Agent = factor(Agent, levels = c("Human", "AI")),
    Pew_Correct_c = scale(Pew_Correct, center = TRUE, scale = FALSE) %>% as.numeric()
  )

# Fit the model
MoralModel_comparison_pew <- lmer(
  Moral ~ Pew_Correct_c * Time * Trait * Agent + 
    (1 | Participant),
  data = long_df_moral_comparison,
  REML = FALSE
)

# Format the table with Familiarity first
formatted_table <- broom.mixed::tidy(MoralModel_comparison_pew, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "Pew_Correct_c" ~ "PEW AI Knowledge (centered)",
      term == "TimePost" ~ "Time [Post]",
      term == "TraitIncreased Intelligence" ~ "Augmented Trait [Increased Intelligence]",
      term == "AgentAI" ~ "Agent [Increased Intelligence]",

      term == "Pew_Correct_c:TimePost" ~ "PEW × Time",
      term == "Pew_Correct_c:TraitIncreased Intelligence" ~ "PEW × Trait",
      term == "Pew_Correct_c:AgentAI" ~ "PEW × Agent",
      
      term == "TimePost:TraitIncreased Intelligence" ~ "Time × Trait",
      term == "TimePost:AgentAI" ~ "Time × Agent",
      term == "TraitIncreased Intelligence:AgentAI" ~ "Trait × Agent",
      

      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence" ~ "PEW × Time × Trait",
      term == "Pew_Correct_c:TimePost:AgentAI" ~ "PEW × Time × Agent",
      term == "Pew_Correct_c:TraitIncreased Intelligence:AgentAI" ~ "PEW × Trait × Agent",
      term == "TimePost:TraitIncreased Intelligence:AgentAI" ~ "Time × Trait × Agent",
      term == "Pew_Correct_c:TimePost:TraitIncreased Intelligence:AgentAI" ~ "PEW × Time × 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) %>%
  arrange(factor(Term, levels = c(
    "Intercept",
    "PEW AI Knowledge (centered)",
    "Time [Post]",
    "Augmented Trait [Increased Intelligence]",
    "Agent [Increased Intelligence]",
    "PEW × Time",
    "PEW × Trait",
    "PEW × Agent",
    "Time × Trait",
    "Time × Agent",
    "Trait × Agent",
    "PEW × Time × Trait",
    "PEW × Time × Agent",
    "PEW × Trait × Agent",
    "Time × Trait × Agent",
    "PEW × Time × Trait × Agent"
  )))

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