Rationale

(Write a paragraph summarizing the key points of the theory being applied in this data analysis)

(Write a paragraph explaining what the theory you just described would predict about the the variables in the data file you will be analyzing.)

Hypothesis

(Write a hypothesis describing the pattern you expect to see in the data you will be analyzing)

Variables & method

(Describe each variable used in the analysis, give its measurement level (categorical or continuous) and indicate which variable is being treated as the dependent variable, and which is being treated as the independent variable. This section also should indicate which statistical procedure the analysis used, and how)

Results & discussion

(Display any relevant figures or tables from the analysis, interpret the findings, and indicate whether the findings supported the hypothesis.)

# ============================================================
#  Setup: Install and Load Required Packages
# ============================================================
if (!require("tidyverse")) install.packages("tidyverse")
## Loading required package: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
if (!require("gt")) install.packages("gt")
## Loading required package: gt
if (!require("gtExtras")) install.packages("gtExtras")
## Loading required package: gtExtras
if (!require("FSA")) install.packages("FSA")
## Loading required package: FSA
## ## FSA v0.10.0. See citation('FSA') if used in publication.
## ## Run fishR() for related website and fishR('IFAR') for related book.
if (!require("plotly")) install.packages("plotly")
## Loading required package: plotly
## 
## Attaching package: 'plotly'
## 
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following object is masked from 'package:graphics':
## 
##     layout
library(tidyverse)
library(gt)
library(gtExtras)
library(FSA)
library(plotly)

options(scipen = 999) # suppress scientific notation

# ============================================================
#  Step 1: Load Data
# ============================================================
mydata <- read.csv("Priming.csv") # <-- Edit YOURFILENAME.csv

# Specify DV and IV (edit column names here)
mydata$DV <- mydata$Value
mydata$IV <- mydata$Group

# ============================================================
#  Step 2: Visualize Group Distributions (Interactive)
# ============================================================
# Compute group means
group_means <- mydata %>%
  group_by(IV) %>%
  summarise(mean_value = mean(DV), .groups = "drop")

# Interactive plot (boxplot + group means)
box_plot <- plot_ly() %>%
  # Boxplot trace
  add_trace(
    data = mydata,
    x = ~IV, y = ~DV,
    type = "box",
    boxpoints = "outliers",   # only applies here
    marker = list(color = "red", size = 4),  # outlier style
    line = list(color = "black"),
    fillcolor = "royalblue",
    name = ""
  ) %>%
  # Group means (diamonds)
  add_trace(
    data = group_means,
    x = ~IV, y = ~mean_value,
    type = "scatter", mode = "markers",
    marker = list(
      symbol = "diamond", size = 9,
      color = "black", line = list(color = "white", width = 1)
    ),
    text = ~paste0("Mean = ", round(mean_value, 2)),
    hoverinfo = "text",
    name = "Group Mean"
  ) %>%
  layout(
    title = "Interactive Group Distributions with Means",
    xaxis = list(title = "Independent Variable (IV)"),
    yaxis = list(title = "Dependent Variable (DV)"),
    showlegend = FALSE
  )

# ============================================================
#  Step 3: Descriptive Statistics by Group
# ============================================================
desc_stats <- mydata %>%
  group_by(IV) %>%
  summarise(
    count = n(),
    mean = mean(DV, na.rm = TRUE),
    sd   = sd(DV, na.rm = TRUE),
    min  = min(DV, na.rm = TRUE),
    max  = max(DV, na.rm = TRUE)
  )

desc_table <- desc_stats %>%
  mutate(across(where(is.numeric), ~round(.x, 2))) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Descriptive Statistics by Group")
## Table has no assigned ID, using random ID 'crhdzffcik' to apply `gt::opt_css()`
## Avoid this message by assigning an ID: `gt(id = '')` or `gt_theme_538(quiet = TRUE)`
# ============================================================
#  Step 4: Test Normality (Shapiro-Wilk)
# ============================================================
shapiro_results <- mydata %>%
  group_by(IV) %>%
  summarise(
    W_statistic = shapiro.test(DV)$statistic,
    p_value = shapiro.test(DV)$p.value
  )

shapiro_table <- shapiro_results %>%
  mutate(
    W_statistic = round(W_statistic, 2),
    p_value = ifelse(p_value < .001, "< .001", sprintf("%.3f", p_value))
  ) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Shapiro-Wilk Normality Test by Group") %>%
  tab_source_note(
    source_note = "Note. If any p-value figures are 0.05 or less, if one or more group distributions appear non-normal, and any group sizes are less than 40, consider using the Kruskal-Wallis and Post-hoc Dunn’s Test results instead of the ANOVA and Tukey HSD Post-hoc results."
  )
## Table has no assigned ID, using random ID 'zsswdmphvw' to apply `gt::opt_css()`
## Avoid this message by assigning an ID: `gt(id = '')` or `gt_theme_538(quiet = TRUE)`
# ============================================================
#  Step 5a: Non-Parametric Test (Kruskal-Wallis + Dunn)
# ============================================================
kruskal_res <- kruskal.test(DV ~ IV, data = mydata)

kruskal_table <- data.frame(
  Statistic = round(kruskal_res$statistic, 2),
  df = kruskal_res$parameter,
  p_value = ifelse(kruskal_res$p.value < .001, "< .001",
                   sprintf("%.3f", kruskal_res$p.value))
) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Kruskal-Wallis Test Results")
## Table has no assigned ID, using random ID 'zpbgfbchmk' to apply `gt::opt_css()`
## Avoid this message by assigning an ID: `gt(id = '')` or `gt_theme_538(quiet = TRUE)`
dunn_res <- dunnTest(DV ~ IV, data = mydata, method = "bonferroni")$res
## Warning: IV was coerced to a factor.
dunn_table <- dunn_res %>%
  mutate(
    Z = round(Z, 2),
    P.unadj = ifelse(P.unadj < .001, "< .001", sprintf("%.3f", P.unadj)),
    P.adj   = ifelse(P.adj < .001, "< .001", sprintf("%.3f", P.adj))
  ) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Post-hoc Dunn’s Test Results")
## Table has no assigned ID, using random ID 'nlailzakwn' to apply `gt::opt_css()`
## Avoid this message by assigning an ID: `gt(id = '')` or `gt_theme_538(quiet = TRUE)`
# ============================================================
#  Step 5b: Parametric Test (ANOVA + Tukey)
# ============================================================
anova_res <- oneway.test(DV ~ IV, data = mydata, var.equal = FALSE)

anova_table <- data.frame(
  Statistic = round(anova_res$statistic, 2),
  df = anova_res$parameter[1],
  df_resid = anova_res$parameter[2],
  p_value = ifelse(anova_res$p.value < .001, "< .001",
                   sprintf("%.3f", anova_res$p.value))
) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "ANOVA Test Results")
## Table has no assigned ID, using random ID 'powrgfnmql' to apply `gt::opt_css()`
## Avoid this message by assigning an ID: `gt(id = '')` or `gt_theme_538(quiet = TRUE)`
anova_model <- aov(DV ~ IV, data = mydata)
tukey_res <- TukeyHSD(anova_model)$IV %>% as.data.frame()

tukey_table <- tukey_res %>%
  rownames_to_column("Comparison") %>%
  mutate(
    diff = round(diff, 2),
    lwr = round(lwr, 2),
    upr = round(upr, 2),
    `p adj` = ifelse(`p adj` < .001, "< .001", sprintf("%.3f", `p adj`))
  ) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Tukey HSD Post-hoc Results")
## Table has no assigned ID, using random ID 'vaesdvicto' to apply `gt::opt_css()`
## Avoid this message by assigning an ID: `gt(id = '')` or `gt_theme_538(quiet = TRUE)`
# ============================================================
#  Step 6: Display Key Results
# ============================================================
# Interactive box plot
box_plot
# Tables
desc_table
Descriptive Statistics by Group
IV count mean sd min max
Art project 45 4.96 1.04 2.3 7.3
Nonviolent game 45 5.86 1.06 3.6 8.4
Violent game 45 10.75 1.00 8.5 12.8
shapiro_table
Shapiro-Wilk Normality Test by Group
IV W_statistic p_value
Art project 0.99 0.923
Nonviolent game 0.98 0.594
Violent game 0.98 0.699
Note. If any p-value figures are 0.05 or less, if one or more group distributions appear non-normal, and any group sizes are less than 40, consider using the Kruskal-Wallis and Post-hoc Dunn’s Test results instead of the ANOVA and Tukey HSD Post-hoc results.
anova_table
ANOVA Test Results
Statistic df df_resid p_value
420.86 2 87.94717 < .001
tukey_table
Tukey HSD Post-hoc Results
Comparison diff lwr upr p adj
Nonviolent game-Art project 0.90 0.38 1.42 < .001
Violent game-Art project 5.79 5.27 6.30 < .001
Violent game-Nonviolent game 4.89 4.37 5.40 < .001
kruskal_table
Kruskal-Wallis Test Results
Statistic df p_value
95.23 2 < .001
dunn_table
Post-hoc Dunn’s Test Results
Comparison Z P.unadj P.adj
Art project - Nonviolent game -2.42 0.016 0.047
Art project - Violent game -9.40 < .001 < .001
Nonviolent game - Violent game -6.98 < .001 < .001

Code:

# ============================================================
#  Setup: Install and Load Required Packages
# ============================================================
if (!require("tidyverse")) install.packages("tidyverse")
if (!require("gt")) install.packages("gt")
if (!require("gtExtras")) install.packages("gtExtras")
if (!require("FSA")) install.packages("FSA")
if (!require("plotly")) install.packages("plotly")

library(tidyverse)
library(gt)
library(gtExtras)
library(FSA)
library(plotly)

options(scipen = 999) # suppress scientific notation

# ============================================================
#  Step 1: Load Data
# ============================================================
mydata <- read.csv("Priming.csv") # <-- Edit YOURFILENAME.csv

# Specify DV and IV (edit column names here)
mydata$DV <- mydata$Group
mydata$IV <- mydata$Value

# ============================================================
#  Step 2: Visualize Group Distributions (Interactive)
# ============================================================
# Compute group means
group_means <- mydata %>%
  group_by(IV) %>%
  summarise(mean_value = mean(DV), .groups = "drop")

# Interactive plot (boxplot + group means)
box_plot <- plot_ly() %>%
  # Boxplot trace
  add_trace(
    data = mydata,
    x = ~IV, y = ~DV,
    type = "box",
    boxpoints = "outliers",   # only applies here
    marker = list(color = "red", size = 4),  # outlier style
    line = list(color = "black"),
    fillcolor = "royalblue",
    name = ""
  ) %>%
  # Group means (diamonds)
  add_trace(
    data = group_means,
    x = ~IV, y = ~mean_value,
    type = "scatter", mode = "markers",
    marker = list(
      symbol = "diamond", size = 9,
      color = "black", line = list(color = "white", width = 1)
    ),
    text = ~paste0("Mean = ", round(mean_value, 2)),
    hoverinfo = "text",
    name = "Group Mean"
  ) %>%
  layout(
    title = "Interactive Group Distributions with Means",
    xaxis = list(title = "Independent Variable (IV)"),
    yaxis = list(title = "Dependent Variable (DV)"),
    showlegend = FALSE
  )

# ============================================================
#  Step 3: Descriptive Statistics by Group
# ============================================================
desc_stats <- mydata %>%
  group_by(IV) %>%
  summarise(
    count = n(),
    mean = mean(DV, na.rm = TRUE),
    sd   = sd(DV, na.rm = TRUE),
    min  = min(DV, na.rm = TRUE),
    max  = max(DV, na.rm = TRUE)
  )

desc_table <- desc_stats %>%
  mutate(across(where(is.numeric), ~round(.x, 2))) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Descriptive Statistics by Group")

# ============================================================
#  Step 4: Test Normality (Shapiro-Wilk)
# ============================================================
shapiro_results <- mydata %>%
  group_by(IV) %>%
  summarise(
    W_statistic = shapiro.test(DV)$statistic,
    p_value = shapiro.test(DV)$p.value
  )

shapiro_table <- shapiro_results %>%
  mutate(
    W_statistic = round(W_statistic, 2),
    p_value = ifelse(p_value < .001, "< .001", sprintf("%.3f", p_value))
  ) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Shapiro-Wilk Normality Test by Group") %>%
  tab_source_note(
    source_note = "Note. If any p-value figures are 0.05 or less, if one or more group distributions appear non-normal, and any group sizes are less than 40, consider using the Kruskal-Wallis and Post-hoc Dunn’s Test results instead of the ANOVA and Tukey HSD Post-hoc results."
  )

# ============================================================
#  Step 5a: Non-Parametric Test (Kruskal-Wallis + Dunn)
# ============================================================
kruskal_res <- kruskal.test(DV ~ IV, data = mydata)

kruskal_table <- data.frame(
  Statistic = round(kruskal_res$statistic, 2),
  df = kruskal_res$parameter,
  p_value = ifelse(kruskal_res$p.value < .001, "< .001",
                   sprintf("%.3f", kruskal_res$p.value))
) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Kruskal-Wallis Test Results")

dunn_res <- dunnTest(DV ~ IV, data = mydata, method = "bonferroni")$res

dunn_table <- dunn_res %>%
  mutate(
    Z = round(Z, 2),
    P.unadj = ifelse(P.unadj < .001, "< .001", sprintf("%.3f", P.unadj)),
    P.adj   = ifelse(P.adj < .001, "< .001", sprintf("%.3f", P.adj))
  ) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Post-hoc Dunn’s Test Results")

# ============================================================
#  Step 5b: Parametric Test (ANOVA + Tukey)
# ============================================================
anova_res <- oneway.test(DV ~ IV, data = mydata, var.equal = FALSE)

anova_table <- data.frame(
  Statistic = round(anova_res$statistic, 2),
  df = anova_res$parameter[1],
  df_resid = anova_res$parameter[2],
  p_value = ifelse(anova_res$p.value < .001, "< .001",
                   sprintf("%.3f", anova_res$p.value))
) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "ANOVA Test Results")

anova_model <- aov(DV ~ IV, data = mydata)
tukey_res <- TukeyHSD(anova_model)$IV %>% as.data.frame()

tukey_table <- tukey_res %>%
  rownames_to_column("Comparison") %>%
  mutate(
    diff = round(diff, 2),
    lwr = round(lwr, 2),
    upr = round(upr, 2),
    `p adj` = ifelse(`p adj` < .001, "< .001", sprintf("%.3f", `p adj`))
  ) %>%
  gt() %>%
  gt_theme_538() %>%
  tab_header(title = "Tukey HSD Post-hoc Results")

# ============================================================
#  Step 6: Display Key Results
# ============================================================
# Interactive box plot
box_plot

# Tables
desc_table
shapiro_table
anova_table
tukey_table
kruskal_table
dunn_table