Arcturex/brca-navigator
0
1# ============================================================2# data_prep.R — Prepare all data for the interactive dashboard3# Run this ONCE in RStudio before launching the app4# ============================================================5 6results_dir <- "C:/Users/hp/Dev/playground/PO3/Results"7setwd("C:/Users/hp/Dev/playground/PO3")8 9library(dplyr)10library(survival)11library(MultiAssayExperiment)12 13cat("========== PREPARING DASHBOARD DATA ==========\n\n")14 15# 1. Load factor scores ---------------------------------16cat("1. Loading factor scores...\n")17factor_scores <- read.csv("Results/patient_factor_scores.csv", row.names = 1)18cat(" Loaded", nrow(factor_scores), "patients,", ncol(factor_scores), "factors\n")19 20# 2. Load clinical data from MAE ------------------------21cat("2. Loading clinical data from MAE...\n")22mae <- readRDS("Data/brca_mae.rds")23clinical <- as.data.frame(colData(mae))24cat(" Loaded", nrow(clinical), "clinical records\n")25 26# 3. Extract survival data ------------------------------27cat("3. Extracting survival data...\n")28os_time <- as.numeric(ifelse(29 clinical$Vital_Status_nature2012 == "DECEASED",30 clinical$Days_to_date_of_Death_nature2012,31 clinical$Days_to_Date_of_Last_Contact_nature201232))33os_event <- ifelse(clinical$Vital_Status_nature2012 == "DECEASED", 1, 0)34cat(" Deaths:", sum(os_event), "Censored:", sum(!os_event), "\n")35 36# 4. Merge scores + survival ----------------------------37cat("4. Merging factor scores with survival data...\n")38common_ids <- intersect(rownames(factor_scores), rownames(clinical))39cat(" Common patients:", length(common_ids), "\n")40 41patient_data <- factor_scores[common_ids, , drop = FALSE]42patient_data$os_time <- os_time[match(common_ids, rownames(clinical))]43patient_data$os_event <- os_event[match(common_ids, rownames(clinical))]44patient_data <- na.omit(patient_data)45cat(" After removing NAs:", nrow(patient_data), "patients\n")46 47# Also get PAM50 subtypes for coloring48pam50 <- clinical$PAM50Call_RNAseq[match(rownames(patient_data), rownames(clinical))]49patient_data$subtype <- as.character(pam50)50patient_data$subtype[is.na(patient_data$subtype) | patient_data$subtype == ""] <- "Unknown"51 52# Get age and stage for risk score model53patient_data$age <- as.numeric(clinical$Age_at_Initial_Pathologic_Diagnosis_nature2012)[match(rownames(patient_data), rownames(clinical))]54patient_data$stage <- clinical$AJCC_Stage_nature2012[match(rownames(patient_data), rownames(clinical))]55 56# 5. Fit multivariate Cox model for simulator -----------57cat("5. Fitting multivariate Cox model...\n")58factor_cols <- paste0("`", colnames(factor_scores), "`", collapse = " + ")59cox_formula <- as.formula(paste("Surv(os_time, os_event) ~", factor_cols))60cox_multi <- coxph(cox_formula, data = patient_data)61cat(" Model converged:", !any(is.na(coef(cox_multi))), "\n")62 63# 6. Baseline survival ----------------------------------64cat("6. Computing baseline survival curve...\n")65baseline_surv <- survfit(cox_multi)66baseline_df <- data.frame(67 time = baseline_surv$time,68 surv = baseline_surv$surv69)70cat(" Baseline curve has", nrow(baseline_df), "time points\n")71 72# 7. Create subtype-specific KM data for display --------73cat("7. Computing overall KM curve for reference...\n")74ref_km <- survfit(Surv(os_time, os_event) ~ 1, data = patient_data)75ref_km_df <- data.frame(76 time = ref_km$time,77 surv = ref_km$surv,78 upper = ref_km$upper,79 lower = ref_km$lower80)81 82# 8. Factor descriptions for the mind map ---------------83cat("8. Creating factor descriptions...\n")84factor_desc <- data.frame(85 factor = paste0("Factor", 1:15),86 top_genes = c(87 "GABRP, C4orf7, STAC2", "PTPRT, TUSC5, ATP1A2",88 "C8orf42, C3orf30, HTR2C", "TMEM179, ZNF692, BEX4",89 "PLA2G2D, SIRPG, TIGIT, ICOS, ZAP70", "IL6ST, GAS2L3, DDI2",90 "PPAPDC1A, COL10A1, EPYC, FN1", "CFB, ADRA2C, TTC22",91 "TFAP2B, CPNE7, GGT6", "C19orf20, COL7A1, WNT9A",92 "TBC1D1, EIF2AK2, MGA", "RPL13AP3, PPIAL4C, ZNF205",93 "TEX28, OR2T10, SNORA42", "SPNS1, DMXL2, NACA2",94 "RAB43, MTRF1L, C11orf10"95 ),96 category = c(97 rep("Luminal Biology", 2), rep("Methylation", 2),98 "Immune", rep("Proliferation", 2),99 rep("Risk Factors", 3), rep("Mixed", 3),100 rep("Undefined", 2)101 )102)103 104# 9. Save everything ------------------------------------105cat("9. Saving to dashboard_app/data/...\n")106dir.create("dashboard_app/data", recursive = TRUE, showWarnings = FALSE)107 108write.csv(patient_data, "dashboard_app/data/patient_data.csv", row.names = TRUE)109saveRDS(cox_multi, "dashboard_app/data/cox_multi.rds")110write.csv(baseline_df, "dashboard_app/data/baseline_survival.csv", row.names = FALSE)111write.csv(ref_km_df, "dashboard_app/data/reference_km.csv", row.names = FALSE)112write.csv(factor_desc, "dashboard_app/data/factor_descriptions.csv", row.names = FALSE)113 114# Copy result CSVs (skip any that don't exist)115result_files <- c(116 "factor_variance_summary.csv", "factor_variance_explained.csv",117 "rmst_per_factor.csv", "timeroc_auc.csv",118 "brca_rsf_importance.csv", "rsf_cindex.csv",119 "top_features_per_factor.csv", "factor_clinical_corrs.csv",120 "total_variance_explained.csv"121)122for (f in result_files) {123 src <- file.path("Results", f)124 if (file.exists(src)) {125 file.copy(src, "dashboard_app/data/", overwrite = TRUE)126 cat(" Copied:", f, "\n")127 } else {128 cat(" Skipped (not found):", f, "\n")129 }130}131 132# 10. Summary -------------------------------------------133cat("\n========== DONE ==========\n")134cat("Files saved to: dashboard_app/data/\n")135cat(" - patient_data.csv (", nrow(patient_data), "patients × ", ncol(patient_data), "columns)\n")136cat(" - cox_multi.rds (multivariate Cox model)\n")137cat(" - baseline_survival.csv (baseline survival curve)\n")138cat(" - reference_km.csv (overall KM curve)\n")139cat(" - factor_descriptions.csv (descriptions for mind map)\n")140cat(" + 9 result CSVs from analysis\n")141cat("\nNext step: Open app.R and click 'Run App' in RStudio!\n")142 