## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 5
)

## -----------------------------------------------------------------------------
library(dplyr)
library(vegan)
library(F2Adonis2)
library(kableExtra)
library(ggplot2)
library(combinat)

# Load package data objects explicitly
data("pkd_metadata", package = "F2Adonis2")
data("pkd_metabolites", package = "F2Adonis2")

set.seed(527)

# ==============================================================================
# 1. Sub-sample the PKD dataset (10 Ctrl / 20 PKD)
# ==============================================================================
sub_metadata <- bind_rows(
  pkd_metadata %>% filter(Group == "Ctrl") %>% slice_sample(n = 10),
  pkd_metadata %>% filter(Group == "PKD") %>% slice_sample(n = 20)
)
sub_metabolites <- pkd_metabolites[rownames(sub_metadata), ]
dist_sub <- vegdist(sub_metabolites, method = "euclidean")

# ==============================================================================
# 2. Dispersion diagnostics (betadisper)
# ==============================================================================
mod_sub <- betadisper(dist_sub, sub_metadata$Group)
anova_disp <- permutest(mod_sub, permutations = 99)
print(anova_disp)

# Spatial hull plot
plot(mod_sub, hull = TRUE, ellipse = FALSE,
     main = "Spatial Dispersion: Sub-sample (10 Ctrl / 20 PKD)")

# Violin + boxplot + jittered points of distance-to-centroid
distances_df <- data.frame(
  distance = mod_sub$distances,
  group = mod_sub$group
)

ggplot(distances_df, aes(x = group, y = distance, fill = group)) +
  geom_violin(alpha = 0.2, trim = TRUE, color = NA) +
  geom_boxplot(width = 0.2, alpha = 0.6, outlier.shape = NA) +
  geom_jitter(width = 0.1, size = 1.5, alpha = 0.5) +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "none",
    panel.grid.major.x = element_blank()
  ) +
  labs(
    title = "Dispersion Check: Sub-sampled Data",
    x = "Group",
    y = "Distance to Centroid"
  )

# ==============================================================================
# 3. F1 vs. F2 inference on the subsample
# ==============================================================================
pkd_fit_f1_sub <- adonis2(dist_sub ~ Group, data = sub_metadata,
                          method = "euclidean", permutations = 99)

pkd_fit_f2_sub <- F2_adonis2(dist_sub ~ Group, data = sub_metadata,
                             method = "euclidean", permutations = 99)

f1_p_sub <- pkd_fit_f1_sub["Model", "Pr(>F)"]
f2_p_sub <- pkd_fit_f2_sub["Model", "Pr(>F2)"]

sub_results <- data.frame(
  Sample_Size = "10 Ctrl / 20 PKD",
  F1_Pval = f1_p_sub,
  F2_Pval = f2_p_sub,
  Verdict = ifelse(f2_p_sub > 0.05 & f1_p_sub < 0.05, "Conflicted", "Consistent")
)

sub_results %>%
  mutate(
    F1_Pval = sprintf("%.4f%s", F1_Pval, ifelse(F1_Pval < 0.05, "*", "")),
    F2_Pval = sprintf("%.4f", F2_Pval)
  ) %>%
  kable(
    col.names = c(
      "Subsample Configuration",
      "Standard F1 ($p$)",
      "F2 ($p$)",
      "Verdict"
    ),
    escape = FALSE,
    caption = "Check: Subsampled PKD Analysis"
  ) %>%
  kable_styling(full_width = FALSE)

print(pkd_fit_f1_sub)
print(pkd_fit_f2_sub)

# F1 permutation null distribution
psub_f1 <- permustats(pkd_fit_f1_sub)
f1_plot_data <- data.frame(F_vals = as.numeric(psub_f1$permutations))
f1_obs_stat <- pkd_fit_f1_sub["Model", "F"]

ggplot(f1_plot_data, aes(x = F_vals)) +
  geom_histogram(bins = 30, fill = "darkgoldenrod", color = "white", alpha = 0.7) +
  geom_vline(xintercept = f1_obs_stat, color = "red", linewidth = 1.2, linetype = "dashed") +
  annotate("text", x = f1_obs_stat, y = Inf, label = paste("Observed F =", round(f1_obs_stat, 3)),
           vjust = 2, hjust = -0.1, color = "red", fontface = "bold") +
  theme_minimal() +
  labs(
    title = "F1 Null Distribution: PKD Subsample",
    x = "Permuted Pseudo-F Statistic",
    y = "Frequency"
  )

# ==============================================================================
# 4. PCA ordination and component-level decomposition
# ==============================================================================
pca_fit <- prcomp(sub_metabolites, scale. = TRUE)
pca_scores <- pca_fit$x[, 1:5]
comp_data <- data.frame(pca_scores, Group = sub_metadata$Group)
var_exp <- (pca_fit$sdev^2 / sum(pca_fit$sdev^2)) * 100

# PCA scores plot (PC1 vs PC2)
ggplot(comp_data, aes(x = PC1, y = PC2, color = Group, fill = Group)) +
  geom_point(size = 3, alpha = 0.6) +
  stat_ellipse(geom = "polygon", alpha = 0.2) +
  theme_minimal() +
  labs(title = "PCA Scores: Subsampled Data",
       subtitle = "Visualizing the overlap of group centroids",
       x = paste0("PC1 (", round(var_exp[1], 1), "%)"),
       y = paste0("PC2 (", round(var_exp[2], 1), "%)"))

# Univariate t-tests on the top 5 PCs
univariate_tests <- lapply(1:5, function(i) {
  test <- t.test(comp_data[[i]] ~ comp_data$Group)
  data.frame(Component = paste0("PC", i), P_Value = test$p.value)
})

do.call(rbind, univariate_tests) %>%
  mutate(P_Value = sprintf("%.4f%s", P_Value, ifelse(P_Value < 0.05, "*", ""))) %>%
  kable(caption = "Decomposition: Univariate Significance of Components",
        booktabs = TRUE) %>%
  kable_styling(latex_options = "hold_position")

# Pairwise F2 sensitivity analysis across all 2D PC planes
pc_pairs <- combn(1:5, 2)

pairwise_results <- lapply(1:ncol(pc_pairs), function(i) {
  pair_idx <- pc_pairs[, i]
  dist_pair <- dist(pca_scores[, pair_idx], method = "euclidean")
  
  fit <- F2_adonis2(dist_pair ~ Group, data = sub_metadata,
                    permutations = 99, bootstrap = FALSE, plot.dist = FALSE)
  
  data.frame(
    Pair = paste0("PC", pair_idx[1], " vs PC", pair_idx[2]),
    F2_Stat = fit["Model", "F2"],
    P_Value = fit["Model", "Pr(>F2)"]
  )
})

do.call(rbind, pairwise_results) %>%
  mutate(P_Value = sprintf("%.4f%s", P_Value, ifelse(P_Value < 0.05, "*", ""))) %>%
  kable(caption = "Pairwise Sensitivity Analysis: F2 on 2D PC Planes",
        booktabs = TRUE) %>%
  kable_styling(latex_options = "hold_position")

## ----pkd-subsample-full, eval = FALSE-----------------------------------------
# pkd_fit_f1_sub <- adonis2(dist_sub ~ Group, data = sub_metadata,
#                           method = "euclidean", permutations = 999)
# 
# pkd_fit_f2_sub <- F2_adonis2(dist_sub ~ Group, data = sub_metadata,
#                              method = "euclidean", permutations = 999)
# 
# pairwise_results_full <- lapply(1:ncol(pc_pairs), function(i) {
#   pair_idx <- pc_pairs[, i]
#   dist_pair <- dist(pca_scores[, pair_idx], method = "euclidean")
# 
#   fit <- F2_adonis2(dist_pair ~ Group, data = sub_metadata,
#                     permutations = 999, bootstrap = FALSE, plot.dist = FALSE)
# 
#   data.frame(
#     Pair = paste0("PC", pair_idx[1], " vs PC", pair_idx[2]),
#     F2_Stat = fit["Model", "F2"],
#     P_Value = fit["Model", "Pr(>F2)"]
#   )
# })
# 
# do.call(rbind, pairwise_results_full)

