---
title: "Orthogonality Study 2a"
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)
```

***

# Description

***

In Study 2a we looked at whether participants think that the AI would be more moral directly because it is more intelligent, or instead may think that breakthroughs in intelligence will happen to coincide with unrelated breakthroughs in safety, without one necessarily causing the other. Moreover, we considered whether the relationship between increased intelligence and morality is symmetrical such that describing an AI as being more moral would also make people think the AI is more intelligent.  To do this, we used a within-subjects “augmentation paradigm” where participants first read a narrative that described an AI agent (“OmegaAI”) that was comparable to current models like ChatGPT and rated this AI on its intelligence and morality and indicated how much they would trust it and how dangerous it is. Next, participants read about how this model due to new advancement in machine learning, either rapidly increased in intelligence or morality, and then answered the questions again, framed as "Because of this breakthrough, how X is this now".

***

# 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(Hmisc)
library(car)
library(tidyverse)
library(knitr)
library(kableExtra)
library(BayesFactor)
library(effectsize)
library(gtsummary)
library(lme4)
library(lmerTest)
library(broom)
library(broom.mixed)
library(patchwork)
```

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

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

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

df$Condition <- 
  factor(df$Condition, 
         levels = c("Increased Morality", "Increased Intelligence"))
```

Sometimes we only want to be looking at one condition (e.g. for paired sample t-tests), so we'll just create two data frames here. One for participants who responded at baseline and then saw increased intelligence, and one for participants who responded at baseline but then saw increased morality.

```{r}
df_inc_intelligence <- df %>% 
  filter (Condition == "Increased Intelligence")

df_inc_morality <- df %>% 
  filter (Condition == "Increased Morality")
```

We will just check this has worked by looking at the number of participants in the conditions in the overall dataframe and then check the same number are in the new conditions.

```{r}
# Overall
kable(table(df$Condition), format = "html", caption = "Overall")%>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")

# Increased Intelligence Condition Dataframe
kable(table(df_inc_intelligence$Condition), format = "html", caption = "Intelligence")%>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")

# Increased Morality Condition Dataframe
kable(table(df_inc_morality$Condition), format = "html", caption = "Morality")%>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")
```

***

In total, we have `r nrow(df)` participants.

***

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


***

# Analysis

***

# Manipulation Checks

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.

First we look for the intelligence manipulation.

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

# Bayes Factor
bf_result <- ttestBF(x = df_inc_intelligence$Post_Intelligent, y = df_inc_intelligence$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_inc_intelligence, 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")
```

So now we'll do it for the human-comparison intelligence question.

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

***

Now we know it works, we will do the same for the morality manipulation check.

```{r, message=FALSE}
morality_inc_morality <- paired.t.test.bf(data = df_inc_morality, var1 = "Pre_Moral", var2 = "Post_Moral", labeldv = "Morality")
kable(morality_inc_morality, format = "html",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```

And for the morality in comparison to a human manipulation check.

```{r, message=FALSE}
morality_comparison_inc_morality <- paired.t.test.bf(data = df_inc_morality, var1 = "Pre_Moral_Comparison", var2 = "Post_Moral_Comparison", labeldv = "Morality_Comparison")
kable(morality_inc_morality, format = "html",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")
```


***

# Effects by Condition

***

## Increased Intelligence Condition

First we'll look at descriptives and the paired sample t-tests for the increased intelligence conditions.

```{r, message=FALSE}

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

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

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

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

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

danger_inc_intelligence <- paired.t.test.bf(data = df_inc_intelligence, 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",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")

```

And now we want descriptives, again for the increased intelligence condition only.

After getting the inferential tests, we also want to have the means and standard deviations. 

```{r}
summary_table <- df_inc_intelligence %>%
  select(
    Pre_Intelligent, Post_Intelligent, 
    Pre_Intelligent_Comparison, Post_Intelligent_Comparison,
    Pre_Moral, Post_Moral,
    Pre_Moral_Comparison, Post_Moral_Comparison,
    Pre_Trust, Post_Trust,
    Pre_Danger, Post_Danger
  ) %>%
  pivot_longer(everything(), names_to = "Variable", values_to = "Value") %>%
  mutate(Variable = factor( # This is just so they're in the order I put them in
    Variable,
    levels = c(
      "Pre_Intelligent", "Post_Intelligent", 
      "Pre_Intelligent_Comparison", "Post_Intelligent_Comparison",
      "Pre_Moral", "Post_Moral",
      "Pre_Moral_Comparison", "Post_Moral_Comparison",
      "Pre_Trust", "Post_Trust",
      "Pre_Danger", "Post_Danger"
    )
  )) %>%
  group_by(Variable) %>% # This is just so they're in the order I put them in
  summarise(
    min = min(Value, na.rm = TRUE),
    max = max(Value, na.rm = TRUE),
    mean = round(mean(Value, na.rm = TRUE), 2),
    sd = round(sd(Value, na.rm = TRUE), 2),
    .groups = "drop"
  )
  

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

***

We'll create a figure focusing on whether increased intelligence predicts rated morality.

```{r, fig.width=3, fig.height=3.5}
fill_color <- "#56B4E9"
line_color <- "#56B4E9"

model_df <- df_inc_intelligence %>%
  pivot_longer(
    cols = c(Pre_Moral, Post_Moral),
    names_to = "Time",
    values_to = "Rating"
  ) %>%
  mutate(
    Time =  dplyr::recode(Time,
                  "Pre_Moral" = "Pre",
                  "Post_Moral" = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Outcome = "Moral"  
  )

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

  # Jittered raw data points
  geom_jitter(
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    fill = fill_color,
    position = position_jitter(width = 0.35, height = 0.35)
  ) +

  # Summary line connecting group means
  stat_summary(
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    color = line_color,
    aes(group = 1)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    fill = fill_color,
    color = line_color,
    aes(group = 1)
  ) +

  # Axis labels and limits
  labs(
    title = "Perceived Morality\nAfter Intelligence Augmentation",
    x = "Time",
    y = "Perceived Morality"
  ) +
  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))
  )

plot_morality_from_intelligence
```

```{r, fig.width=3.5, fig.height=3.5}
fill_color <- "#56B4E9"
line_color <- "#56B4E9"

model_df <- df_inc_intelligence %>%
  pivot_longer(
    cols = c(Pre_Moral_Comparison, Post_Moral_Comparison),
    names_to = "Time",
    values_to = "Rating"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  "Pre_Moral_Comparison" = "Pre",
                  "Post_Moral_Comparison" = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Outcome = "Moral_Comparison"
  )

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

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

  # Summary line connecting group means
  stat_summary(
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    color = line_color,
    aes(group = 1)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    fill = fill_color,
    color = line_color,
    aes(group = 1)
  ) +

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

  # 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 = 3)),
    axis.title.x = element_blank(),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10))
  )

plot_morality_from_intelligence_comparison
```


***

## Increased Morality Condition

First we'll look at descriptives and the paired sample t-tests for the increased morality conditions.

```{r, message=FALSE}

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

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

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

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

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

danger_inc_morality <- paired.t.test.bf(data = df_inc_morality, 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",
            row.names = FALSE) %>%
        kable_styling(bootstrap_options = "striped", 
                      full_width = FALSE, position = "left")

```

And now we want descriptives, again for the increased morality condition only.

After getting the inferential tests, we also want to have the means and standard deviations. 

```{r}
summary_table <- df_inc_morality %>%
  select(
    Pre_Intelligent, Post_Intelligent, 
    Pre_Intelligent_Comparison, Post_Intelligent_Comparison,
    Pre_Moral, Post_Moral,
    Pre_Moral_Comparison, Post_Moral_Comparison,
    Pre_Trust, Post_Trust,
    Pre_Danger, Post_Danger
  ) %>%
  pivot_longer(everything(), names_to = "Variable", values_to = "Value") %>%
  mutate(Variable = factor( # This is just so they're in the order I put them in
    Variable,
    levels = c(
      "Pre_Intelligent", "Post_Intelligent", 
      "Pre_Intelligent_Comparison", "Post_Intelligent_Comparison",
      "Pre_Moral", "Post_Moral",
      "Pre_Moral_Comparison", "Post_Moral_Comparison",
      "Pre_Trust", "Post_Trust",
      "Pre_Danger", "Post_Danger"
    )
  )) %>%
  group_by(Variable) %>% # This is just so they're in the order I put them in
  summarise(
    min = min(Value, na.rm = TRUE),
    max = max(Value, na.rm = TRUE),
    mean = round(mean(Value, na.rm = TRUE), 2),
    sd = round(sd(Value, na.rm = TRUE), 2),
    .groups = "drop"
  )
  

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

***

We'll create a figure focusing on whether increased morality predicts rated intelligence.

```{r, fig.width=3, fig.height=3.5}
fill_color <- "#56B4E9"
line_color <- "#56B4E9"

model_df <- df_inc_morality %>%
  pivot_longer(
    cols = c(Pre_Intelligent, Post_Intelligent),
    names_to = "Time",
    values_to = "Rating"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent = "Pre",
                  Post_Intelligent = "Post"),
      Time = factor(Time, levels = c("Pre", "Post")),  # ensure correct order
    Outcome = "Intelligent"  # 
  )

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

  # Jittered raw data points
  geom_jitter(
    shape = 21,
    size = 2,
    stroke = 0.1,
    color = "gray80",
    alpha = 0.15,
    fill = fill_color,
    position = position_jitter(width = 0.35, height = 0.35)
  ) +

  # Summary line connecting group means
  stat_summary(
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    color = line_color,
    aes(group = 1)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    fill = fill_color,
    color = line_color,
    aes(group = 1)
  ) +

  # Axis labels and limits
  labs(
    title = "Perceived Intelligence\nAfter Morality Augmentation",
    x = "Time",
    y = "Perceived Intelligence"
  ) +
  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))
  )

plot_intelligence_from_morality
```

***

And we'll do the same for the comparison variable.

```{r, fig.width=3.5, fig.height=3.5}
fill_color <- "#56B4E9"
line_color <- "#56B4E9"

model_df <- df_inc_morality %>%
  pivot_longer(
    cols = c(Pre_Intelligent_Comparison, Post_Intelligent_Comparison),
    names_to = "Time",
    values_to = "Rating"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  "Pre_Intelligent_Comparison" = "Pre",
                  "Post_Intelligent_Comparison" = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")),
    Outcome = "Intelligent_Comparison"
  )

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

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

  # Summary line connecting group means
  stat_summary(
    fun = mean,
    geom = "line",
    linewidth = 1.2,
    color = line_color,
    aes(group = 1)
  ) +

  # Mean points with confidence intervals
  stat_summary(
    fun.data = mean_cl_normal,
    geom = "pointrange",
    shape = 21,
    size = 1.2,
    stroke = 1.2,
    fatten = 3,
    fill = fill_color,
    color = line_color,
    aes(group = 1)
  ) +

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

  # 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 = 5)),
    axis.title.x = element_blank(),
    plot.title = element_text(size = 12, hjust = 0.5, margin = margin(b = 10))
  )

plot_intelligence_from_morality_comparison
```


# Mixed Model (Time x Agent)

We then conduct a mixed model to explore whether the difference between pre- and post- judgments (i.e. before and after augmentation) is bigger when the agent increases in intelligence or increases in morality. We'll do this for all the variables.

## Trust

First we'll need to reshape the data.

```{r}
# Reshape to long format
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Trust, Post_Trust),
    names_to = "Time", # This is pre/post
    values_to = "Trust"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Trust = "Pre",
                  Post_Trust = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")) #ordered
  )
```

Due to the study design including only two measurements per participant (Pre/Post), random slopes for within-subject factors could not be estimated. As such, we fit models with random intercepts only, which is appropriate and identifiable given the data.

```{r}
# Fit the model
TrustModel_random_intercept <- lmer(
  Trust ~ Condition * Time + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(TrustModel_random_intercept, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      TRUE ~ term  # fallback
    ),
    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}
# Create Trust difference score
df <- df %>%
  mutate(Trust_Diff = Post_Trust - Pre_Trust)

# descriptives by condition
summary_trust_by_condition <- df %>%
  group_by(Condition) %>%
  summarise(
    min = min(Trust_Diff, na.rm = TRUE),
    max = max(Trust_Diff, na.rm = TRUE),
    mean = round(mean(Trust_Diff, na.rm = TRUE), 2),
    sd = round(sd(Trust_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(Variable = "Trust (Post - Pre)") %>%
  select(Variable, Condition, min, max, mean, sd)

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

***

## Danger

First we'll need to reshape the data.

```{r}
# Reshape to long format
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Danger, Post_Danger),
    names_to = "Time", # This is pre/post
    values_to = "Danger"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Danger = "Pre",
                  Post_Danger = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")) #ordered
  )
```

Due to the study design including only two measurements per participant (Pre/Post), random slopes for within-subject factors could not be estimated. As such, we fit models with random intercepts only, which is appropriate and identifiable given the data.

```{r}
# Fit the model
DangerModel_random_intercept <- lmer(
  Danger ~ Condition * Time + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(DangerModel_random_intercept, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      TRUE ~ term  # fallback
    ),
    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}
# Create Danger difference score
df <- df %>%
  mutate(Danger_Diff = Post_Danger - Pre_Danger)

# descriptives by condition
summary_danger_by_condition <- df %>%
  group_by(Condition) %>%
  summarise(
    min = min(Danger_Diff, na.rm = TRUE),
    max = max(Danger_Diff, na.rm = TRUE),
    mean = round(mean(Danger_Diff, na.rm = TRUE), 2),
    sd = round(sd(Danger_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(Variable = "Danger (Post - Pre)") %>%
  select(Variable, Condition, min, max, mean, sd)

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

***

## Intelligence

First we'll need to reshape the data.

```{r}
# Reshape to long format
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Intelligent, Post_Intelligent),
    names_to = "Time", # This is pre/post
    values_to = "Intelligent"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent = "Pre",
                  Post_Intelligent = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")) #ordered
  )
```

Due to the study design including only two measurements per participant (Pre/Post), random slopes for within-subject factors could not be estimated. As such, we fit models with random intercepts only, which is appropriate and identifiable given the data.

```{r}
# Fit the model
IntelligentModel_random_intercept <- lmer(
  Intelligent ~ Condition * Time + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(IntelligentModel_random_intercept, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      TRUE ~ term  # fallback
    ),
    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}
# Create Intelligent difference score
df <- df %>%
  mutate(Intelligent_Diff = Post_Intelligent - Pre_Intelligent)

# descriptives by condition
summary_intelligent_by_condition <- df %>%
  group_by(Condition) %>%
  summarise(
    min = min(Intelligent_Diff, na.rm = TRUE),
    max = max(Intelligent_Diff, na.rm = TRUE),
    mean = round(mean(Intelligent_Diff, na.rm = TRUE), 2),
    sd = round(sd(Intelligent_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(Variable = "Intelligent (Post - Pre)") %>%
  select(Variable, Condition, min, max, mean, sd)

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

***

## Intelligence Comparison

First we'll need to reshape the data.

```{r}
# Reshape to long format
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Intelligent_Comparison, Post_Intelligent_Comparison),
    names_to = "Time", # This is pre/post
    values_to = "Intelligent_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Intelligent_Comparison = "Pre",
                  Post_Intelligent_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")) #ordered
  )
```

Due to the study design including only two measurements per participant (Pre/Post), random slopes for within-subject factors could not be estimated. As such, we fit models with random intercepts only, which is appropriate and identifiable given the data.

```{r}
# Fit the model
Intelligent_Comparison_Model_random_intercept <- 
  lmer(Intelligent_Comparison ~ Condition * Time + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(Intelligent_Comparison_Model_random_intercept, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      TRUE ~ term  # fallback
    ),
    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}
# Create Intelligent difference score
df <- df %>%
  mutate(Intelligent_Comparison_Diff = Post_Intelligent_Comparison - Pre_Intelligent_Comparison)

# descriptives by condition
summary_intelligent_comparison_by_condition <- df %>%
  group_by(Condition) %>%
  summarise(
    min = min(Intelligent_Comparison_Diff, na.rm = TRUE),
    max = max(Intelligent_Comparison_Diff, na.rm = TRUE),
    mean = round(mean(Intelligent_Comparison_Diff, na.rm = TRUE), 2),
    sd = round(sd(Intelligent_Comparison_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(Variable = "Intelligent (Comparison) (Post - Pre)") %>%
  select(Variable, Condition, min, max, mean, sd)

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

***

## Morality

First we'll need to reshape the data.

```{r}
# Reshape to long format
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral, Post_Moral),
    names_to = "Time", # This is pre/post
    values_to = "Moral"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral = "Pre",
                  Post_Moral = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")) #ordered
  )
```

Due to the study design including only two measurements per participant (Pre/Post), random slopes for within-subject factors could not be estimated. As such, we fit models with random intercepts only, which is appropriate and identifiable given the data.

```{r}
# Fit the model
MoralModel_random_intercept <- lmer(
  Moral ~ Condition * Time + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(MoralModel_random_intercept, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      TRUE ~ term  # fallback
    ),
    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}
# Create Moral difference score
df <- df %>%
  mutate(Moral_Diff = Post_Moral - Pre_Moral)

# descriptives by condition
summary_moral_by_condition <- df %>%
  group_by(Condition) %>%
  summarise(
    min = min(Moral_Diff, na.rm = TRUE),
    max = max(Moral_Diff, na.rm = TRUE),
    mean = round(mean(Moral_Diff, na.rm = TRUE), 2),
    sd = round(sd(Moral_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(Variable = "Moral (Post - Pre)") %>%
  select(Variable, Condition, min, max, mean, sd)

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

***

## Morality Comparison

First we'll need to reshape the data.

```{r}
# Reshape to long format
long_df <- df %>%
  pivot_longer(
    cols = c(Pre_Moral_Comparison, Post_Moral_Comparison),
    names_to = "Time", # This is pre/post
    values_to = "Moral_Comparison"
  ) %>%
  mutate(
    Time = dplyr::recode(Time,
                  Pre_Moral_Comparison = "Pre",
                  Post_Moral_Comparison = "Post"),
    Time = factor(Time, levels = c("Pre", "Post")) #ordered
  )
```

Due to the study design including only two measurements per participant (Pre/Post), random slopes for within-subject factors could not be estimated. As such, we fit models with random intercepts only, which is appropriate and identifiable given the data.

```{r}
# Fit the model
Moral_Comparison_Model_random_intercept <- 
  lmer(Moral_Comparison ~ Condition * Time + 
    (1 | Participant),
  data = long_df,
  REML = FALSE
)

# Tidy and format results
formatted_table <- broom.mixed::tidy(Moral_Comparison_Model_random_intercept, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      TRUE ~ term  # fallback
    ),
    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}
# Create Moral difference score
df <- df %>%
  mutate(Moral_Comparison_Diff = Post_Moral_Comparison - Pre_Moral_Comparison)

# descriptives by condition
summary_moral_comparison_by_condition <- df %>%
  group_by(Condition) %>%
  summarise(
    min = min(Moral_Comparison_Diff, na.rm = TRUE),
    max = max(Moral_Comparison_Diff, na.rm = TRUE),
    mean = round(mean(Moral_Comparison_Diff, na.rm = TRUE), 2),
    sd = round(sd(Moral_Comparison_Diff, na.rm = TRUE), 2),
    .groups = "drop"
  ) %>%
  mutate(Variable = "Moral (Comparison) (Post - Pre)") %>%
  select(Variable, Condition, min, max, mean, sd)

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

***

# 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 overall 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(
      Condition == "Increased Intelligence" ~ Morality_Diff,
      Condition == "Increased Morality" ~ Intelligence_Diff
    )
  )

# conduct a linear model and get df
model_obj <- lm(Cross_Target_Diff ~ Condition, 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",
      TRUE ~ paste0("Condition [", str_replace(term, "Condition", ""), "]")
    ),
    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(Condition) %>%
  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(
    Condition = case_when(
      Condition == "Increased Intelligence" ~ "Increased Intelligence on Perceived Morality",
      Condition == "Increased Morality" ~ "Increased Morality on Perceived Intelligence",
      TRUE ~ Condition
    )
  )

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

***

We can also here combine the figures we created earlier.

```{r, message=FALSE}
# Combine
combined_int_morality_plot <- plot_morality_from_intelligence + plot_intelligence_from_morality +
  plot_layout(ncol = 2, guides = "collect")

# 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 2a Intelligence and Morality.png")), plot = combined_int_morality_plot,
       width = 6.5, height = 3.5, units = "in", dpi = 300)

combined_int_morality_plot

```


## Intelligence and Morality (Comparison)

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

```{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(
      Condition == "Increased Intelligence" ~ Morality_Diff,
      Condition == "Increased Morality" ~ Intelligence_Diff
    )
  )


# conduct a linear model and get df
model_obj <- lm(Cross_Target_Diff ~ Condition, 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",
      TRUE ~ paste0("Condition [", str_replace(term, "Condition", ""), "]")
    ),
    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(Condition) %>%
  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(
    Condition = case_when(
      Condition == "Increased Intelligence" ~ "Increased Intelligence on Perceived Morality (Comparison)",
      Condition == "Increased Morality" ~ "Increased Morality on Perceived Intelligence (Comparison)",
      TRUE ~ Condition
    )
  )

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

***

```{r, message=FALSE}
# Combine
combined_int_morality_comparison_plot <- plot_morality_from_intelligence_comparison + 
  plot_intelligence_from_morality_comparison +
  plot_layout(ncol = 2, guides = "collect")

# 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 2a Intelligence and Morality Comparison.png")), plot = combined_int_morality_comparison_plot,
       width = 7, height = 3.5, units = "in", dpi = 300)

combined_int_morality_comparison_plot

```

***

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

```

***

## Overall

We can look overall at correlations so we will report these, but also break down by conditions. To do this we need to combine the Pre- and Post- scores on intelligence and morality.

```{r}
df <- df %>%
  mutate(
    Combined_Intelligent = rowMeans(across(c(Pre_Intelligent, Post_Intelligent)), na.rm = TRUE),
    Combined_Moral = rowMeans(across(c(Pre_Moral, Post_Moral)), na.rm = TRUE),
    Combined_Intelligent_Comparison = rowMeans(across(c(Pre_Intelligent_Comparison, Post_Intelligent_Comparison)), na.rm = TRUE),
    Combined_Moral_Comparison = rowMeans(across(c(Pre_Moral_Comparison, Post_Moral_Comparison)), na.rm = TRUE),
  )
```

We then look at correlations.

```{r}
combined_intelligence_morality_corr <- jim.correlation(DV_A = df$Combined_Intelligent, DV_B = df$Combined_Moral, Item = "Overall Intelligence + Overall Morality")

combined_intelligence_morality_comparison_corr <- jim.correlation(DV_A = df$Combined_Intelligent_Comparison, DV_B = df$Combined_Moral_Comparison, Item = "Overall Intelligence + Overall Morality (Comparison)")

combined_overall <- rbind(combined_intelligence_morality_corr, combined_intelligence_morality_comparison_corr)

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

## Prior to Augmentation.

We first look at the correlation between baseline judgments of intelligence and morality prior to the augmentation. 

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

## 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_inc_intelligence$Post_Moral, 
                  DV_B = df_inc_intelligence$Post_Intelligent,
                  Item = "Increased Intelligence: Post Intelligence + Post Morality")

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

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

post_comparison_corr_increased_morality <- 
  jim.correlation(DV_A = df_inc_morality$Post_Moral_Comparison, 
                  DV_B = df_inc_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")
```

***

# Familiarity

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

## Intelligence 

We'll look first at intelligence.

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

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

# format the table
formatted_table <- broom.mixed::tidy(IntelligentModel_familiarity, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      term == "ConditionIncreased Intelligence:Familiarity_c" ~ "Interaction [Condition × Familiarity]",
      term == "TimePost:Familiarity_c" ~ "Interaction [Time × Familiarity]",
      term == "ConditionIncreased Intelligence:TimePost:Familiarity_c" ~ "Interaction [Condition × Time × Familiarity]",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

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

****

## Morality 

We'll then look at morality.

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

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

# format the table
formatted_table <- broom.mixed::tidy(MoralModel_familiarity, effects = "fixed") %>%
  mutate(
    Term = case_when(
      term == "(Intercept)" ~ "Intercept",
      term == "ConditionIncreased Intelligence" ~ "Condition [Increased Intelligence]",
      term == "TimePost" ~ "Time [Post]",
      term == "Familiarity_c" ~ "Familiarity (centered)",
      term == "ConditionIncreased Intelligence:TimePost" ~ "Interaction [Condition × Time]",
      term == "ConditionIncreased Intelligence:Familiarity_c" ~ "Interaction [Condition × Familiarity]",
      term == "TimePost:Familiarity_c" ~ "Interaction [Time × Familiarity]",
      term == "ConditionIncreased Intelligence:TimePost:Familiarity_c" ~ "Interaction [Condition × Time × Familiarity]",
      TRUE ~ term
    ),
    Estimate = round(estimate, 2),
    SE = round(std.error, 2),
    df = round(df, 1),
    t = round(statistic, 2),
    p = ifelse(
      is.na(p.value), NA,
      ifelse(p.value < .001, "< .001", paste0("= ", sub("^0", "", sprintf("%.3f", p.value))))
    )
  ) %>%
  select(Term, Estimate, SE, df, t, p)

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

***

We could also look just at baseline to see whether, independent of everything else, familarity predicts ratings of morality and intelligence at baseline.

***

First for morality at baseline.

```{r}
# conduct a linear model and get df
model_obj <- lm(Pre_Moral ~ Familiarity, data = df)
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",
      TRUE ~ paste0("Condition [", str_replace(term, "Condition", ""), "]")
    ),
    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"
  )
```

***

Second for intelligence at baseline.

```{r}
# conduct a linear model and get df
model_obj <- lm(Pre_Intelligent ~ Familiarity, data = df)
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",
      TRUE ~ paste0("Condition [", str_replace(term, "Condition", ""), "]")
    ),
    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"
  )
```