## 04_label_sensitivity.R
## Exhaustive label-sensitivity enumeration (R/limma version)
## Input:  FPHL_final_miRNA_matrix.csv
## Output: label_sensitivity_summary.csv (S13), supplementary to S12

library(limma)

# ---- 1. Read normalised expression matrix ----
expr <- read.csv("../data/derived/FPHL_final_miRNA_matrix.csv",
                 row.names = 1, check.names = FALSE)

# ---- 2. All 56 possible 3-vs-5 partitions ----
samples <- colnames(expr)
n <- length(samples)
k <- 3  # FPHL group size

combinations <- combn(n, k)

results_list <- list()
for (i in seq_len(ncol(combinations))) {
  fphl_idx <- combinations[, i]
  group <- rep("Control", n)
  group[fphl_idx] <- "FPHL"
  group <- factor(group, levels = c("Control", "FPHL"))

  design <- model.matrix(~ group)
  fit <- lmFit(expr, design)
  fit <- eBayes(fit)

  de_tab <- topTable(fit, coef = "groupFPHL", number = Inf,
                     adjust.method = "BH")
  n_de <- sum(de_tab$adj.P.Val < 0.05 & abs(de_tab$logFC) > 1)

  results_list[[i]] <- data.frame(
    Partition = i,
    FPHL_Samples = paste(samples[fphl_idx], collapse = ";"),
    N_DE_miRNAs = n_de,
    stringsAsFactors = FALSE
  )
}

all_results <- do.call(rbind, results_list)

# ---- 3. Summary (S13 Table) ----
summary_df <- data.frame(
  Metric = c("Total partitions enumerated", "Observed partition N_DE",
             "Median across alternative partitions",
             "Maximum among alternative partitions",
             "Partitions with >= observed N_DE"),
  Value = c(ncol(combinations),
            all_results$N_DE[1],
            median(all_results$N_DE[-1]),
            max(all_results$N_DE[-1]),
            sum(all_results$N_DE[-1] >= all_results$N_DE[1])),
  stringsAsFactors = FALSE
)

write.csv(summary_df, "../data/derived/label_sensitivity_summary.csv",
          row.names = FALSE)

cat(sprintf("Partitions enumerated: %d\n", ncol(combinations)))
cat(sprintf("Observed partition DE count: %d\n", all_results$N_DE[1]))
cat(sprintf("Median alternative DE count: %d\n", median(all_results$N_DE[-1])))
