This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
library(readxl)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ 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
library(ggplot2)
library(lme4)
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
##
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
library(rstatix)
##
## Attaching package: 'rstatix'
##
## The following object is masked from 'package:stats':
##
## filter
library(ggpubr)
df <- read_excel("TPDT.xlsx")
## New names:
## • `` -> `...16`
df
df_long <- df %>%
pivot_longer(
cols = 7:11, # these are the trial columns
names_to = "Trial",
values_to = "Measurement"
) %>%
mutate(
Trial = as.integer(Trial) # Convert trial number to numeric
) %>%
select(ID, Location, Pregnant, Trial, Measurement) # Keep relevant columns
df_long %>%
group_by(Location, Pregnant) %>%
summarise(
n = sum(!is.na(Measurement)),
mean = mean(Measurement, na.rm = TRUE),
sd = sd(Measurement, na.rm = TRUE),
median = median(Measurement, na.rm = TRUE),
min = min(Measurement, na.rm = TRUE),
max = max(Measurement, na.rm = TRUE)
)
## `summarise()` has grouped output by 'Location'. You can override using the
## `.groups` argument.
df_long %>% #group by participant
group_by(ID, Location) %>%
summarise(
trials_completed = sum(!is.na(Measurement)),
mean = mean(Measurement, na.rm = TRUE),
sd = sd(Measurement, na.rm = TRUE)
)
## `summarise()` has grouped output by 'ID'. You can override using the `.groups`
## argument.
df_long$Pregnant <- factor(df_long$Pregnant,
levels = c(0, 1),
labels = c("Not Pregnant", "Pregnant"))
df_long %>%
distinct(ID, Pregnant) %>% # remove duplicate rows per participant
count(Pregnant) # count participants per group
threshold_summary <- df_long %>%
filter(!is.na(Measurement), !Trial >=4) %>% # Exclude missing trials and trials above 3
group_by(ID, Pregnant, Location) %>%
summarise(
n_trials = n(),
mean_threshold = mean(Measurement),
median_threshold = median(Measurement),
.groups = "drop"
)
# View the result
print(threshold_summary)
## # A tibble: 92 × 6
## ID Pregnant Location n_trials mean_threshold median_threshold
## <dbl> <fct> <chr> <int> <dbl> <dbl>
## 1 1 Pregnant Abdomen 3 46.3 50
## 2 1 Pregnant Forearm 3 38.3 40
## 3 3 Pregnant Abdomen 3 32.7 32
## 4 3 Pregnant Forearm 3 15.3 15
## 5 4 Pregnant Abdomen 3 33.7 34
## 6 4 Pregnant Forearm 3 34 35
## 7 6 Pregnant Abdomen 3 31.7 30
## 8 6 Pregnant Forearm 2 31.5 31.5
## 9 8 Pregnant Abdomen 3 36.3 34
## 10 8 Pregnant Forearm 2 57 57
## # ℹ 82 more rows
threshold_forearm <- threshold_summary %>%
filter(Location == "Forearm")
threshold_abdomen <- threshold_summary %>%
filter(Location == "Abdomen")
# Scatter plot: Mean threshold by participant and location
ggplot(threshold_forearm) +
aes(x = factor(Pregnant), y = mean_threshold, color = Pregnant) +
geom_jitter() +
labs(
title = "Mean Two-Point Discrimination Threshold - Forearm",
x = "Pregnancy status",
y = "Mean Threshold (mm)"
) +
theme(legend.position = "none")
# Scatter plot: Mean threshold by participant and location
ggplot(threshold_abdomen) +
aes(x = factor(Pregnant), y = mean_threshold, color = Pregnant) +
geom_jitter() +
labs(
title = "Mean Two-Point Discrimination Threshold - Abdomen",
x = "Pregnancy status",
y = "Mean Threshold (mm)"
) +
theme(legend.position = "none")
# Outliers
threshold_summary %>%
group_by(Location, Pregnant) %>%
identify_outliers(mean_threshold) #no extreme values
# Normality
threshold_summary %>%
group_by(Location, Pregnant) %>%
shapiro_test(mean_threshold) #can assume normality if P > 0.05 for each cell
ggqqplot(threshold_summary, "mean_threshold", ggtheme = theme_bw()) +
facet_grid(Location ~ Pregnant)
Note on Outliers - Values above Q3 + 1.5xIQR or below Q1 - 1.5xIQR are considered as outliers. Values above Q3 + 3xIQR or below Q1 - 3xIQR are considered as extreme points (or extreme outliers).
anova_results <- threshold_summary %>%
anova_test(dv = mean_threshold, wid = ID, within = Location, between = Pregnant) # Two-way mixed ANOVA
get_anova_table(anova_results)
## Post-hoc tests
# Simple main effect of group variable
# Effect of group at each location
one.way <- threshold_summary %>%
group_by(Location) %>%
anova_test(dv = mean_threshold, wid = ID, between = Pregnant) %>%
get_anova_table() %>%
adjust_pvalue(method = "bonferroni")
one.way
# Pairwise comparison between group levels
between_pwc <- threshold_summary %>%
group_by(Location) %>%
pairwise_t_test(mean_threshold ~ Pregnant, paired = FALSE, p.adjust.method = "bonferroni")
between_pwc
# Simple main effect of location variable
# Effect of location for each group
one.way2 <- threshold_summary %>%
group_by(Pregnant) %>%
anova_test(dv = mean_threshold, wid = ID, between = Location) %>%
get_anova_table() %>%
adjust_pvalue(method = "bonferroni")
## Warning: There were 2 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `data = map(.data$data, .f, ...)`.
## Caused by warning:
## ! The 'wid' column contains duplicate ids across between-subjects variables. Automatic unique id will be created
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 1 remaining warning.
one.way2
# Pairwise comparison between locations at each group level
within_pwc <- threshold_summary %>%
group_by(Pregnant) %>%
pairwise_t_test(mean_threshold ~ Location, paired = TRUE, p.adjust.method = "bonferroni")
within_pwc
threshold_summary %>%
group_by(Pregnant, Location) %>%
summarise(mean = mean(mean_threshold), se = sd(mean_threshold)/sqrt(n())) %>%
ggplot(aes(x = Location, y = mean, color = Pregnant, group = Pregnant)) +
geom_line() +
geom_point() +
geom_errorbar(aes(ymin = mean - se, ymax = mean + se), width = 0.2) +
labs(
title = "Two Point Discrimination Test - Inteaction Plot",
x = "Location",
y = "Mean Threshold (mm)"
) +
theme_minimal()
## `summarise()` has grouped output by 'Pregnant'. You can override using the
## `.groups` argument.
When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.