OSCR

Identification of suicide brain transcriptomic signatures using meta-analysis of multiple cohorts.

Code ↔ Paper

23 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 23 matches
  1. [1] § Materials and methods › Differential expression analysis in the primary cohorts ↔ Cell_expression_imputation_analysis.R, lines 1713 to 1777 · score 0.87 · filterByExpr, DGEList, lmFit, topTable, eBayes, design matrix · Report a mismatch
  2. [2] § Results › Gene set enrichment analysis and classification ↔ AI_gene_classification.ipynb, lines 72 to 96 · score 0.83 · secreted molecules, immune receptors, structural proteins, transcription factors, enzymes, kinase · Report a mismatch
  3. [3] § Results › Generation of datasets ↔ Moderator_calculation.R, lines 79 to 160 · score 0.79 · GSE92538_U133A, GSE92538_U133_PLUS2, dorsolateral prefrontal cortex, brain regions, sex, GSE248260 · Report a mismatch
  4. [4] § Materials and methods › Probe and transcript mapping to gene symbols ↔ Data_preprocessing_analysis/TRANSCRIPT_SUICIDE_PREPR_ANALYSIS_SCRIPT.R, lines 667 to 709 · score 0.77 · BioMart, probe IDs, map probes, gene symbols, Ensembl, Python · Report a mismatch
  5. [5] § Results › Generation of datasets ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 2338 to 2373 · score 0.74 · GSE92538_U133A, GSE92538_U133_PLUS2, Single cell, prefrontal cortex, GSE248260, GSE199536 · Report a mismatch
  6. [6] § Materials and methods › Cohort identification ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 1656 to 1699 · score 0.74 · genome tiling, MeSH, Expression profiling, Fields, Organism, human · Report a mismatch
  7. [7] § Results › Generation of datasets ↔ Data_preprocessing_analysis/DEMOGRAPHICS_TRANSCRIPT_SCRIPT.R, lines 1193 to 1223 · score 0.73 · aINS, insula, BA11, Cg25, OFC, gyrus · Report a mismatch
  8. [8] § Results › Generation of datasets ↔ Data_preprocessing_analysis/TRANSCRIPT_SUICIDE_PREPR_ANALYSIS_SCRIPT.R, lines 3165 to 3210 · score 0.73 · aINS, insula, BA11, Cg25, OFC, gyrus · Report a mismatch
  9. [9] § Results › Random effects meta-analyses ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 2436 to 2503 · score 0.72 · AC159540.14, CX3CR1, P2RY12, FOS, DEPP1, KLF4 · Report a mismatch
  10. [10] § Results › Sensitivity and moderator analyses ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 2436 to 2503 · score 0.71 · AC159540.14, CX3CR1, P2RY12, DEPP1, KLF4, SOX9 · Report a mismatch
  11. [11] § Results › Cell deconvolution analysis and cell-specific meta-analysis ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 2145 to 2192 · score 0.69 · precursor cells, excitatory neurons, mixed expression, oligodendrocytes, suicide, meta · Report a mismatch
  12. [12] § Results › Generation of datasets ↔ Data_preprocessing_analysis/DEMOGRAPHICS_TRANSCRIPT_SCRIPT.R, lines 995 to 1047 · score 0.65 · major depressive disorder, bipolar disorder, GSE92538 U133A, schizophrenia, diagnoses, DLPFC · Report a mismatch
  13. [13] § Results › Generation of datasets ↔ Moderator_calculation.R, lines 270 to 312 · score 0.64 · major depressive disorder, bipolar disorder, GSE92538 U133A, schizophrenia, GSE5388, GSE208338 · Report a mismatch
  14. [14] § Results › Comparison of brain meta-analysis with blood transcriptome and PSY proteome ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 1510 to 1562 · score 0.63 · PLA2G10, AKT1S1, CCL27, RBKS, antidepressant, PSY · Report a mismatch
  15. [15] § Materials and methods › Cohort identification ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 1745 to 1789 · score 0.62 · MeSH, Expression profiling, Fields, sequencing, Organism, human · Report a mismatch
  16. [16] § Results › Differential expression analysis in the individual cohorts ↔ Moderator_calculation.R, lines 79 to 160 · score 0.62 · nucleus accumbens, GSE92538_U133_PLUS2, dorsolateral prefrontal cortex, GSE202537, GSE144136, GSE213982 · Report a mismatch
  17. [17] § Materials and methods › Cohort identification ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 2338 to 2373 · score 0.61 · GSE92538 U133A, GSE248260, GSE199536, PSY, GSE247998, GSE101521 · Report a mismatch
  18. [18] § Materials and methods › Meta-analysis of differential expression changes ↔ Cell_expression_imputation_analysis.R, lines 2290 to 2369 · score 0.57 · p.adjust, rma.uni, Weights, SE, FDR, model · Report a mismatch
  19. [19] § Materials and methods › Cell deconvolution meta-analysis ↔ Cell_expression_imputation_analysis.R, lines 775 to 818 · score 0.54 · sampled signature matrix, single cell, bulk, CIBERSORTx, GSE144136, GSE213982 · Report a mismatch
  20. [20] § Materials and methods › Bulk RNAseq data preprocessing ↔ Data_preprocessing_analysis/TRANSCRIPT_SUICIDE_PREPR_ANALYSIS_SCRIPT.R, lines 3873 to 3935 · score 0.53 · FastQC, SRA, conda, tools, preprocessed, STAR · Report a mismatch
  21. [21] § Materials and methods › Cohort identification ↔ Moderator_calculation.R, lines 314 to 361 · score 0.53 · major depressive disorder, psychiatric diagnoses, suicide · Report a mismatch
  22. [22] § Materials and methods › Meta-analysis of differential expression changes ↔ OLINK_PSY_SUICIDE_SCRIPT.R, lines 675 to 718 · score 0.52 · rma.uni, Log2FC, Weights, SE, model, meta · Report a mismatch
  23. [23] § Materials and methods › Meta-analysis of differential expression changes ↔ Data_preprocessing_analysis/TRANSCRIPT_SUICIDE_PREPR_ANALYSIS_SCRIPT.R, lines 4204 to 4256 · score 0.50 · causal pathway, status, depression, diagnosis, phenotypes, variables · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

R · 4,359 lines · 195 KB · GPL-3.0 · 9 matches

  1. # The script is intended viewed in R studio
  2. # Blocks are titled
  3. # "=" symbol was used as an assignment operator
  4. # Data processing and DE in initial cohorts is located in another file "Data_preprocessing_analysis/TRANSCRIPT_SUICIDE_PREPR_ANALYSIS_SCRIPT.R"
  5. # Calculation of cohort-level moderators is located in "Moderator_calculation.R"
  6. # Cell expression deconvolution tests are located in "Cell_expression_imputation_tests.R"
  7. # Cell expression deconvolution final runs and analysis are located in "Cell_expression_imputation_analysis.R"
  8. setwd("/home/aleksandr/Desktop/WORK/OLINK_suicide_PSY_project")
  9. # Setting options
  10. getOption("scipen") # Default number notation is 0
  11. options(scipen=999)
  12. options(stringsAsFactors = FALSE)
  13. options(show.error.messages = TRUE)
  14. ################### Package import ###################
  15. library(R.utils)
  16. library(fun)
  17. library(stringr)
  18. library(dplyr)
  19. library(ggplot2)
  20. library(openxlsx)
  21. library(grid)
  22. library(gdata)
  23. library(RColorBrewer)
  24. library(networkD3)
  25. library(webshot)
  26. library(htmlwidgets)
  27. library(magrittr)
  28. library(igraph)
  29. library(visNetwork)
  30. library(data.table)
  31. library(XML)
  32. library(rvest)
  33. library(RCurl)
  34. library(HGNChelper)
  35. library(stringi)
  36. library(httr)
  37. library(lubridate)
  38. library(rjson)
  39. library(rtracklayer)
  40. library(rstudioapi)
  41. library(tidyr)
  42. library(Gviz)
  43. library(limma)
  44. library(FactoMineR)
  45. library(ggthemes)
  46. library(igraph)
  47. library(RSelenium)
  48. library(lumi)
  49. library(outliers)
  50. library(svglite)
  51. library(scatterplot3d)
  52. library(sva)
  53. library(jsonlite)
  54. library(ggrepel)
  55. library(parallel)
  56. library(bacon)
  57. library(gridExtra)
  58. library(ggplotify)
  59. library(HGNChelper)
  60. library(jetset)
  61. library(GEOquery)
  62. library(clusterProfiler)
  63. library(DOSE)
  64. library(enrichplot)
  65. library(chromoMap)
  66. library(RIdeogram)
  67. library(ggVennDiagram)
  68. library(seqinr)
  69. library(Biostrings)
  70. library(dbparser)
  71. library(LDlinkR)
  72. library(parallel)
  73. library(HardyWeinberg)
  74. library(sva)
  75. library(MatrixEQTL)
  76. library(MASS)
  77. library(metafor)
  78. library(AnnotationDbi)
  79. library(org.Hs.eg.db)
  80. library(RobustRankAggreg)
  81. ################### Defining basic functions ###################
  82. # NOT IN operator
  83. '%!in%' = function(x,y){!('%in%'(x,y))}
  84. # A function to convert list to data frame
  85. list_to_df = function(data_list){
  86. if (length(data_list) > 1){
  87. data_list = do.call(rbind, data_list)
  88. } else {
  89. data_list = data_list[[1]]
  90. }
  91. return(data_list)
  92. }
  93. # A function to replace multiple patterns by multiple replacements in a string
  94. multiple_stri_replacer = function(string, pattern_vector, replacement_vector){
  95. # Pattern_vector and replacement_vector should have the same length
  96. for (i in 1:length(pattern_vector)){
  97. string = stri_replace_all_fixed(str = string, pattern = pattern_vector[i], replacement = replacement_vector[i])
  98. }
  99. return(string)
  100. }
  101. # A function to read text files fast; uses data.table::fread
  102. smart_fread = function(x, ...){
  103. x = as.data.frame(fread(x, nThread = 10, ...))
  104. if ("V1" %in% colnames(x)){
  105. rownames(x) = x$V1
  106. x$V1 = NULL
  107. }
  108. return(x)
  109. }
  110. # A function to detect at least one pattern in a string
  111. multiple_stri_detector = function(string, pattern_vector){
  112. output_list = list()
  113. for (i in 1:length(pattern_vector)){
  114. output_list[[i]] = stri_detect_fixed(str = string, pattern = pattern_vector[i])
  115. }
  116. output_list = do.call(rbind, output_list)
  117. apply(output_list, 2, any)
  118. }
  119. # A function to expand a data frame where several columns contain condensed cells with a specified separator
  120. multiple_expander = function(df, cols_to_expand, pattern){
  121. #
  122. orig_colnames = colnames(df)
  123. df_modif = df[, cols_to_expand, drop = FALSE]
  124. df_const = df[,-cols_to_expand, drop = FALSE]
  125. orig_colnames_modif = colnames(df_modif)
  126. # Running expansion
  127. df_list = list()
  128. for (i in 1:nrow(df_const)){
  129. print(i)
  130. curr_df_const = df_const[i,, drop = FALSE]
  131. curr_df_modif = df_modif[i,, drop = FALSE]
  132. curr_df_modif = apply(curr_df_modif, 2, function(x) unlist(stri_split_fixed(x, pattern = pattern)), simplify = FALSE)
  133. if (length(cols_to_expand) > 1){
  134. curr_df_modif = do.call(cbind, curr_df_modif)
  135. } else {
  136. curr_df_modif = unlist(curr_df_modif)
  137. }
  138. if (is.matrix(curr_df_modif)){
  139. for (b in 1:nrow(curr_df_modif)){
  140. curr_df_const[b, ] = curr_df_const[1, ]
  141. }
  142. } else {
  143. for (b in 1:length(curr_df_modif)){
  144. curr_df_const[b, ] = curr_df_const[1, ]
  145. }
  146. }
  147. curr_df_combined = cbind(curr_df_const, curr_df_modif)
  148. if (length(cols_to_expand) == 1){
  149. colnames(curr_df_combined)[ncol(curr_df_combined)] = orig_colnames[cols_to_expand]
  150. }
  151. df_list[[i]] = curr_df_combined
  152. }
  153. if (length(df_list) > 1){
  154. df_list = do.call(rbind, df_list)
  155. } else {
  156. df_list = df_list[[1]]
  157. }
  158. df_list = df_list[, orig_colnames]
  159. return(df_list)
  160. }
  161. # A function to check gene symbols
  162. # Importing NIH dataset
  163. Homo_Sapiens_Gene_info_NIH = smart_fread("/home/aleksandr/Desktop/WORK/UCSC_ID_MAP/Homo_sapiens.gene_info")
  164. # https://ftp.ncbi.nih.gov/gene/DATA/GENE_INFO/Mammalia/ (replace with an appropriate path)
  165. Homo_Sapiens_Gene_info_NIH_expanded = multiple_expander(df = Homo_Sapiens_Gene_info_NIH, cols_to_expand = 5, pattern = "|")
  166. check_gene_symbol_NIH = function(PRF_gene_symbols, PRF_ref_NIH_expanded, PRF_replace_NA_with_old = FALSE){
  167. PRF_gene_symbols_check = lapply(PRF_gene_symbols, function(x){
  168. if (x %in% PRF_ref_NIH_expanded$Symbol_from_nomenclature_authority){
  169. Curr_gene = x
  170. Approved = TRUE
  171. Suggested.Symbol = x
  172. } else if (x %in% PRF_ref_NIH_expanded$Symbol){
  173. RRF_df = PRF_ref_NIH_expanded[PRF_ref_NIH_expanded$Symbol == x,]
  174. Curr_gene = x
  175. Approved = FALSE
  176. Suggested.Symbol = RRF_df[,"Symbol_from_nomenclature_authority"]
  177. Suggested.Symbol = unique(Suggested.Symbol)
  178. Suggested.Symbol = Suggested.Symbol[Suggested.Symbol != "-"]
  179. if (length(Suggested.Symbol) >= 1){
  180. Suggested.Symbol = Suggested.Symbol[1]
  181. if (Suggested.Symbol == x){
  182. Approved = TRUE
  183. }
  184. } else {
  185. Suggested.Symbol = RRF_df[,"Symbol"]
  186. Suggested.Symbol = unique(Suggested.Symbol)
  187. Suggested.Symbol = Suggested.Symbol[1]
  188. }
  189. } else if (x %in% PRF_ref_NIH_expanded$Synonyms){
  190. RRF_df = PRF_ref_NIH_expanded[PRF_ref_NIH_expanded$Synonyms == x,]
  191. Curr_gene = x
  192. Approved = FALSE
  193. Suggested.Symbol = RRF_df[,"Symbol_from_nomenclature_authority"]
  194. Suggested.Symbol = unique(Suggested.Symbol)
  195. Suggested.Symbol = Suggested.Symbol[Suggested.Symbol != "-"]
  196. if (length(Suggested.Symbol) >= 1){
  197. Suggested.Symbol = Suggested.Symbol[1]
  198. } else {
  199. Suggested.Symbol = RRF_df[,"Symbol"]
  200. Suggested.Symbol = unique(Suggested.Symbol)
  201. Suggested.Symbol = Suggested.Symbol[1]
  202. }
  203. } else {
  204. Curr_gene = x
  205. Approved = FALSE
  206. Suggested.Symbol = NA
  207. if (PRF_replace_NA_with_old){
  208. Suggested.Symbol = x
  209. }
  210. }
  211. Dataset = data.frame(x = Curr_gene, Approved = Approved, Suggested.Symbol = Suggested.Symbol)
  212. })
  213. PRF_gene_symbols_check = list_to_df(PRF_gene_symbols_check)
  214. return(PRF_gene_symbols_check)
  215. }
  216. test_genes_OLINK_linear_models_generalized = function(PREFIX_Pheno_df,
  217. PREFIX_Expression_matrix,
  218. PREFIX_contrast_col_number,
  219. PREFIX_participants_col_number,
  220. PREFIX_contrast_vector,
  221. PREFIX_model.covariates,
  222. PREFIX_Remove_NA_predictors = TRUE,
  223. PREFIX_show_all_coef = FALSE,
  224. PREFIX_round_output = TRUE){
  225. writeLines("Testing all genes")
  226. #Preparing data
  227. colnames(PREFIX_Pheno_df)[PREFIX_contrast_col_number] = "Case_Control"
  228. PREFIX_Pheno_df = PREFIX_Pheno_df[PREFIX_Pheno_df$Case_Control %in% PREFIX_contrast_vector, ]
  229. PREFIX_Pheno_df$Case_Control = factor(PREFIX_Pheno_df$Case_Control, levels = c(PREFIX_contrast_vector[1], PREFIX_contrast_vector[2]))
  230. colnames(PREFIX_Pheno_df)[PREFIX_participants_col_number] = "Participant_ID_FUN"
  231. # getting expression values
  232. PREFIX_Tested_expression = PREFIX_Expression_matrix
  233. PREFIX_Tested_expression = PREFIX_Tested_expression[,colnames(PREFIX_Tested_expression) %in% PREFIX_Pheno_df$Participant_ID_FUN]
  234. # preparing pheno df before model
  235. if (!is.null(PREFIX_model.covariates)){
  236. PREFIX_Pheno_df = PREFIX_Pheno_df[,c("Participant_ID_FUN", "Case_Control", PREFIX_model.covariates)]
  237. } else {
  238. PREFIX_Pheno_df = PREFIX_Pheno_df[,c("Participant_ID_FUN", "Case_Control")]
  239. }
  240. PREFIX_MODEL_LIST = list()
  241. for (PREFIX_i in 1:nrow(PREFIX_Tested_expression)){
  242. PREFIX_Curr_Test = rownames(PREFIX_Tested_expression)[PREFIX_i]
  243. PREFIX_Curr_values = PREFIX_Tested_expression[PREFIX_Curr_Test,]
  244. PREFIX_tmp_df = cbind(PREFIX_Pheno_df, t(PREFIX_Curr_values))
  245. if (PREFIX_Remove_NA_predictors){
  246. writeLines("Removing NA predictors")
  247. PREFIX_Participants_missing_data = apply(PREFIX_tmp_df, 1, function(x){
  248. x = as.character(x)
  249. if (any(is.na(x))){
  250. return(TRUE)
  251. } else{
  252. return(FALSE)
  253. }
  254. })
  255. PREFIX_Participants_missing_data = PREFIX_tmp_df$Participant_ID_FUN[PREFIX_Participants_missing_data]
  256. }
  257. PREFIX_tmp_df = PREFIX_tmp_df[PREFIX_tmp_df$Participant_ID_FUN %!in% PREFIX_Participants_missing_data,]
  258. if (!is.null(PREFIX_model.covariates)){
  259. PREFIX_Model.formula.string = paste0(PREFIX_model.covariates, collapse = " + ")
  260. PREFIX_Model.formula.string = paste0(PREFIX_Curr_Test, " ~ ", "Case_Control", " + ", PREFIX_Model.formula.string)
  261. } else {
  262. PREFIX_Model.formula.string = paste0(PREFIX_Curr_Test, " ~ ", "Case_Control")
  263. }
  264. PREFIX_model_fit = lm(formula = as.formula(PREFIX_Model.formula.string), data = PREFIX_tmp_df)
  265. if (PREFIX_show_all_coef){
  266. PREFIX_model_output = modify_coef_log_model(PREFIX_model_fit, model = "lin.model", rounding = FALSE)
  267. } else {
  268. PREFIX_model_output = modify_coef_log_model(PREFIX_model_fit, model = "lin.model", rounding = FALSE)
  269. PREFIX_model_output = PREFIX_model_output[2,]
  270. }
  271. PREFIX_model_output$Model.formula.string = PREFIX_Model.formula.string
  272. PREFIX_model_output$Gene = PREFIX_Curr_Test
  273. PREFIX_model_output$Contrast = paste0(PREFIX_contrast_vector, collapse = "/")
  274. PREFIX_model_output$Excluded_particip = paste0(PREFIX_Participants_missing_data, collapse = ";")
  275. PREFIX_model_output$Excluded_particip_number = length(PREFIX_Participants_missing_data)
  276. PREFIX_model_output$Df = PREFIX_model_fit$df.residual
  277. # Calculate logFC
  278. PREFIX_expression_values_controls = PREFIX_tmp_df[PREFIX_tmp_df$Case_Control == PREFIX_contrast_vector[1], ncol(PREFIX_tmp_df)]
  279. PREFIX_expression_values_cases = PREFIX_tmp_df[PREFIX_tmp_df$Case_Control == PREFIX_contrast_vector[2], ncol(PREFIX_tmp_df)]
  280. PREFIX_expression_values_controls_exp = 2^PREFIX_expression_values_controls
  281. PREFIX_expression_values_cases_exp = 2^PREFIX_expression_values_cases
  282. Mean_1 = mean(PREFIX_expression_values_controls_exp)
  283. Mean_2 = mean(PREFIX_expression_values_cases_exp)
  284. FC = Mean_2/Mean_1
  285. Log_FC = log2(FC)
  286. PREFIX_model_output$logFC = Log_FC
  287. PREFIX_model_output = PREFIX_model_output[,c("Model.formula.string", "Contrast", "Gene", "Excluded_particip", "Excluded_particip_number",
  288. "Coef.", "logFC", "β","95% CI β","Std. Error β","T.value","P.value", "Df")]
  289. PREFIX_MODEL_LIST[[PREFIX_i]] = PREFIX_model_output
  290. }
  291. if (length(PREFIX_MODEL_LIST) > 1){
  292. PREFIX_MODEL_LIST = do.call(rbind, PREFIX_MODEL_LIST)
  293. } else {
  294. PREFIX_MODEL_LIST = PREFIX_MODEL_LIST[[1]]
  295. }
  296. if (PREFIX_show_all_coef == FALSE){
  297. PREFIX_MODEL_LIST$Adj.P.val = p.adjust(p = PREFIX_MODEL_LIST$P.value, method = "bonferroni")
  298. PREFIX_MODEL_LIST = dplyr::arrange(PREFIX_MODEL_LIST, P.value)
  299. } else {
  300. PREFIX_MODEL_LIST$Adj.P.val = NA
  301. }
  302. colnames(PREFIX_MODEL_LIST) = stri_replace_all_fixed(colnames(PREFIX_MODEL_LIST), pattern = "PREFIX_", replacement = "")
  303. if (PREFIX_round_output){
  304. writeLines("Rounding Output")
  305. PREFIX_MODEL_LIST$β = as.numeric(PREFIX_MODEL_LIST$β)
  306. PREFIX_MODEL_LIST$`Std. Error β` = as.numeric(PREFIX_MODEL_LIST$`Std. Error β`)
  307. PREFIX_MODEL_LIST$P.value = as.numeric(PREFIX_MODEL_LIST$P.value)
  308. PREFIX_MODEL_LIST$`95% CI β` = sapply(PREFIX_MODEL_LIST$`95% CI β`, function(x){
  309. x = stri_split_fixed(x, pattern = " \u2013 ")
  310. x = unlist(x)
  311. x = x[x!=""]
  312. x = as.numeric(x)
  313. x = round(x, digits = 3)
  314. x = paste0(x, collapse = " \u2013 ")
  315. })
  316. PREFIX_MODEL_LIST = PREFIX_MODEL_LIST %>%
  317. mutate_if(is.numeric, function(x) (round(x, digits = 3)))
  318. }
  319. return(PREFIX_MODEL_LIST)
  320. }
  321. modify_coef_log_model = function(x, digits = 3, model = "log_regr", rounding = TRUE){
  322. if (model == "log_regr"){
  323. Summary_model = summary(x)[["coefficients"]]
  324. if (rounding){
  325. Summary_model[,-ncol(Summary_model)] = apply(Summary_model[,-ncol(Summary_model)], 2, function(x) round(x, digits = digits))
  326. }
  327. #Summary_model[,ncol(Summary_model)] = round(Summary_model[,ncol(Summary_model)], digits = 9)
  328. Conf_inter = confint(x, level = 0.95)
  329. if (rounding){
  330. Conf_inter = apply(Conf_inter, 2, function(x) round(x, digits = digits))
  331. }
  332. Conf_inter = mapply(Conf_inter[,1], Conf_inter[,2], FUN = function(x,y){paste0(x, " \u2013 " ,y)})
  333. Exponent_beta_coef = round(exp(Summary_model[,1]), digits = digits)
  334. Table_output = cbind(rownames(Summary_model), Summary_model[,1], Conf_inter, Exponent_beta_coef, Summary_model[,-1])
  335. colnames(Table_output) = c("Coef.", "\U03B2", "95% CI \U03B2", "exp(\U03B2)", "Std. Error \U03B2","Z.value", "P.value")
  336. rownames(Table_output) = NULL
  337. Table_output = as.data.frame(Table_output)
  338. } else {
  339. Summary_model = summary(x)[["coefficients"]]
  340. if (rounding){
  341. Summary_model[,-ncol(Summary_model)] = apply(Summary_model[,-ncol(Summary_model)], 2, function(x) round(x, digits = digits))
  342. }
  343. #Summary_model[,ncol(Summary_model)] = round(Summary_model[,ncol(Summary_model)], digits = 9)
  344. Conf_inter = confint(x, level = 0.95)
  345. if (rounding){
  346. Conf_inter = apply(Conf_inter, 2, function(x) round(x, digits = digits))
  347. }
  348. Conf_inter = mapply(Conf_inter[,1], Conf_inter[,2], FUN = function(x,y){paste0(x, " \u2013 " ,y)})
  349. Table_output = cbind(rownames(Summary_model), Summary_model[,1], Conf_inter, Summary_model[,-1])
  350. colnames(Table_output) = c("Coef.", "\U03B2", "95% CI \U03B2", "Std. Error \U03B2", "T.value", "P.value")
  351. rownames(Table_output) = NULL
  352. Table_output = as.data.frame(Table_output)
  353. }
  354. return(Table_output)
  355. }
  356. characterize_categorical_variable = function(df, Category_1, Category_2, Variable_name, P.val.valid = TRUE, keep_missing = TRUE){
  357. Total_variable = df[, Variable_name]
  358. if (!is.ordered(Variable_name)){
  359. df[, Variable_name] = ordered(Total_variable, levels = sort(unique(Total_variable)))
  360. Total_variable = df[, Variable_name]
  361. }
  362. Contingency_table = table(df[,Variable_name], df[,"variable_to_split"])
  363. if (keep_missing){
  364. Contingency_table = table(df[,Variable_name], df[,"variable_to_split"], exclude = NULL)
  365. }
  366. Contingency_table_percents_1 = (Contingency_table[,Category_1]/(sum(Contingency_table[,Category_1])) * 100) %>% round(., digits = 1)
  367. Contingency_table_percents_2 = (Contingency_table[,Category_2]/(sum(Contingency_table[,Category_2])) * 100) %>% round(., digits = 1)
  368. Report_1 = paste0(row.names(Contingency_table), ": ")
  369. Report_1 = paste0(Report_1, Contingency_table[,Category_1], " (",Contingency_table_percents_1, "%)", collapse = "\n")
  370. Report_2 = paste0(row.names(Contingency_table), ": ")
  371. Report_2 = paste0(Report_2, Contingency_table[,Category_2], " (",Contingency_table_percents_2, "%)", collapse = "\n")
  372. Contingency_table_pval = table(df[,Variable_name], df[,"variable_to_split"])
  373. if (P.val.valid){
  374. tryCatch({
  375. Var.pval <<- chisq.test(Contingency_table_pval)
  376. Var.pval <<- Var.pval$p.value}, warning = function(w){
  377. message = paste0(Variable_name, " has small counts in some groups, using P.val from Fisher's Exact Test")
  378. writeLines(message)
  379. Var.pval <<- fisher.test(Contingency_table_pval)
  380. Var.pval <<- Var.pval$p.value
  381. })
  382. } else {
  383. Var.pval = "Not valid"
  384. }
  385. Output_list = list()
  386. Output_list[[1]] = Report_1
  387. Output_list[[2]] = Report_2
  388. Output_list[[3]] = Var.pval
  389. return(Output_list)
  390. }
  391. characterize_numeric_variable = function(df, Category_1, Category_2, Variable_name, Mention_NAs = TRUE){
  392. Total_variable = df[, Variable_name]
  393. Variable_1 = df[df$variable_to_split == Category_1, Variable_name]
  394. Variable_1_report = describe_vector_numeric(Variable_1, Mention_NAs = Mention_NAs)
  395. Variable_2 = df[df$variable_to_split == Category_2, Variable_name]
  396. Variable_2_report = describe_vector_numeric(Variable_2, Mention_NAs = Mention_NAs)
  397. Shapiro_normality_check = shapiro.test(Total_variable)
  398. Shapiro_normality_check = Shapiro_normality_check$p.value
  399. if (Shapiro_normality_check < 0.05){
  400. message = paste0(Variable_name, " is not normally distributed. Using P-val from Mann Whitney U Test")
  401. writeLines(message)
  402. formula_test = paste0(Variable_name, "~ variable_to_split")
  403. tryCatch(
  404. {
  405. Total_pval = wilcox.test(formula = as.formula(formula_test), data = df)
  406. Total_pval = Total_pval$p.value
  407. },
  408. error = function(cond) {
  409. message(conditionMessage(cond))
  410. message("Returning NA for p-value")
  411. Total_pval <<- NA
  412. }
  413. )
  414. } else {
  415. message = paste0(Variable_name, " is normally distributed. Using P-val from T Test")
  416. writeLines(message)
  417. formula_test = paste0(Variable_name, "~ variable_to_split")
  418. Var_test_check = var.test(formula = as.formula(formula_test), data = df)
  419. Var_test_check = Var_test_check$p.value
  420. if (Var_test_check >= 0.05){
  421. Total_pval = t.test(formula = as.formula(formula_test), data = df, var.equal = TRUE)
  422. } else {
  423. Total_pval = t.test(formula = as.formula(formula_test), data = df, var.equal = FALSE)
  424. }
  425. Total_pval = Total_pval$p.value
  426. }
  427. Output_list = list()
  428. Output_list[[1]] = Variable_1_report
  429. Output_list[[2]] = Variable_2_report
  430. Output_list[[3]] = Total_pval
  431. return(Output_list)
  432. }
  433. describe_vector_numeric = function(x, Mention_NAs, show_as_percent = FALSE, Describe_min_max = TRUE){
  434. if (all(is.na(x))){
  435. Missing_count = length(x[is.na(x)])
  436. Missing_val_percent = (Missing_count/length(x) * 100) %>% round(., digits = 2)
  437. Var_report = paste0("Missing val: ", Missing_count, " (", Missing_val_percent, "%)")
  438. return(Var_report)
  439. }
  440. Mean_var = mean(x, na.rm = TRUE) %>% round(., digits = 2)
  441. SD_var = sd(x, na.rm = TRUE) %>% round(., digits = 2)
  442. Var_report = paste0(Mean_var, " ± ", SD_var)
  443. if (is.na(SD_var)){
  444. Var_report = paste0("Single non-NA value")
  445. }
  446. if (show_as_percent & Var_report != "Single non-NA value"){
  447. Mean_var = Mean_var * 100/Mean_var
  448. SD_var = SD_var * 100/Mean_var
  449. Var_report = paste0(Mean_var, " ± ", SD_var, "%")
  450. }
  451. if (Mention_NAs){
  452. Missing_count = length(x[is.na(x)])
  453. Missing_val_percent = (Missing_count/length(x) * 100) %>% round(., digits = 2)
  454. if (Missing_count > 0){
  455. Var_report = paste0(Var_report, "\nMissing val: ", Missing_count, " (", Missing_val_percent, "%)")
  456. }
  457. }
  458. if (Describe_min_max){
  459. Min_var = min(x, na.rm = TRUE) %>% round(., digits = 2)
  460. Max_var = max(x, na.rm = TRUE) %>% round(., digits = 2)
  461. if (show_as_percent & !is.na(SD_var)){
  462. Min_var = Min_var * 100/Mean_var
  463. Max_var = Max_var * 100/Mean_var
  464. Var_report = paste0(Var_report, "\n", "Min: ", Min_var, "%, Max: ",Max_var, "%")
  465. } else {
  466. Var_report = paste0(Var_report, "\n", "Min: ", Min_var, ", Max: ",Max_var)
  467. }
  468. }
  469. return(Var_report)
  470. }
  471. characterize_dataset_generelized_two_subgroups = function(dataset,
  472. study_char,
  473. contrast_col_number,
  474. participants_col_number,
  475. model_covariates_col_vector,
  476. columns_to_characterise_vector,
  477. Remove_NA_predictors = FALSE,
  478. drop_P = TRUE,
  479. simplif_P = 3){
  480. # Running Raw Statistics
  481. total_number = nrow(dataset)
  482. total_number_message = paste0("Initial dataset includes ", total_number, " participants")
  483. writeLines(total_number_message)
  484. first_row_output = data.frame(Name = total_number_message,Category.1 = "", Category.2 = "", P.value = NA)
  485. # Removing missing data
  486. colnames(dataset)[participants_col_number] = "Participant_ID_FUN"
  487. indeces = c(participants_col_number, contrast_col_number, model_covariates_col_vector)
  488. indeces = unique(indeces)
  489. Model_df = dataset[,indeces]
  490. if (Remove_NA_predictors){
  491. writeLines("Removing participants with missing data")
  492. Participants_missing_data = apply(Model_df, 1, function(x){
  493. x = as.character(x)
  494. if (any(is.na(x))){
  495. return(TRUE)
  496. } else{
  497. return(FALSE)
  498. }
  499. })
  500. Participants_missing_data = Model_df$Participant_ID_FUN[Participants_missing_data]
  501. if (length(Participants_missing_data) < 1){
  502. excluded_number = 0
  503. } else {
  504. excluded_number = length(Participants_missing_data)
  505. }
  506. Participants_excluded_df = dataset[dataset$Participant_ID_FUN %in% Participants_missing_data, ]
  507. dataset = dataset[dataset$Participant_ID_FUN %!in% Participants_missing_data, ]
  508. excluded_message = paste0("Participants with missing data excluded: ", excluded_number,"\n",
  509. "Resulting number of participants: ", nrow(dataset))
  510. second_row_output = data.frame(Name = excluded_message,Category.1 = "", Category.2 = "", P.value = NA)
  511. writeLines(excluded_message)
  512. } else {
  513. writeLines("Exclusion of participants was not performed")
  514. second_row_output = data.frame(Name = "Exclusion of participants was not performed", Category.1 = "", Category.2 = "", P.value = NA)
  515. Participants_excluded_df = NA
  516. }
  517. main_indeces = c(contrast_col_number, columns_to_characterise_vector)
  518. main_indeces = unique(main_indeces)
  519. Main_dataset = list()
  520. # Making categories
  521. Initial_names = colnames(dataset)[main_indeces]
  522. colnames(dataset)[contrast_col_number] = "variable_to_split"
  523. levels_var = dataset[,"variable_to_split"]
  524. levels_var = levels(levels_var)
  525. names(levels_var) = NULL
  526. Category_1 = levels_var[1]
  527. Category_2 = levels_var[2]
  528. for (i in 1:length(main_indeces)){
  529. curr_variable = dataset[, main_indeces[i]]
  530. if (is.factor(curr_variable)){
  531. Characterised_var = characterize_categorical_variable(df = dataset,
  532. Category_1 = Category_1,
  533. Category_2 = Category_2,
  534. Variable_name = colnames(dataset)[main_indeces[i]],
  535. keep_missing = TRUE)
  536. } else if (is.character(curr_variable)){
  537. message = paste0("Bad index: ", main_indeces[i])
  538. print(message)
  539. stop("All columns should be either a Factor or Numeric")
  540. } else if (is.numeric(curr_variable)){
  541. Characterised_var = characterize_numeric_variable(df = dataset,
  542. Category_1 = Category_1,
  543. Category_2 = Category_2,
  544. Variable_name = colnames(dataset)[main_indeces[i]],
  545. Mention_NAs = TRUE)
  546. }
  547. Current_DF = data.frame(Name = Initial_names[i],
  548. Category.1 = Characterised_var[[1]],
  549. Category.2 = Characterised_var[[2]],
  550. P.value = Characterised_var[[3]])
  551. Main_dataset[[i]] = Current_DF
  552. }
  553. Main_dataset = list_to_df(data_list = Main_dataset)
  554. Main_dataset$P.value = round(Main_dataset$P.value, digits = simplif_P)
  555. # Compiling full dataframe
  556. header = data.frame(Name = study_char, Category.1 = "", Category.2 = "", P.value = NA)
  557. Full_table = rbind(header, first_row_output, second_row_output, Main_dataset)
  558. if(drop_P){
  559. Full_table$P.value = NULL
  560. }
  561. output = list()
  562. output$Table = Full_table
  563. output$Excluded = Participants_excluded_df
  564. return(output)
  565. }
  566. # SCAS score calculator
  567. SCAS_calculator = function(df_SCAS_ordered, NA_param = FALSE){
  568. sum_function = function(x){
  569. x = sum(x, na.rm = NA_param)
  570. return(x)
  571. }
  572. Total_score = apply(df_SCAS_ordered[,-c(11, 17, 26, 31, 38, 43)], MARGIN = 1, sum_function)
  573. Social_phobia = apply(df_SCAS_ordered[,c(6, 7, 9, 10, 29, 35)], MARGIN = 1, sum_function)
  574. GAD = apply(df_SCAS_ordered[,c(1, 3, 4, 20, 22, 24)], MARGIN = 1, sum_function)
  575. FOPH = apply(df_SCAS_ordered[,c(2, 18, 23, 25, 33)], MARGIN = 1, sum_function)
  576. Panic_agoraphobia = apply(df_SCAS_ordered[,c(13, 21, 28, 30, 32, 34, 36, 37, 39)], MARGIN = 1, sum_function)
  577. OCD = apply(df_SCAS_ordered[,c(14, 19, 27, 40, 41, 42)], MARGIN = 1, sum_function)
  578. SAD = apply(df_SCAS_ordered[,c(5, 8, 12, 15, 16, 44)], MARGIN = 1, sum_function)
  579. Score_df = cbind(Total_score, Social_phobia, GAD, FOPH, Panic_agoraphobia, OCD, SAD)
  580. colnames(Score_df) = paste0("SCAS_", colnames(Score_df))
  581. Score_df = as.data.frame(Score_df)
  582. return(Score_df)
  583. }
  584. # plot forest for genes
  585. plot_forest_meta_gene = function(gene_name, meta_df){
  586. tmp_df_genes = meta_df[meta_df$Corrected_symbol == gene_name,]
  587. if(nrow(tmp_df_genes)<1){
  588. writeLines("Gene is missing in the data")
  589. return(NULL)
  590. }
  591. tmp_meta_model = rma.uni(yi = avgLog2FC, vi = maxSE^2, data = tmp_df_genes, method = "SJ", weighted = TRUE)
  592. # Example Visualization
  593. weights = fmtx(weights(tmp_meta_model), digits=1)
  594. sav = forest(tmp_meta_model, slab = Study, ilab = weights)
  595. k = nrow(tmp_df_genes)
  596. colp <- "red"
  597. segments(coef(tmp_meta_model), 0, coef(tmp_meta_model), k, col=colp, lty="33", lwd=0.8)
  598. # Add text
  599. par(xpd=NA)
  600. par(cex=sav$cex, font=2)
  601. difference_coords = sav$xlim[2] - sav$xlim[1]
  602. # Headers
  603. text(sav$xlim[1], k+2.5, pos=4, "Cohort")
  604. text(sav$xlim[1]+difference_coords*0.25, k+2.5, pos=4, "Weight %")
  605. text(0, k+2.7, "Log2FC,\n(95% CI)")
  606. segments(sav$ilab.xpos[1]-0.22, k+2.5, sav$ilab.xpos[2]+0.13, k+2.8)
  607. text(sav$xlim[2]-0.10, k+2.7, "Log2FC\n(95% CI)")
  608. # Use a non-bold font for the rest of the text
  609. # Y coord for heterogen
  610. y_low = sav$ylim[1]
  611. y_high = sav$ylim[2]
  612. par(cex=sav$cex, font=1)
  613. text(sav$ilab.xpos[3], 0, "100.0")
  614. text(sav$xlim[1], y_low, pos=4, bquote(paste("Test for heterogeneity: ",
  615. I^2, "=", .(fmtx(tmp_meta_model$I2, digits=2)), ", ",
  616. tau^2, "=", .(fmtx(tmp_meta_model$tau2, digits=2)), ", ",
  617. chi^2, "=", .(fmtx(tmp_meta_model$QE, digits=2)),
  618. ", df=", .(tmp_meta_model$k - tmp_meta_model$p), ", ",
  619. .(fmtp(tmp_meta_model$QEp, digits=2, pname="P", add0=TRUE, equal=TRUE)))))
  620. title(paste0("Gene: ", gene_name))
  621. }
  622. plot_forest_simple_gene = function(gene_name, meta_df, study_column_char = "Study"){
  623. tmp_df_genes = meta_df[meta_df$Corrected_symbol == gene_name,]
  624. if(nrow(tmp_df_genes)<1){
  625. writeLines("Gene is missing in the data")
  626. return(NULL)
  627. }
  628. forest(tmp_df_genes$avgLog2FC, tmp_df_genes$maxSE**2, slab = tmp_df_genes[,study_column_char], xlab = paste0("Gene: ", gene_name))
  629. }
  630. # A function to make Venn diagrams from named lists (uses ggplot2 and ggVennDiagram)
  631. make_Venn_digram_list = function(named_list, plot_full_path = NULL, label_text_size=4, ...){
  632. # Customizable Venn diagram
  633. venn = Venn(named_list)
  634. data = process_data(venn)
  635. data@region$full_lable = sapply(data@region$count, function(x){
  636. Number = x
  637. Percent = x/sum(data@region$count)
  638. Percent = Percent*100
  639. Percent = round(Percent, digits = 1)
  640. Label_full = paste0(Number, "\n","(", Percent, "%)")
  641. return(Label_full)
  642. })
  643. # to see available shapes plot_shapes()
  644. plot = ggplot() +
  645. # 1. region count layer
  646. geom_sf(aes(fill = id), data = venn_region(data), ...) +
  647. # 2. set edge layer
  648. geom_sf(color="black", size = 0.5, data = venn_setedge(data), show.legend = FALSE, ...) +
  649. # 3. set label layer
  650. geom_sf_text(aes(label = name), data = venn_setlabel(data), size = label_text_size, ...) +
  651. # 4. region label layer
  652. geom_sf_label(aes(label = full_lable), data = venn_region(data), size = label_text_size, ...) +
  653. scale_fill_brewer(...) +
  654. scale_x_continuous(expand = expansion(mult = .2)) +
  655. theme(
  656. axis.title = element_blank(),
  657. axis.text = element_blank(),
  658. axis.ticks = element_blank(),
  659. axis.line = element_blank(),
  660. legend.background = element_blank(),
  661. legend.key = element_blank(),
  662. legend.position = "none",
  663. panel.grid.major = element_blank(),
  664. panel.grid.minor = element_blank(),
  665. plot.background = element_blank(),
  666. panel.background = element_blank(),
  667. plot.margin = margin(1,1,1,1, "cm")
  668. )
  669. print(plot)
  670. if (is.character(plot_full_path)){
  671. if (stri_detect_fixed(plot_full_path, ".pdf")){
  672. pdf(plot_full_path, width = 10, height = 10)
  673. print(plot)
  674. dev.off()
  675. }
  676. if (stri_detect_fixed(plot_full_path, ".png")){
  677. png(plot_full_path, width = 1024, height = 1024)
  678. print(plot)
  679. dev.off()
  680. }
  681. }
  682. }
  683. run_enrichment_GO_KEGG_gene_set = function(genes, universe, categories_to_show = 30, folder, plot_name_pref){
  684. # genes should be submitted as Entrez IDs
  685. if (length(genes) < 10) {
  686. Minsize = length(genes)
  687. } else {
  688. Minsize = 10
  689. }
  690. # IDs should be characters
  691. genes = as.character(genes)
  692. universe = as.character(universe)
  693. # Running GO analysis
  694. GO_String = c("BP", "MF", "CC")
  695. GO_Enrichment = lapply(GO_String, function(x){
  696. result = clusterProfiler::enrichGO(gene = genes, OrgDb = 'org.Hs.eg.db', ont = x, universe = universe, minGSSize = Minsize)
  697. return(result)
  698. })
  699. KEGG_Enrichment = clusterProfiler::enrichKEGG(gene = genes, organism = 'hsa' , universe = universe, minGSSize = Minsize)
  700. # Saving GO results
  701. dir.create(folder)
  702. combined_enrich = list()
  703. for (i in 1:length(GO_String)){
  704. filename = paste0(plot_name_pref, "_GO_", GO_String[i], ".xlsx")
  705. filename = paste0(folder, "/", filename)
  706. Curr_GO = GO_Enrichment[[i]]
  707. Curr_GO_readable = setReadable(Curr_GO, 'org.Hs.eg.db', 'ENTREZID')
  708. Curr_GO_result = Curr_GO@result
  709. Curr_GO_result$geneSymbol = Curr_GO_readable@result$geneID
  710. combined_enrich[[i]] = Curr_GO_result
  711. openxlsx::write.xlsx(x = Curr_GO_result, file = filename, overwrite = TRUE)
  712. }
  713. # Saving KEGG results
  714. if (!is.null(KEGG_Enrichment)){
  715. KEGG_Enrichment_readable = setReadable(KEGG_Enrichment, 'org.Hs.eg.db', 'ENTREZID')
  716. KEGG_Enrichment_result = KEGG_Enrichment@result
  717. KEGG_Enrichment_result$geneSymbol = KEGG_Enrichment_readable@result$geneID
  718. combined_enrich[[4]] = KEGG_Enrichment_result
  719. openxlsx::write.xlsx(x = KEGG_Enrichment_result, file = paste0(folder, "/", plot_name_pref, "_KEGG.xlsx"), overwrite = TRUE)
  720. } else {
  721. combined_enrich[[4]] = NA
  722. }
  723. # Saving full results
  724. openxlsx::write.xlsx(x = combined_enrich, file = paste0(folder, "/", plot_name_pref, "_enrichment_combined_sheet.xlsx"), overwrite = TRUE)
  725. # Making plots
  726. GO_Enrichment_readable = lapply(GO_Enrichment, function(x) setReadable(x, 'org.Hs.eg.db', 'ENTREZID'))
  727. if (!is.null(KEGG_Enrichment)){
  728. GO_Enrichment_readable[[4]] = KEGG_Enrichment_readable
  729. } else {
  730. GO_Enrichment_readable[[4]] = NA
  731. }
  732. GO_String = c("BP", "MF", "CC", "KEGG")
  733. gc()
  734. for (i in 1:length(GO_String)){
  735. Curr_GO = GO_Enrichment_readable[[i]]
  736. if (is.na(Curr_GO)){
  737. writeLines(paste0(filename, " has NO results and analysis was not conducted"))
  738. next
  739. }
  740. filename = paste0(plot_name_pref, "_GO_", GO_String[i])
  741. filename = paste0(folder, "/", filename)
  742. if (GO_String[i] == "KEGG"){
  743. # Figures for KEGG
  744. dimensions = c(19*nrow(summary(Curr_GO))/categories_to_show, 11*nrow(summary(Curr_GO))/categories_to_show)
  745. if (any(dimensions < 1)){
  746. dimensions = dimensions*10
  747. }
  748. if (nrow(summary(Curr_GO)) < 1){
  749. writeLines(paste0(filename, " has NO significant results"))
  750. next
  751. }
  752. # Barplot
  753. pdf(paste0(filename, "_bar.pdf")
  754. , width = 10, height = 10)
  755. print(barplot(Curr_GO, showCategory = categories_to_show, font.size = 10))
  756. dev.off()
  757. pdf(paste0(filename, "_bar_full.pdf")
  758. , width = 10, height = 10*nrow(summary(Curr_GO))/categories_to_show)
  759. print(barplot(Curr_GO, showCategory = nrow(summary(Curr_GO)), font.size = 10))
  760. dev.off()
  761. # Dotplot
  762. pdf(paste0(filename, "_dot.pdf")
  763. , width = 10, height = 10)
  764. print(dotplot(Curr_GO, showCategory= categories_to_show, font.size = 10))
  765. dev.off()
  766. pdf(paste0(filename, "_dot_full.pdf")
  767. , width = 10, height = dimensions[2])
  768. print(dotplot(Curr_GO, showCategory = nrow(summary(Curr_GO)), font.size = 10))
  769. dev.off()
  770. # Gene-Concept Network
  771. pdf(paste0(filename, "_gene_conc.pdf")
  772. , width = 19, height = 11)
  773. print(cnetplot(Curr_GO, circular = FALSE, colorEdge = TRUE, color_category='firebrick', color_gene='steelblue', layout = "kk",
  774. showCategory = categories_to_show, cex_gene = 0.7, cex_label_gene = 0.7, shadowtext = "gene", max.overlaps = 1000, force = 3, force_pull = 0.5, max.time = 2))
  775. dev.off()
  776. tryCatch({
  777. pdf(paste0(filename, "_gene_conc_full.pdf")
  778. , width = dimensions[1], height = dimensions[2])
  779. print(cnetplot(Curr_GO, circular = FALSE, colorEdge = TRUE, color_category='firebrick', color_gene='steelblue', layout = "kk",
  780. showCategory = nrow(summary(Curr_GO)), cex_gene = 0.7, cex_label_gene = 0.7, shadowtext = "gene", max.overlaps = 1000, force = 3, force_pull = 0.5, max.time = 2))
  781. dev.off()
  782. }, error = function(e) {writeLines(paste0("Full gene conc plot is not available for ", filename))})
  783. } else {
  784. # Figures for GO
  785. dimensions = c(19*nrow(summary(Curr_GO))/categories_to_show, 11*nrow(summary(Curr_GO))/categories_to_show)
  786. if (any(dimensions < 1)){
  787. dimensions = dimensions*10
  788. }
  789. if (nrow(summary(Curr_GO)) < 1){
  790. writeLines(paste0(filename, " has NO significant results"))
  791. next
  792. }
  793. # Barplot
  794. pdf(paste0(filename, "_bar.pdf")
  795. , width = 10, height = 10)
  796. print(barplot(Curr_GO, showCategory = categories_to_show, font.size = 10))
  797. dev.off()
  798. pdf(paste0(filename, "_bar_full.pdf")
  799. , width = 10, height = dimensions[2])
  800. print(barplot(Curr_GO, showCategory = nrow(summary(Curr_GO)), font.size = 10))
  801. dev.off()
  802. # Dotplot
  803. pdf(paste0(filename, "_dot.pdf")
  804. , width = 10, height = 10)
  805. print(dotplot(Curr_GO, showCategory= categories_to_show, font.size = 10))
  806. dev.off()
  807. pdf(paste0(filename, "_dot_full.pdf")
  808. , width = 10, height = dimensions[2])
  809. print(dotplot(Curr_GO, showCategory = nrow(summary(Curr_GO)), font.size = 10))
  810. dev.off()
  811. # Gene-Concept Network
  812. pdf(paste0(filename, "_gene_conc.pdf")
  813. , width = 19, height = 11)
  814. print(cnetplot(Curr_GO, circular = FALSE, colorEdge = TRUE, color_category='firebrick', color_gene='steelblue', layout = "kk",
  815. showCategory = categories_to_show, cex_gene = 0.7, cex_label_gene = 0.7, shadowtext = "gene", max.overlaps = 1000, force = 3, force_pull = 0.5, max.time = 2))
  816. dev.off()
  817. tryCatch({
  818. pdf(paste0(filename, "_gene_conc_full.pdf"),
  819. width = dimensions[1], height = dimensions[2])
  820. print(cnetplot(Curr_GO, circular = FALSE, colorEdge = TRUE, color_category='firebrick', color_gene='steelblue', layout = "kk",
  821. showCategory = nrow(summary(Curr_GO)), cex_gene = 0.7, cex_label_gene = 0.7, shadowtext = "gene", max.overlaps = 1000, force = 3, force_pull = 0.5, max.time = 2))
  822. dev.off()
  823. }, error = function(e) {writeLines(paste0("Full gene conc plot is not available for ", filename))})
  824. # GO induced graph
  825. tryCatch({
  826. pdf(paste0(filename, "_go_graph.pdf"),
  827. width = 19, height = 11)
  828. print(goplot(Curr_GO, showCategory = categories_to_show))
  829. dev.off()
  830. }, error = function(e) {writeLines(paste0("Go graph is not available for ", filename))})
  831. tryCatch({
  832. pdf(paste0(filename, "_go_graph_full.pdf"),
  833. width = dimensions[1], height = dimensions[2])
  834. print(goplot(Curr_GO, showCategory = nrow(summary(Curr_GO))))
  835. dev.off()
  836. }, error = function(e) {writeLines(paste0("Go graph (big) is not available for ", filename))})
  837. # Tree plot
  838. Curr_GO_pairwise = enrichplot::pairwise_termsim(Curr_GO)
  839. dimensions = c(19*nrow(Curr_GO_pairwise@termsim)/categories_to_show, 11*nrow(Curr_GO_pairwise@termsim)/categories_to_show)
  840. if (any(dimensions < 1)){
  841. dimensions = dimensions*10
  842. }
  843. tryCatch({
  844. pdf(paste0(filename, "_tree.pdf"),
  845. width = 19, height = 11)
  846. print(treeplot(Curr_GO_pairwise, showCategory = categories_to_show, nCluster = 10))
  847. dev.off()
  848. }, error = function(e) {writeLines(paste0("Tree plot is not available for ", filename))})
  849. tryCatch({
  850. pdf(paste0(filename, "_tree_full.pdf"),
  851. width = dimensions[1], height = dimensions[2])
  852. print(treeplot(Curr_GO_pairwise, showCategory = nrow(Curr_GO_pairwise@termsim), nCluster = 10))
  853. dev.off()
  854. }, error = function(e) {writeLines(paste0("Tree plot (big) is not available for ", filename))})
  855. # Enrichment map
  856. tryCatch({
  857. pdf(paste0(filename, "_enr_map.pdf"),
  858. width = 19, height = 11)
  859. print(emapplot(Curr_GO_pairwise, showCategory = categories_to_show, layout = "fr", cex_label_category = 0.9,
  860. cex_line = 0.8, repel = TRUE))
  861. dev.off()
  862. }, error = function(e) {writeLines(paste0("Enrich. map is not available for ", filename))})
  863. tryCatch({
  864. pdf(paste0(filename, "_enr_map_full.pdf"),
  865. width = dimensions[1], height = dimensions[2])
  866. print(emapplot(Curr_GO_pairwise, showCategory = nrow(Curr_GO_pairwise@termsim), layout = "fr", cex_label_category = 0.9,
  867. cex_line = 0.8, repel = TRUE))
  868. dev.off()
  869. }, error = function(e) {writeLines(paste0("Enrich. map is not available for ", filename))})
  870. }
  871. }
  872. # Preparing outputs to load into the environment
  873. GO_Enrichment[[4]] = KEGG_Enrichment
  874. if (is.null(KEGG_Enrichment)){
  875. GO_Enrichment[[4]] = NA
  876. }
  877. Output = list()
  878. Output[[1]] = GO_Enrichment
  879. Output[[2]] = GO_Enrichment_readable
  880. Output[[3]] = combined_enrich
  881. names(Output) = c("Enrichment", "Mapped Enrichment", "Combined Results")
  882. for (i in 1:length(Output)){
  883. names(Output[[i]]) = GO_String
  884. }
  885. return(Output)
  886. }
  887. run_enrichment_GO_KEGG_gene_set_only_tables = function(genes, universe, folder, plot_name_pref){
  888. # genes should be submitted as Entrez IDs
  889. if (length(genes) < 10) {
  890. Minsize = length(genes)
  891. } else {
  892. Minsize = 10
  893. }
  894. # IDs should be characters
  895. genes = as.character(genes)
  896. universe = as.character(universe)
  897. # Running GO analysis
  898. GO_String = c("BP", "MF", "CC")
  899. GO_Enrichment = lapply(GO_String, function(x){
  900. result = clusterProfiler::enrichGO(gene = genes, OrgDb = 'org.Hs.eg.db', ont = x, universe = universe, minGSSize = Minsize)
  901. return(result)
  902. })
  903. KEGG_Enrichment = clusterProfiler::enrichKEGG(gene = genes, organism = 'hsa' , universe = universe, minGSSize = Minsize)
  904. # Saving GO results
  905. dir.create(folder)
  906. combined_enrich = list()
  907. for (i in 1:length(GO_String)){
  908. filename = paste0(plot_name_pref, "_GO_", GO_String[i], ".xlsx")
  909. filename = paste0(folder, "/", filename)
  910. Curr_GO = GO_Enrichment[[i]]
  911. Curr_GO_readable = setReadable(Curr_GO, 'org.Hs.eg.db', 'ENTREZID')
  912. Curr_GO_result = Curr_GO@result
  913. Curr_GO_result$geneSymbol = Curr_GO_readable@result$geneID
  914. combined_enrich[[i]] = Curr_GO_result
  915. openxlsx::write.xlsx(x = Curr_GO_result, file = filename, overwrite = TRUE)
  916. }
  917. # Saving KEGG results
  918. if (!is.null(KEGG_Enrichment)){
  919. KEGG_Enrichment_readable = setReadable(KEGG_Enrichment, 'org.Hs.eg.db', 'ENTREZID')
  920. KEGG_Enrichment_result = KEGG_Enrichment@result
  921. KEGG_Enrichment_result$geneSymbol = KEGG_Enrichment_readable@result$geneID
  922. combined_enrich[[4]] = KEGG_Enrichment_result
  923. openxlsx::write.xlsx(x = KEGG_Enrichment_result, file = paste0(folder, "/", plot_name_pref, "_KEGG.xlsx"), overwrite = TRUE)
  924. } else {
  925. combined_enrich[[4]] = NA
  926. }
  927. # Saving full results
  928. openxlsx::write.xlsx(x = combined_enrich, file = paste0(folder, "/", plot_name_pref, "_enrichment_combined_sheet.xlsx"), overwrite = TRUE)
  929. GO_Enrichment_readable = lapply(GO_Enrichment, function(x) setReadable(x, 'org.Hs.eg.db', 'ENTREZID'))
  930. # Preparing outputs to load into the environment
  931. GO_Enrichment[[4]] = KEGG_Enrichment
  932. if (is.null(KEGG_Enrichment)){
  933. GO_Enrichment[[4]] = NA
  934. }
  935. Output = list()
  936. Output[[1]] = GO_Enrichment
  937. Output[[2]] = GO_Enrichment_readable
  938. Output[[3]] = combined_enrich
  939. names(Output) = c("Enrichment", "Mapped Enrichment", "Combined Results")
  940. for (i in 1:length(Output)){
  941. names(Output[[i]]) = GO_String
  942. }
  943. return(Output)
  944. }
  945. ################### PSY Recall phenotype preprocessing ###################
  946. DAWBA_DS = read.xlsx("DAWBA PSY June 2021.xlsx", sheet = 1)
  947. Recall_2_Pheno = list.files()
  948. Recall_2_Pheno = Recall_2_Pheno[stri_detect_fixed(Recall_2_Pheno, "RECALL_2")]
  949. Recall_2_Pheno = lapply(Recall_2_Pheno, function(x) read.xlsx(x, sheet = 1, startRow = 1, detectDates = TRUE))
  950. which(colnames(Recall_2_Pheno[[1]]) == "Medication")
  951. which(colnames(Recall_2_Pheno[[2]]) == "Medication")
  952. names(Recall_2_Pheno) = c("Recall_2A", "Recall_2B")
  953. Columns_Recall_2A = c(1, 4, 5, 6, 7, 8:16, 17, 18,20, 21:24, 25:33, 111:132, 168:178, 179:226, 152:167) # HADS - 152:167
  954. Columns_Recall_2B = c(1:30, 31:52, 53:63, 64:111)
  955. Recall_2A_Pheno = Recall_2_Pheno[[1]]
  956. Recall_2A_Pheno = Recall_2A_Pheno[,Columns_Recall_2A]
  957. Recall_2B_Pheno = Recall_2_Pheno[[2]]
  958. Recall_2B_Pheno = Recall_2B_Pheno[,Columns_Recall_2B]
  959. Recall_2B_Pheno = Recall_2B_Pheno[!is.na(Recall_2B_Pheno$Code),]
  960. ############ Recall 2A
  961. Recall_2A_Pheno_small = Recall_2A_Pheno
  962. Columns_to_select_RC2A = c(1,2, 22:26, 30, 31:51, 52, 53:63, 64:108, 111, 112, 113)
  963. Recall_2A_Pheno_small = Recall_2A_Pheno_small[,Columns_to_select_RC2A]
  964. Recall_2A_Pheno_small$DAWBA_DEPBAND = sapply(Recall_2A_Pheno_small$DAWBA.ID, function(x){
  965. index = which(DAWBA_DS$dawbaID == x)
  966. output = DAWBA_DS$depband[index]
  967. if (length(output)<1){return(NA)}
  968. return(output)
  969. })
  970. SCAS_DF_RC2A = Recall_2A_Pheno_small[,42:86]
  971. SCAS_DF_RC2A = apply(SCAS_DF_RC2A, 2, as.numeric)
  972. # corrupt total score check
  973. corrupt_total_score = which(apply(SCAS_DF_RC2A[,-c(11, 17, 26, 31, 38, 43)], 1, function(x) any(is.na(x))))
  974. corrupt_total_score
  975. # Rows 2 199 200 336 should be technically excluded
  976. corrupt_total_score_item_count = apply(SCAS_DF_RC2A[,-c(11, 17, 26, 31, 38, 43)], 1, function(x) sum(is.na(x)))
  977. corrupt_total_score_item_count[corrupt_total_score_item_count>0]
  978. # All rows just miss 1 item
  979. SCAS_scores_RC2A = SCAS_calculator(df_SCAS_ordered = SCAS_DF_RC2A, NA_param = TRUE)
  980. SCAS_scores_RC2A[corrupt_total_score, ]
  981. Recall_2A_Pheno_small = cbind(Recall_2A_Pheno_small, SCAS_scores_RC2A)
  982. Recall_2A_Pheno_small$Code[2] # "PSY0021"
  983. # item check
  984. item_numbers = sapply(colnames(SCAS_DF_RC2A), function(x) unlist(stri_split_fixed(x, pattern = "."))[2])
  985. names(item_numbers) = NULL
  986. is.unsorted(as.numeric(item_numbers)) # FALSE
  987. ############ Recall 2B
  988. Recall_2B_Pheno_small = Recall_2B_Pheno
  989. Columns_to_select_RC2B = c(1, 2, 22:26, 30, 31:51, 52, 53:63, 64:108, 111)
  990. Recall_2B_Pheno_small = Recall_2B_Pheno_small[,Columns_to_select_RC2B]
  991. Recall_2B_Pheno_small$DAWBA_DEPBAND = sapply(Recall_2B_Pheno_small$DAWBA.ID, function(x){
  992. index = which(DAWBA_DS$dawbaID == x)
  993. output = DAWBA_DS$depband[index]
  994. if (length(output)<1){return(NA)}
  995. return(output)
  996. })
  997. SCAS_DF_RC2B = Recall_2B_Pheno_small[,42:86]
  998. SCAS_DF_RC2B = apply(SCAS_DF_RC2B, 2, as.numeric)
  999. # corrupt total score check
  1000. corrupt_total_score = which(apply(SCAS_DF_RC2B[,-c(11, 17, 26, 31, 38, 43)], 1, function(x) any(is.na(x))))
  1001. corrupt_total_score
  1002. # ALL rows are OK!
  1003. SCAS_scores_RC2B = SCAS_calculator(df_SCAS_ordered = Recall_2B_Pheno_small[,42:86])
  1004. Recall_2B_Pheno_small = cbind(Recall_2B_Pheno_small, SCAS_scores_RC2B)
  1005. # item check
  1006. item_numbers = sapply(colnames(SCAS_DF_RC2B), function(x) unlist(stri_split_fixed(x, pattern = "."))[2])
  1007. names(item_numbers) = NULL
  1008. is.unsorted(as.numeric(item_numbers)) # FALSE
  1009. ############ Saving phenotypes
  1010. write.csv(Recall_2A_Pheno_small, "Recall_2A_Pheno_small.csv", row.names = FALSE)
  1011. write.csv(Recall_2B_Pheno_small, "Recall_2B_Pheno_small.csv", row.names = FALSE)
  1012. ################### PSY Recall phenotype curation ###################
  1013. PSY_PHENO_RC2A = smart_fread("Recall_2A_Pheno_small.csv")
  1014. PSY_PHENO_RC2B = smart_fread("Recall_2B_Pheno_small.csv")
  1015. intersecting_cols_RC2 = intersect(colnames(PSY_PHENO_RC2A), colnames(PSY_PHENO_RC2B))
  1016. PSY_PHENO_RC_TOTAL = rbind(PSY_PHENO_RC2A[,intersecting_cols_RC2], PSY_PHENO_RC2B[,intersecting_cols_RC2])
  1017. # Curating recall
  1018. PSY_PHENO_RC_TOTAL$Code = toupper(PSY_PHENO_RC_TOTAL$Code)
  1019. PSY_PHENO_RC_TOTAL$`Gender.(0)male.(1)female` = sapply(PSY_PHENO_RC_TOTAL$`Gender.(0)male.(1)female`, function(x){
  1020. if (x == 0){
  1021. return("M")
  1022. } else {
  1023. return("W")
  1024. }
  1025. })
  1026. colnames(PSY_PHENO_RC_TOTAL) = stri_replace_all_fixed(colnames(PSY_PHENO_RC_TOTAL), pattern = "Gender.(0)male.(1)female", replacement = "Gender")
  1027. ############ Saving phenotypes
  1028. write.csv(PSY_PHENO_RC_TOTAL, "PSY_PHENO_RC_TOTAL.csv", row.names = FALSE)
  1029. ################### Curating phenotype medication intake and removing duplicates ###################
  1030. ANXIETY_CURATED_PSY_PHENO_RC_TOTAL = openxlsx::read.xlsx("ANXIETY_PSY_PHENO_RC_TOTAL_CURATED.xlsx", sheet = 1)
  1031. CURATED_PSY_PHENO_RC_TOTAL = PSY_PHENO_RC_TOTAL
  1032. CURATED_PSY_PHENO_RC_TOTAL$Code = toupper(CURATED_PSY_PHENO_RC_TOTAL$Code)
  1033. any(duplicated(CURATED_PSY_PHENO_RC_TOTAL$Code)) # TRUE There are duplicates in phenotypes
  1034. CURATED_PSY_PHENO_RC_TOTAL$Code[duplicated(CURATED_PSY_PHENO_RC_TOTAL$Code)] # "PSY0662" "PSY0867"
  1035. duplicated_recall = CURATED_PSY_PHENO_RC_TOTAL[CURATED_PSY_PHENO_RC_TOTAL$Code %in% c("PSY0662", "PSY0867"),]
  1036. duplicated_recall_orig = Recall_2A_Pheno[Recall_2A_Pheno$Code %in% c("PSY0662", "PSY0867"),]
  1037. # "PSY0662" should be female as indicated in screening "Collected data_Screening.xlsx", height=159
  1038. as.Date(43158, origin = "1899-12-30") # "2018-02-27", timestamp from PSY_recall_1_2_Biobank_masterfile - Updated_Aleksandr_Sokolov_Oct2021.xlsx
  1039. # "PSY0867" # 02/27/2018 is the correct date -> Age 16
  1040. duplicated_recall_selected = duplicated_recall[c(1,3),]
  1041. # curating recall dataset
  1042. CURATED_PSY_PHENO_RC_TOTAL = CURATED_PSY_PHENO_RC_TOTAL[CURATED_PSY_PHENO_RC_TOTAL$Code %!in% duplicated_recall$Code,]
  1043. CURATED_PSY_PHENO_RC_TOTAL = rbind(CURATED_PSY_PHENO_RC_TOTAL, duplicated_recall_selected)
  1044. # curating recall anxiety dataset
  1045. duplicated_recall = ANXIETY_CURATED_PSY_PHENO_RC_TOTAL[ANXIETY_CURATED_PSY_PHENO_RC_TOTAL$Code %in% c("PSY0662", "PSY0867"),]
  1046. duplicated_recall_selected = duplicated_recall[c(1,3),]
  1047. ANXIETY_CURATED_PSY_PHENO_RC_TOTAL = ANXIETY_CURATED_PSY_PHENO_RC_TOTAL[ANXIETY_CURATED_PSY_PHENO_RC_TOTAL$Code %!in% duplicated_recall$Code,]
  1048. ANXIETY_CURATED_PSY_PHENO_RC_TOTAL = rbind(ANXIETY_CURATED_PSY_PHENO_RC_TOTAL, duplicated_recall_selected)
  1049. # check
  1050. any(duplicated(CURATED_PSY_PHENO_RC_TOTAL$Code)) # FALSE
  1051. any(duplicated(ANXIETY_CURATED_PSY_PHENO_RC_TOTAL$Code)) # FALSE
  1052. CURATED_PSY_PHENO_RC_TOTAL$Antidepr_anxiety = sapply(CURATED_PSY_PHENO_RC_TOTAL$Code, function(x){
  1053. if (x %in% ANXIETY_CURATED_PSY_PHENO_RC_TOTAL$Code){
  1054. treatment_status = ANXIETY_CURATED_PSY_PHENO_RC_TOTAL[ANXIETY_CURATED_PSY_PHENO_RC_TOTAL$Code == x, "Antidepr_anxiety"]
  1055. treatment_status = as.numeric(treatment_status)
  1056. } else {
  1057. treatment_status = NA
  1058. }
  1059. return(treatment_status)
  1060. })
  1061. # PSY0021
  1062. CURATED_PSY_PHENO_RC_TOTAL[CURATED_PSY_PHENO_RC_TOTAL$Code == "PSY0021", "Antidepr_anxiety"] = 0
  1063. ################### Initial Variable prep ###################
  1064. any(is.na(CURATED_PSY_PHENO_RC_TOTAL$SUAS.Total.score)) # FALSE
  1065. CURATED_PSY_PHENO_RC_TOTAL$Gender = factor(CURATED_PSY_PHENO_RC_TOTAL$Gender, levels = c("W", "M"))
  1066. CURATED_PSY_PHENO_RC_TOTAL$SUAS_binary = ifelse(CURATED_PSY_PHENO_RC_TOTAL$SUAS.Total.score >= 31,
  1067. "Risk group", "Normal")
  1068. CURATED_PSY_PHENO_RC_TOTAL$SUAS_binary = factor(CURATED_PSY_PHENO_RC_TOTAL$SUAS_binary, levels = c("Normal", "Risk group"))
  1069. # Variables
  1070. CURATED_PSY_PHENO_RC_TOTAL$Gender
  1071. CURATED_PSY_PHENO_RC_TOTAL$Age
  1072. CURATED_PSY_PHENO_RC_TOTAL$BMI
  1073. CURATED_PSY_PHENO_RC_TOTAL$SUAS.Total.score
  1074. CURATED_PSY_PHENO_RC_TOTAL$SUAS_binary
  1075. ################### Importing proteomics data ###################
  1076. # Preprocess OLINK function
  1077. preprocess_OLINK_main = function(PRFX_OLINK_DS){
  1078. # modifying original DS
  1079. PRFX_idx = which(PRFX_OLINK_DS[,1] == "Panel")
  1080. PRFX_OLINK_DS = PRFX_OLINK_DS[PRFX_idx:nrow(PRFX_OLINK_DS),]
  1081. PRFX_OLINK_DS = as.data.frame(t(PRFX_OLINK_DS))
  1082. colnames(PRFX_OLINK_DS) = PRFX_OLINK_DS[1,]
  1083. PRFX_OLINK_DS = PRFX_OLINK_DS[-1,]
  1084. rownames(PRFX_OLINK_DS) = PRFX_OLINK_DS$Assay
  1085. #preparing data
  1086. PRFX_probes = PRFX_OLINK_DS[,c(1:4, (ncol(PRFX_OLINK_DS)-2):ncol(PRFX_OLINK_DS))]
  1087. PRFX_probes = PRFX_probes[-((nrow(PRFX_OLINK_DS)-1):nrow(PRFX_OLINK_DS)),]
  1088. PRFX_probes$`Missing Data freq.` = as.numeric(PRFX_probes$`Missing Data freq.`)
  1089. PRFX_probes$LOD = as.numeric(PRFX_probes$LOD)
  1090. PRFX_sample_status = PRFX_OLINK_DS[(nrow(PRFX_OLINK_DS)-1):nrow(PRFX_OLINK_DS), ]
  1091. PRFX_sample_status = PRFX_sample_status[,colnames(PRFX_sample_status) %!in% colnames(PRFX_probes)]
  1092. PRFX_sample_status = as.data.frame(t(PRFX_sample_status))
  1093. PRFX_sample_status$Sample = rownames(PRFX_sample_status)
  1094. PRFX_expression = PRFX_OLINK_DS[, colnames(PRFX_OLINK_DS) %in% PRFX_sample_status$Sample]
  1095. PRFX_expression = PRFX_expression[-((nrow(PRFX_OLINK_DS)-1):nrow(PRFX_OLINK_DS)),]
  1096. PRFX_expression = as.matrix(PRFX_expression)
  1097. PRFX_matrix_names = rownames(PRFX_expression)
  1098. PRFX_expression = apply(PRFX_expression, 2, as.numeric)
  1099. rownames(PRFX_expression) = PRFX_matrix_names
  1100. #filtering probes and samples
  1101. PRFX_sample_status$QC_result = ifelse(PRFX_sample_status$`QC Warning` == "Pass", "Included", "Excluded")
  1102. PRFX_expression_pass = PRFX_expression[, colnames(PRFX_expression) %in% PRFX_sample_status[PRFX_sample_status$`QC Warning` == "Pass", "Sample"]]
  1103. PRFX_probes$Probe_QC = ifelse(PRFX_probes$`Missing Data freq.` > 0.2, "Excluded", "Pass")
  1104. for (PRFX_I in 1 : nrow(PRFX_probes)){
  1105. if (PRFX_probes$LOD[PRFX_I] > 2.5 & PRFX_probes$Probe_QC[PRFX_I] == "Excluded"){
  1106. PRFX_probes$Probe_QC[PRFX_I] = "High LOD"
  1107. }
  1108. }
  1109. PRFX_passed_probes = PRFX_probes[PRFX_probes$Probe_QC == "Pass", "Assay"]
  1110. PRFX_expression_pass = PRFX_expression_pass[rownames(PRFX_expression_pass) %in% PRFX_passed_probes,]
  1111. PRFX_expression_pass_strict = PRFX_expression_pass
  1112. for (PRFX_I in 1 : nrow(PRFX_expression_pass_strict)){
  1113. PRFX_Curr_Probe = rownames(PRFX_expression_pass_strict)[PRFX_I]
  1114. PRFX_Curr_LOD = PRFX_probes[PRFX_probes$Assay == PRFX_Curr_Probe, "LOD"]
  1115. PRFX_Curr_row = PRFX_expression_pass_strict[PRFX_I,]
  1116. PRFX_Curr_row = ifelse(PRFX_Curr_row >= PRFX_Curr_LOD, PRFX_Curr_row, NA)
  1117. PRFX_expression_pass_strict[PRFX_I,] = PRFX_Curr_row
  1118. }
  1119. PRFX_expression_pass = as.data.frame(PRFX_expression_pass)
  1120. PRFX_expression_pass_strict = as.data.frame(PRFX_expression_pass_strict)
  1121. PRFX_Output = list(Expression_matrix = PRFX_expression_pass,
  1122. Expression_matrix_strict = PRFX_expression_pass_strict,
  1123. Probes = PRFX_probes,
  1124. Samples = PRFX_sample_status)
  1125. return(PRFX_Output)
  1126. }
  1127. # Batch 2021
  1128. OLINK_DS_2021 = openxlsx::read.xlsx("OLINK_DIANA/Proteomics in healthy adolescents_PSY_NPX_no duplicates.xlsx")
  1129. OLINK_DS_2021_prep = preprocess_OLINK_main(PRFX_OLINK_DS = OLINK_DS_2021)
  1130. View(OLINK_DS_2021_prep$Samples)
  1131. View(OLINK_DS_2021_prep$Probes)
  1132. table(OLINK_DS_2021_prep$Samples$QC_result) # 4 - excluded, 313 - included
  1133. OLINK_DS_2021_prep$Samples[OLINK_DS_2021_prep$Samples$QC_result == "Excluded", ]
  1134. table(OLINK_DS_2021_prep$Probes$Probe_QC) # 43 - excluded, 49 - passed
  1135. OLINK_DS_2021_EXPR = OLINK_DS_2021_prep$Expression_matrix
  1136. # Batch 2022
  1137. OLINK_DS_2022 = openxlsx::read.xlsx("OLINK_AS/Proteomic analyses_Plasma_NPX.xlsx")
  1138. OLINK_DS_2022_prep = preprocess_OLINK_main(PRFX_OLINK_DS = OLINK_DS_2022)
  1139. View(OLINK_DS_2022_prep$Samples)
  1140. View(OLINK_DS_2022_prep$Probes)
  1141. table(OLINK_DS_2022_prep$Samples$QC_result) # 5 - excluded, 233 - included
  1142. OLINK_DS_2022_prep$Samples[OLINK_DS_2022_prep$Samples$QC_result == "Excluded", ]
  1143. table(OLINK_DS_2022_prep$Probes$Probe_QC) # 39 - excluded, 10 - High LOD, 43 - passed
  1144. OLINK_DS_2022_EXPR = OLINK_DS_2022_prep$Expression_matrix
  1145. # Check for repeated measurement
  1146. table(colnames(OLINK_DS_2022_EXPR) %in% colnames(OLINK_DS_2021_EXPR)) # 8 samples were analyzed the 2nd time
  1147. over_analyzed_samples = colnames(OLINK_DS_2022_EXPR)[colnames(OLINK_DS_2022_EXPR) %in% colnames(OLINK_DS_2021_EXPR)]
  1148. OLINK_DS_2022_EXPR = OLINK_DS_2022_EXPR[,colnames(OLINK_DS_2022_EXPR) %!in% over_analyzed_samples]
  1149. # Updating phenotype information
  1150. ALL_PSY_OLINK = c(OLINK_DS_2021_prep$Samples$Sample, OLINK_DS_2022_prep$Samples$Sample)
  1151. ALL_PSY_OLINK = unique(ALL_PSY_OLINK)
  1152. CURATED_PSY_PHENO_RC_TOTAL$OLINK_STATUS = NA
  1153. CURATED_PSY_PHENO_RC_TOTAL$OLINK_BATCH = NA
  1154. CURATED_PSY_PHENO_RC_TOTAL$OLINK_PLATE = NA
  1155. for (i in 1:length(ALL_PSY_OLINK)){
  1156. PRF_sample = ALL_PSY_OLINK[i]
  1157. PRF_name_frag = unlist(stri_split_fixed(PRF_sample, pattern = "_"))
  1158. PRF_name_frag = unlist(stri_split_fixed(PRF_name_frag, pattern = "-"))
  1159. # Meta data
  1160. PRF_praticip = PRF_name_frag[1]
  1161. PRF_visit = PRF_name_frag[2]
  1162. # Get Batch info
  1163. if (PRF_sample %in% OLINK_DS_2021_prep$Samples$Sample){
  1164. PRF_OLINK_BATCH = "2021"
  1165. PRF_SAMPLE_DF = OLINK_DS_2021_prep$Samples
  1166. } else if (PRF_sample %in% OLINK_DS_2022_prep$Samples$Sample){
  1167. PRF_OLINK_BATCH = "2022"
  1168. PRF_SAMPLE_DF = OLINK_DS_2022_prep$Samples
  1169. }
  1170. # Get Plate Info and Status
  1171. PRF_OLINK_STATUS = PRF_SAMPLE_DF[PRF_SAMPLE_DF$Sample == PRF_sample, "QC_result"]
  1172. PRF_OLINK_PLATE = PRF_SAMPLE_DF[PRF_SAMPLE_DF$Sample == PRF_sample, "Plate ID"]
  1173. if (stri_detect_fixed(PRF_visit, pattern = "2")){
  1174. # Data from recall
  1175. CURATED_PSY_PHENO_RC_TOTAL[CURATED_PSY_PHENO_RC_TOTAL$Code == PRF_praticip, "OLINK_STATUS"] = PRF_OLINK_STATUS
  1176. CURATED_PSY_PHENO_RC_TOTAL[CURATED_PSY_PHENO_RC_TOTAL$Code == PRF_praticip, "OLINK_BATCH"] = PRF_OLINK_BATCH
  1177. CURATED_PSY_PHENO_RC_TOTAL[CURATED_PSY_PHENO_RC_TOTAL$Code == PRF_praticip, "OLINK_PLATE"] = PRF_OLINK_PLATE
  1178. }
  1179. # Cleaning
  1180. rm(list = c("PRF_sample",
  1181. "PRF_name_frag",
  1182. "PRF_praticip",
  1183. "PRF_visit",
  1184. "PRF_SAMPLE_DF",
  1185. "PRF_OLINK_STATUS",
  1186. "PRF_OLINK_BATCH",
  1187. "PRF_OLINK_PLATE"))
  1188. }
  1189. table(CURATED_PSY_PHENO_RC_TOTAL$OLINK_STATUS)
  1190. table(CURATED_PSY_PHENO_RC_TOTAL$OLINK_BATCH)
  1191. table(CURATED_PSY_PHENO_RC_TOTAL$OLINK_PLATE)
  1192. ################### Participant Selection ###################
  1193. colnames(OLINK_DS_2022_EXPR) = toupper(colnames(OLINK_DS_2022_EXPR))
  1194. colnames(OLINK_DS_2021_EXPR) = toupper(colnames(OLINK_DS_2021_EXPR))
  1195. colnames(OLINK_DS_2022_EXPR) = stri_replace_all_fixed(colnames(OLINK_DS_2022_EXPR), pattern = "-", replacement = "_")
  1196. colnames(OLINK_DS_2021_EXPR) = stri_replace_all_fixed(colnames(OLINK_DS_2021_EXPR), pattern = "-", replacement = "_")
  1197. combined_cols = c(colnames(OLINK_DS_2022_EXPR), colnames(OLINK_DS_2021_EXPR))
  1198. combined_cols = toupper(combined_cols)
  1199. any(duplicated(combined_cols)) # FALSE -> no duplicated tubes
  1200. combined_cols = stri_replace_all_fixed(combined_cols, pattern = "-", replacement = "_")
  1201. recall_samples = combined_cols[multiple_stri_detector(combined_cols, pattern_vector = c("_2_", "_2B_", "_2A_"))]
  1202. recall_particip = sapply(recall_samples, function(x) unlist(stri_split_fixed(x, pattern = "_"))[1])
  1203. PSY_PHENO_RECALL_OLINK_VALID = CURATED_PSY_PHENO_RC_TOTAL[CURATED_PSY_PHENO_RC_TOTAL$Code %in% recall_particip, ]
  1204. # Filtering Samples
  1205. OLINK_DS_2021_EXPR_KEEP = OLINK_DS_2021_EXPR[, colnames(OLINK_DS_2021_EXPR) %in% recall_samples]
  1206. OLINK_DS_2022_EXPR_KEEP = OLINK_DS_2022_EXPR[, colnames(OLINK_DS_2022_EXPR) %in% recall_samples]
  1207. all(recall_samples %in% c(colnames(OLINK_DS_2021_EXPR), colnames(OLINK_DS_2022_EXPR))) # TRUE
  1208. # Check for duplicated individuals
  1209. total_samples_keep_individ = sapply(recall_samples, function(x) unlist(stri_split_fixed(x, pattern = "_"))[1])
  1210. any(duplicated(total_samples_keep_individ)) # -> FALSE, no duplicated persons
  1211. # Filtering phenotypes
  1212. any(duplicated(PSY_PHENO_RECALL_OLINK_VALID$Code)) # FALSE There are NO duplicates in phenotypes
  1213. PSY_PHENO_RECALL_OLINK_FINAL_curated = PSY_PHENO_RECALL_OLINK_VALID
  1214. # QC
  1215. any(duplicated(PSY_PHENO_RECALL_OLINK_FINAL_curated$Code)) # FALSE
  1216. # Finding overlapping proteins
  1217. proteins_passed_2021 = rownames(OLINK_DS_2021_EXPR_KEEP)
  1218. proteins_passed_2022 = rownames(OLINK_DS_2022_EXPR_KEEP)
  1219. proteins_passed_both_batches = intersect(proteins_passed_2021, proteins_passed_2022)
  1220. # Obtaining combined proteomic dataset
  1221. OLINK_DS_2021_EXPR_KEEP_both = OLINK_DS_2021_EXPR_KEEP[proteins_passed_both_batches,]
  1222. OLINK_DS_2022_EXPR_KEEP_both = OLINK_DS_2022_EXPR_KEEP[proteins_passed_both_batches,]
  1223. all(rownames(OLINK_DS_2021_EXPR_KEEP_both) == rownames(OLINK_DS_2022_EXPR_KEEP_both)) # -> TRUE
  1224. OLINK_DS_BOTH_BATCHES_FINAL = cbind(OLINK_DS_2021_EXPR_KEEP_both, OLINK_DS_2022_EXPR_KEEP_both)
  1225. # Adding Sample column
  1226. PSY_PHENO_RECALL_OLINK_FINAL_curated$Matching_sample = sapply(PSY_PHENO_RECALL_OLINK_FINAL_curated$Code, function(x){
  1227. sample = colnames(OLINK_DS_BOTH_BATCHES_FINAL)[stri_detect_fixed(str = colnames(OLINK_DS_BOTH_BATCHES_FINAL), pattern = x)]
  1228. return(sample)
  1229. })
  1230. # QC
  1231. any(duplicated(colnames(OLINK_DS_BOTH_BATCHES_FINAL))) # FALSE
  1232. any(duplicated(colnames(PSY_PHENO_RECALL_OLINK_FINAL_curated$Matching_sample))) # FALSE
  1233. # uncovered participant in phenotype
  1234. colnames(OLINK_DS_BOTH_BATCHES_FINAL)[colnames(OLINK_DS_BOTH_BATCHES_FINAL) %!in% PSY_PHENO_RECALL_OLINK_FINAL_curated$Matching_sample]
  1235. # all participants are covered!
  1236. PSY_PHENO_RECALL_OLINK_FINAL_curated$OLINK_PLATE = as.factor(PSY_PHENO_RECALL_OLINK_FINAL_curated$OLINK_PLATE)
  1237. table(PSY_PHENO_RECALL_OLINK_FINAL_curated$OLINK_PLATE)
  1238. # Reordering proteomics
  1239. OLINK_DS_BOTH_BATCHES_FINAL = OLINK_DS_BOTH_BATCHES_FINAL[,PSY_PHENO_RECALL_OLINK_FINAL_curated$Matching_sample]
  1240. all(PSY_PHENO_RECALL_OLINK_FINAL_curated$Matching_sample == colnames(OLINK_DS_BOTH_BATCHES_FINAL)) # -> TRUE, order is matching
  1241. # Checking missing values in the data
  1242. corrupt_samples_proteomics = apply(OLINK_DS_BOTH_BATCHES_FINAL, 2, function(x) any(is.na(x)))
  1243. OLINK_DS_BOTH_BATCHES_FINAL = OLINK_DS_BOTH_BATCHES_FINAL[,!corrupt_samples_proteomics]
  1244. PSY_PHENO_RECALL_OLINK_FINAL_curated = PSY_PHENO_RECALL_OLINK_FINAL_curated[!corrupt_samples_proteomics, ]
  1245. all(colnames(OLINK_DS_BOTH_BATCHES_FINAL) == PSY_PHENO_RECALL_OLINK_FINAL_curated$Matching_sample) # TRUE
  1246. ######## Saving processed data
  1247. write.csv(OLINK_DS_BOTH_BATCHES_FINAL, "OLINK_DS_BOTH_BATCHES_FINAL.csv", row.names = TRUE) # 404 samples, 43 proteins
  1248. write.csv(PSY_PHENO_RECALL_OLINK_FINAL_curated, "PSY_PHENO_RECALL_OLINK_FINAL_curated.csv", row.names = FALSE)
  1249. ################### SUAS cut-off cpecs ###################
  1250. CURATED_PSY_PHENO_RC_TOTAL$SUAS_binary = ifelse(CURATED_PSY_PHENO_RC_TOTAL$SUAS.Total.score >= 29,
  1251. "Risk group", "Normal")
  1252. CURATED_PSY_PHENO_RC_TOTAL$SUAS_binary = factor(CURATED_PSY_PHENO_RC_TOTAL$SUAS_binary, levels = c("Normal", "Risk group"))
  1253. ################### Adjusting for batch covariates ###################
  1254. ########### Raw Adjustment (no Covariates)
  1255. OLINK_DS_BOTH_BATCHES_FINAL_ADJUSTED = ComBat(OLINK_DS_BOTH_BATCHES_FINAL, batch = PSY_PHENO_RECALL_OLINK_FINAL_curated$OLINK_PLATE)
  1256. OLINK_DS_BOTH_BATCHES_FINAL_ADJUSTED = as.data.frame(OLINK_DS_BOTH_BATCHES_FINAL_ADJUSTED)
  1257. ########### Adjustment with covar (no antidepr)
  1258. # Batch effect
  1259. # Participants must be columns
  1260. model_batch = model.matrix(~ SUAS_binary + Gender + Age, data = PSY_PHENO_RECALL_OLINK_FINAL_curated)
  1261. OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ADJ = ComBat(dat=OLINK_DS_BOTH_BATCHES_FINAL, batch = PSY_PHENO_RECALL_OLINK_FINAL_curated$OLINK_PLATE, mod=model_batch)
  1262. OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ADJ = as.data.frame(OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ADJ)
  1263. ########### Adjustment with covar (including antidepr)
  1264. # Selecting participants that all have SUAS score and information on antidepressants
  1265. PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR = PSY_PHENO_RECALL_OLINK_FINAL_curated[!is.na(PSY_PHENO_RECALL_OLINK_FINAL_curated$Antidepr_anxiety),]
  1266. OLINK_DS_BOTH_BATCHES_FINAL_ANTIDEPR = OLINK_DS_BOTH_BATCHES_FINAL[,PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR$Matching_sample]
  1267. all(PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR$Matching_sample == colnames(OLINK_DS_BOTH_BATCHES_FINAL_ANTIDEPR)) # -> TRUE, order is matching
  1268. PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR$Antidepr_anxiety = factor(PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR$Antidepr_anxiety, levels = c(0,1))
  1269. # Batch effect
  1270. # Participants must be columns
  1271. PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR$OLINK_PLATE = factor(PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR$OLINK_PLATE)
  1272. model_batch = model.matrix(~ SUAS_binary + Antidepr_anxiety + Gender + Age, data = PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR)
  1273. test_table = model.matrix(~ SUAS_binary + Antidepr_anxiety + Gender + Age + OLINK_PLATE, data = PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR)
  1274. test_table = cor(test_table, method = "pearson", use = "complete.obs")
  1275. OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ANTIDEPR_ADJ = ComBat(dat=OLINK_DS_BOTH_BATCHES_FINAL_ANTIDEPR, batch = PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR$OLINK_PLATE, mod=model_batch)
  1276. OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ANTIDEPR_ADJ = as.data.frame(OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ANTIDEPR_ADJ)
  1277. ################### Limma differential expression ###################
  1278. PSY_PHENO_RECALL_OLINK_FINAL_curated$OLINK_PLATE = factor(PSY_PHENO_RECALL_OLINK_FINAL_curated$OLINK_PLATE)
  1279. # Analysis with limma
  1280. design.matrix = model.matrix(~ SUAS_binary + Gender + Age, data = PSY_PHENO_RECALL_OLINK_FINAL_curated)
  1281. fit = lmFit(OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ADJ, design.matrix)
  1282. fitE = eBayes(fit, robust = TRUE)
  1283. Top_table = limma::topTable(fit = fitE, coef = 2, adjust.method = "fdr", number = Inf)
  1284. Top_table$Gene = rownames(Top_table) # RBKS CCL27 AKT1S1
  1285. ################### Limma differential expression (antidepress) ###################
  1286. # Analysis with limma
  1287. design.matrix = model.matrix(~ SUAS_binary + Antidepr_anxiety + Gender + Age, data = PSY_PHENO_RECALL_OLINK_FINAL_ANTIDEPR)
  1288. fit = lmFit(OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ANTIDEPR_ADJ, design.matrix)
  1289. fitE = eBayes(fit, robust = TRUE)
  1290. Top_table_antidepr = limma::topTable(fit = fitE, coef = 2, adjust.method = "fdr", number = Inf)
  1291. Top_table_antidepr$Gene = rownames(Top_table_antidepr) # PLA2G10
  1292. # Boxplot for CCL27 in PSY
  1293. probe = "CCL27"
  1294. plot_df = PSY_PHENO_RECALL_OLINK_FINAL_curated
  1295. probe_vals = OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ADJ[probe,plot_df$Matching_sample]
  1296. all(colnames(probe_vals) == plot_df$Matching_sample)
  1297. probe_vals = as.numeric(probe_vals)
  1298. plot_df = cbind(plot_df, probe_vals)
  1299. plot = ggplot(data = plot_df, aes(x = SUAS_binary, y = probe_vals, fill = SUAS_binary)) +
  1300. geom_boxplot(notchwidth = 0.25) +
  1301. scale_fill_manual(values = c("#C44652","#EAC151")) +
  1302. geom_violin(alpha = 0.25) +
  1303. labs(y = "NPX: CCL27", x = "SUAS risk group", fill = "Disease status") +
  1304. ggthemes::theme_clean(base_size = 14)
  1305. plot
  1306. ggsave(file = "CCL27_PSY_box.pdf", plot = plot, width = 15, height = 20, units = "cm")
  1307. # Boxplot for AKT1S1 in PSY
  1308. probe = "AKT1S1"
  1309. plot_df = PSY_PHENO_RECALL_OLINK_FINAL_curated
  1310. probe_vals = OLINK_DS_BOTH_BATCHES_FINAL_SUAS_ADJ[probe,plot_df$Matching_sample]
  1311. all(colnames(probe_vals) == plot_df$Matching_sample)
  1312. probe_vals = as.numeric(probe_vals)
  1313. plot_df = cbind(plot_df, probe_vals)
  1314. plot = ggplot(data = plot_df, aes(x = SUAS_binary, y = probe_vals, fill = SUAS_binary)) +
  1315. geom_boxplot(notchwidth = 0.25) +
  1316. scale_fill_manual(values = c("#C44652","#EAC151")) +
  1317. geom_violin(alpha = 0.25) +
  1318. labs(y = "NPX: AKT1S1", x = "SUAS risk group", fill = "Disease status") +
  1319. ggthemes::theme_clean(base_size = 14)
  1320. plot
  1321. ggsave(file = "AKT1S1_PSY_box.pdf", plot = plot, width = 15, height = 20, units = "cm")
  1322. ################### Saving PSY data ###################
  1323. PSY_results_limma = list(
  1324. "PSY_no_antidepr" = Top_table,
  1325. "PSY_antidep_adj" = Top_table_antidepr
  1326. )
  1327. names_for_list_PSY = c(
  1328. "PSY_no_antidepr",
  1329. "PSY_antidep_adj"
  1330. )
  1331. wb = createWorkbook()
  1332. for (i in 1:2) {
  1333. # Add a new worksheet with the sheet name
  1334. addWorksheet(wb, names_for_list_PSY[i])
  1335. # Write the data frame to the worksheet
  1336. writeData(wb, sheet = names_for_list_PSY[i], PSY_results_limma[[i]])
  1337. # Adjust column widths to fit the text
  1338. setColWidths(wb, sheet = names_for_list_PSY[i], cols = 1:ncol(PSY_results_limma[[i]]), widths = "auto")
  1339. }
  1340. saveWorkbook(wb, "PSY_proteomics_SUAS.xlsx", overwrite = TRUE)
  1341. # Dataset caracterization
  1342. PSY_charact_df = PSY_PHENO_RECALL_OLINK_FINAL_curated
  1343. # variables
  1344. # SUAS_binary + Antidepr_anxiety + Gender + Age
  1345. which(colnames(PSY_charact_df) == "Code") # 1
  1346. which(colnames(PSY_charact_df) == "Gender") # 4
  1347. which(colnames(PSY_charact_df) == "Age") # 3
  1348. which(colnames(PSY_charact_df) == "SUAS_binary") # 93
  1349. which(colnames(PSY_charact_df) == "Antidepr_anxiety") # 92
  1350. PSY_charact_df$Antidepr_anxiety = ifelse(PSY_charact_df$Antidepr_anxiety == 0, "No treatment", "Treatment")
  1351. PSY_charact_df$Antidepr_anxiety = factor(PSY_charact_df$Antidepr_anxiety, levels = c("No treatment", "Treatment"))
  1352. PSY_summary = characterize_dataset_generelized_two_subgroups(dataset = PSY_charact_df,
  1353. study_char = "PSY",
  1354. contrast_col_number = 93,
  1355. participants_col_number = 1,
  1356. model_covariates_col_vector = c(4,3,92),
  1357. columns_to_characterise_vector = c(93,4,3,92),
  1358. Remove_NA_predictors = FALSE,
  1359. drop_P = TRUE)
  1360. PSY_summary = PSY_summary$Table
  1361. PSY_summary = PSY_summary[-3,]
  1362. PSY_summary
  1363. PSY_summary = apply(X = PSY_summary, MARGIN = 2, function(x){
  1364. x = multiple_stri_replacer(string = x,
  1365. pattern_vector = c("Initial dataset includes",
  1366. "SUAS_binary",
  1367. "Antidepr_anxiety",
  1368. "W: ",
  1369. "M: "),
  1370. replacement_vector = c("Dataset includes",
  1371. "Suicide risk group (SUAS)",
  1372. "Treatment for depression or anxiety",
  1373. "Female: ",
  1374. "Male: "))
  1375. })
  1376. PSY_summary = as.data.frame(PSY_summary)
  1377. PSY_summary
  1378. wb = createWorkbook()
  1379. # Add a new worksheet with the sheet name
  1380. addWorksheet(wb, sheetName = "PSY_demographics")
  1381. # Write the data frame to the worksheet
  1382. writeData(wb, sheet = "PSY_demographics", PSY_summary)
  1383. # Adjust column widths to fit the text
  1384. setColWidths(wb, sheet = "PSY_demographics", cols = 1:ncol(PSY_summary), widths = "auto")
  1385. # Adjust row heights
  1386. setRowHeights(wb, sheet = "PSY_demographics", rows = 1:nrow(PSY_summary), heights = "auto")
  1387. saveWorkbook(wb, "PSY_demographics.xlsx", overwrite = TRUE)
  1388. ################### Array Suicide datasets GEO ###################
  1389. # Jul 17 2024
  1390. # Organism - human
  1391. # Study type: ("suicide"[MeSH Terms] OR suicide[All Fields]) AND ("human"[Organism] AND ("Expression profiling by array"[Filter] OR "Expression profiling by genome tiling array"[Filter]))
  1392. # https://www.ncbi.nlm.nih.gov/gds/?term=suicide
  1393. ## GSE146446
  1394. geo_test = getGEO("GSE146446")
  1395. geo_test = geo_test[[1]]
  1396. geo_test_pheno = pData(geo_test)
  1397. geo_test_pheno$`tissue:ch1` # only blood -> no data on suicide
  1398. # GSE146446 is only for antidepressant response
  1399. ## GSE92538
  1400. # seems good
  1401. geo_test = getGEO("GSE92538")
  1402. geo_test = geo_test[[1]]
  1403. geo_test_pheno = pData(geo_test)
  1404. geo_test_pheno$`suicide (1=yes):ch1`
  1405. table(geo_test_pheno$`suicide (1=yes):ch1`) # 95 33
  1406. # GSE92538 seems good
  1407. ## GSE208338
  1408. geo_test = getGEO("GSE208338")
  1409. geo_test = geo_test[[1]]
  1410. geo_test_pheno = pData(geo_test)
  1411. table(geo_test_pheno$`suicide:ch1`, geo_test_pheno$`diagnosis:ch1`)
  1412. # GSE208338 this cohort is good!
  1413. ## GSE5388 and GSE5389
  1414. geo_test = getGEO("GSE5388")
  1415. geo_test = geo_test[[1]]
  1416. geo_test_pheno = pData(geo_test)
  1417. table(geo_test_pheno$`Suicide:ch1`, geo_test_pheno$`Disease_status:ch1`)
  1418. # GSE5388 seems good
  1419. geo_test = getGEO("GSE5389")
  1420. geo_test = geo_test[[1]]
  1421. geo_test_pheno = pData(geo_test)
  1422. table(geo_test_pheno$`Suicide:ch1`, geo_test_pheno$`Disease_status:ch1`)
  1423. # GSE5389 seems good
  1424. ## GSE66937
  1425. geo_test = getGEO("GSE66937")
  1426. geo_test = geo_test[[1]]
  1427. geo_test_pheno = pData(geo_test)
  1428. table(geo_test_pheno$`group:ch1`, geo_test_pheno$`brain region:ch1`)
  1429. # GSE66937 seems good
  1430. ## GSE125681
  1431. geo_test = getGEO("GSE125681")
  1432. geo_test = geo_test[[1]]
  1433. geo_test_pheno = pData(geo_test)
  1434. table(geo_test_pheno$`suicide:ch1`)
  1435. # GSE125681 only suicide and there are no controls...
  1436. ## GSE24095
  1437. geo_test = getGEO("GSE24095")
  1438. geo_test = geo_test[[1]]
  1439. geo_test_pheno = pData(geo_test)
  1440. table(geo_test_pheno$`Cause of death:ch1`)
  1441. table(geo_test_pheno$`Cause of death:ch2`)
  1442. # GSE24095 weird design -> better to avoid?
  1443. # Not a comparison of suicide VS control -> exclude
  1444. ## GSE199536
  1445. geo_test = getGEO("GSE199536")
  1446. geo_test = geo_test[[1]]
  1447. geo_test_pheno = pData(geo_test)
  1448. table(geo_test_pheno$`group:ch1`)
  1449. # GSE199536 seems good
  1450. ## GSE20568
  1451. geo_test = getGEO("GSE20568")
  1452. geo_test = geo_test[[1]]
  1453. geo_test_pheno = pData(geo_test)
  1454. table(geo_test_pheno$`cause of death:ch1`) # 1 suicide -> useless
  1455. # GSE20568 is useless
  1456. ## GSE93112
  1457. geo_test = getGEO("GSE93112")
  1458. geo_test = geo_test[[1]]
  1459. geo_test_pheno = pData(geo_test)
  1460. table(geo_test_pheno$`disease state:ch1`)
  1461. table(geo_test_pheno$`response phenotype, alda scale:ch1`)
  1462. # response to treatment Yes/No
  1463. # GSE93112 is useless
  1464. ## GSE9058
  1465. geo_test = getGEO("GSE9058")
  1466. geo_test = geo_test[[1]]
  1467. geo_test_pheno = pData(geo_test)
  1468. # bad phenotypes and 1 suicide -> useless
  1469. # GSE9058 is useless
  1470. #### Array Cohorts to include: GSE208338, GSE5388, GSE5389, GSE66937, GSE199536, GSE92538
  1471. ################### RNA Seq Suicide datasets GEO ###################
  1472. # ("suicide"[MeSH Terms] OR suicide[All Fields]) AND ("human"[Organism] AND "Expression profiling by high throughput sequencing"[Filter])
  1473. ## GSE102556
  1474. geo_test = getGEO("GSE102556")
  1475. geo_test = geo_test[[1]]
  1476. geo_test_pheno = pData(geo_test)
  1477. table(geo_test_pheno$organism_ch1) # 263 homo sapiens
  1478. table(geo_test_pheno$`tissue:ch1`, geo_test_pheno$`Cause of death:ch1`)
  1479. # GSE102556 is good
  1480. ## GSE202537
  1481. geo_test = getGEO("GSE202537")
  1482. geo_test = geo_test[[1]]
  1483. geo_test_pheno = pData(geo_test)
  1484. table(geo_test_pheno$organism_ch1) # 215 homo sapiens
  1485. table(geo_test_pheno$`tissue:ch1`, geo_test_pheno$`manner of death:ch1`)
  1486. # GSE202537 is good
  1487. ## GSE243356
  1488. geo_test = getGEO("GSE243356")
  1489. geo_test = geo_test[[1]]
  1490. geo_test_pheno = pData(geo_test)
  1491. table(geo_test_pheno$organism_ch1) # 61 homo sapiens
  1492. table(geo_test_pheno$`group:ch1`, geo_test_pheno$`tissue:ch1`)
  1493. # GSE243356 is good
  1494. ## GSE247998
  1495. geo_test = getGEO("GSE247998")
  1496. geo_test = geo_test[[1]]
  1497. geo_test_pheno = pData(geo_test)
  1498. table(geo_test_pheno$organism_ch1) # 100 homo sapiens
  1499. table(geo_test_pheno$`suicide attempt:ch1`)
  1500. # GSE247998 is good
  1501. ## GSE101521
  1502. geo_test = getGEO("GSE101521")
  1503. geo_test = geo_test[[1]]
  1504. geo_test_pheno = pData(geo_test)
  1505. table(geo_test_pheno$organism_ch1) # 27 homo sapiens
  1506. table(geo_test_pheno$`diagnosis:ch1`)
  1507. # GSE101521 is good
  1508. ## GSE157197
  1509. geo_test = getGEO("GSE157197")
  1510. geo_test = geo_test[[1]]
  1511. geo_test_pheno = pData(geo_test)
  1512. table(geo_test_pheno$organism_ch1) # 45 homo sapiens
  1513. table(geo_test_pheno$`diagnosis:ch1`)
  1514. # GSE157197 is useless
  1515. ## GSE213982
  1516. geo_test = getGEO("GSE213982")
  1517. geo_test = geo_test[[1]]
  1518. geo_test_pheno = pData(geo_test)
  1519. table(geo_test_pheno$organism_ch1) # 36 homo sapiens
  1520. table(geo_test_pheno$`group:ch1`)
  1521. # GSE213982 is good
  1522. ## GSE144136
  1523. # GSE144136 is single cell -> skipped for now as difficult to compare to bulk
  1524. ## GSE248260
  1525. geo_test = getGEO("GSE248260")
  1526. geo_test = geo_test[[1]]
  1527. geo_test_pheno = pData(geo_test)
  1528. table(geo_test_pheno$organism_ch1) # 24 homo sapiens
  1529. table(geo_test_pheno$`suicide:ch1`)
  1530. # GSE248260 is good
  1531. ## GSE12297
  1532. geo_test = getGEO("GSE12297")
  1533. geo_test = geo_test[[1]]
  1534. geo_test_pheno = pData(geo_test)
  1535. table(geo_test_pheno$organism_ch1) # 20 homo sapiens
  1536. # only 3 suicide
  1537. # GSE12297 is useless
  1538. ## GSE193417
  1539. geo_test = getGEO("GSE193417")
  1540. geo_test = geo_test[[1]]
  1541. geo_test_pheno = pData(geo_test)
  1542. table(geo_test_pheno$organism_ch1) # 12 homo sapiens
  1543. # only 3 suicide
  1544. # GSE193417 is useless
  1545. ## GSE208438
  1546. # GSE208438 is on cell lines -> useless
  1547. # Single cell
  1548. # GSE144136 (SC) MDD vs control (suicide)
  1549. # GSE213982 (SC) MDD vs control (suicide)
  1550. #### RNA seq cohorts to include: GSE102556, GSE202537, GSE243356, GSE247998, GSE101521, GSE213982, GSE248260
  1551. ################### Selected cohorts ###################
  1552. #### Array Cohorts to include: GSE208338, GSE5388, GSE5389, GSE66937, GSE199536, GSE92538 (limma-trend (standard pipeline))
  1553. #### RNA seq cohorts to include: GSE102556, GSE202537, GSE243356, GSE247998, GSE101521, GSE213982, GSE144136, GSE248260 (limma-voom (RNAseq specific))
  1554. # genome version in records:
  1555. # GSE102556 hg19 n>240
  1556. # GSE243356 most likely hg19 n=61
  1557. # GSE248260 hg19 n=24 # Macedonian/New York State Psychiatric Institute Brain Collection
  1558. # GSE247998 hg19 n=100 # Study participants were adults 20–65 years old and were recruited in the New York metropolitan area by advertising, via the Columbia University Medical Center Portal
  1559. # GSE202537 hg38 n=215
  1560. # GSE101521 hg19 n=86
  1561. # Single cell GSE144136
  1562. # Single cell GSE213982
  1563. # Criteria: More than 5 suicide cases
  1564. # Criteria: Individual signals/counts are available
  1565. # Criteria: Study/Methods allow comparison between suicide and control
  1566. # Criteria: Human samples only
  1567. # Single cell (separate)
  1568. # GSE144136 (SC) MDD vs control (suicide)
  1569. # GSE213982 (SC) MDD vs control (suicide)
  1570. #### Competitor: https://www.sciencedirect.com/science/article/pii/S0924977X21016631?via%3Dihub#sec0002
  1571. # competitor cohorts:
  1572. # GSE5389
  1573. # GSE5388
  1574. # GSE66937
  1575. # GSE102556
  1576. # GSE92538
  1577. #### Inspection of datasets from https://www.sciencedirect.com/science/article/pii/S0022395621000480?via%3Dihub (post-analysis)
  1578. # GSE21138 - no clear evidence for suicide in samples on GEO, paper has potentially matchable variables in the supplement https://www.sciencedirect.com/science/article/pii/S0006899308019410?via%3Dihub#app1
  1579. # GSE92538 - used by us
  1580. # GSE53987 - no clear evidence for suicide in samples on GEO, paper has NO variables (only grouped): https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0121744#pone-0121744-t001
  1581. # GSE54567 - no clear evidence for suicide in samples on GEO, paper does not show variables (shared https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0090980)
  1582. # GSE54568 - no clear evidence for suicide in samples on GEO, paper does not show variables (shared https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0090980)
  1583. # GSE5388 - used by us
  1584. # GSE5389 - used by us
  1585. # GSE54570 - no clear evidence for suicide in samples on GEO, paper does not show variables (shared https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0090980)
  1586. # SMRI 2 and SMRI 7 were not available as www.stanleyresearch.org was not responsive
  1587. # Conclusion -> GSE21138 could be theoretically useful due to 13 suicide cases however does not fit inclusion protocol based on GEO search
  1588. # Other datasets have no readily available infromation on suicide or already used by us
  1589. ################### Importing DE summary stats ###################
  1590. summary_paths_no_covar = list.files(path = "Data_preprocessing_analysis", recursive = TRUE, full.names = TRUE)
  1591. summary_paths_no_covar = summary_paths_no_covar[stri_detect_fixed(summary_paths_no_covar, pattern = "no_covar")]
  1592. summary_paths_no_covar = summary_paths_no_covar[!stri_detect_fixed(summary_paths_no_covar, pattern = "_SV")]
  1593. summary_paths_no_covar = summary_paths_no_covar[!stri_detect_fixed(summary_paths_no_covar, pattern = "_cell_types")]
  1594. summary_paths_with_covar = list.files(path = "Data_preprocessing_analysis", recursive = TRUE, full.names = TRUE)
  1595. summary_paths_with_covar = summary_paths_with_covar[stri_detect_fixed(summary_paths_with_covar, pattern = "Top_table")]
  1596. summary_paths_with_covar = summary_paths_with_covar[!stri_detect_fixed(summary_paths_with_covar, pattern = "_SV")]
  1597. summary_paths_with_covar = summary_paths_with_covar[!stri_detect_fixed(summary_paths_with_covar, pattern = "no_covar")]
  1598. summary_paths_cell_types = list.files(path = "Data_preprocessing_analysis", recursive = TRUE, full.names = TRUE)
  1599. summary_paths_cell_types = summary_paths_cell_types[stri_detect_fixed(summary_paths_cell_types, pattern = "_cell_types")]
  1600. data_list_no_covar = lapply(summary_paths_no_covar, function(x){
  1601. study_name = unlist(stri_split_fixed(x, pattern = "/"))
  1602. study_name = study_name[length(study_name)]
  1603. study_name = stri_replace_all_fixed(study_name, pattern = "_Top_table_no_covar.csv", replacement = "")
  1604. x = smart_fread(x)
  1605. x$Study = study_name
  1606. return(x)
  1607. })
  1608. reference_colnames = colnames(data_list_no_covar[[1]])
  1609. data_list_no_covar = lapply(data_list_no_covar, function(x){
  1610. if ("Gene_symbol_non_hgnc" %!in% colnames(x)){
  1611. x$Gene_symbol_non_hgnc = NA
  1612. }
  1613. x = x[,reference_colnames]
  1614. return(x)
  1615. })
  1616. data_list_with_covar = lapply(summary_paths_with_covar, function(x){
  1617. study_name = unlist(stri_split_fixed(x, pattern = "/"))
  1618. study_name = study_name[length(study_name)]
  1619. study_name = stri_replace_all_fixed(study_name, pattern = "_Top_table.csv", replacement = "")
  1620. x = smart_fread(x)
  1621. x$Study = study_name
  1622. return(x)
  1623. })
  1624. reference_colnames = colnames(data_list_with_covar[[1]])
  1625. data_list_with_covar = lapply(data_list_with_covar, function(x){
  1626. if ("Gene_symbol_non_hgnc" %!in% colnames(x)){
  1627. x$Gene_symbol_non_hgnc = NA
  1628. }
  1629. x = x[,reference_colnames]
  1630. return(x)
  1631. })
  1632. data_list_cell_types = lapply(summary_paths_cell_types, function(x){
  1633. study_name = unlist(stri_split_fixed(x, pattern = "/"))
  1634. study_name = study_name[length(study_name)]
  1635. study_name = stri_replace_all_fixed(study_name, pattern = "_Top_table_no_covar_cell_types.csv", replacement = "")
  1636. x = smart_fread(x)
  1637. x$Study = study_name
  1638. return(x)
  1639. })
  1640. data_list_cell_types = lapply(data_list_cell_types, function(x){
  1641. if ("Gene_symbol_non_hgnc" %!in% colnames(x)){
  1642. x$Gene_symbol_non_hgnc = NA
  1643. }
  1644. x = x[,reference_colnames]
  1645. return(x)
  1646. })
  1647. # SV datasets
  1648. summary_paths_SV = list.files(path = "Data_preprocessing_analysis", recursive = TRUE, full.names = TRUE)
  1649. summary_paths_SV = summary_paths_SV[stri_detect_fixed(summary_paths_SV, pattern = "Top_table")]
  1650. summary_paths_SV = summary_paths_SV[stri_detect_fixed(summary_paths_SV, pattern = "_SV")]
  1651. data_list_SV = lapply(summary_paths_SV, function(x){
  1652. study_name = unlist(stri_split_fixed(x, pattern = "/"))
  1653. study_name = study_name[length(study_name)]
  1654. study_name = stri_replace_all_fixed(study_name, pattern = "_Top_table_SV.csv", replacement = "")
  1655. x = smart_fread(x)
  1656. x$Study = study_name
  1657. return(x)
  1658. })
  1659. reference_colnames = colnames(data_list_SV[[1]])
  1660. data_list_SV = lapply(data_list_SV, function(x){
  1661. if ("Gene_symbol_non_hgnc" %!in% colnames(x)){
  1662. x$Gene_symbol_non_hgnc = NA
  1663. }
  1664. x = x[,reference_colnames]
  1665. return(x)
  1666. })
  1667. ################### Harmonizing gene names ###################
  1668. gene_names_no_covar = lapply(data_list_no_covar, function(x){
  1669. gene_symbols = x$Gene_symbol
  1670. gene_symbols_non_HGNC = x$Gene_symbol_non_hgnc
  1671. gene_symbols_all = c(gene_symbols, gene_symbols_non_HGNC)
  1672. gene_symbols_all = unlist(gene_symbols_all)
  1673. gene_symbols_all = unique(gene_symbols_all)
  1674. gene_symbols_all = unlist(stri_split_fixed(gene_symbols_all, pattern = ";"))
  1675. gene_symbols_all = gene_symbols_all[!is.na(gene_symbols_all)]
  1676. gene_symbols_all = gene_symbols_all[gene_symbols_all != ""]
  1677. gene_symbols_all = gene_symbols_all[gene_symbols_all != " "]
  1678. gene_symbols_all = gene_symbols_all[gene_symbols_all != "NA"]
  1679. return(gene_symbols_all)
  1680. })
  1681. gene_names_no_covar = unlist(gene_names_no_covar)
  1682. gene_names_no_covar = unique(gene_names_no_covar)
  1683. gene_names_with_covar = lapply(data_list_with_covar, function(x){
  1684. gene_symbols = x$Gene_symbol
  1685. gene_symbols_non_HGNC = x$Gene_symbol_non_hgnc
  1686. gene_symbols_all = c(gene_symbols, gene_symbols_non_HGNC)
  1687. gene_symbols_all = unlist(gene_symbols_all)
  1688. gene_symbols_all = unique(gene_symbols_all)
  1689. gene_symbols_all = unlist(stri_split_fixed(gene_symbols_all, pattern = ";"))
  1690. gene_symbols_all = gene_symbols_all[!is.na(gene_symbols_all)]
  1691. gene_symbols_all = gene_symbols_all[gene_symbols_all != ""]
  1692. gene_symbols_all = gene_symbols_all[gene_symbols_all != " "]
  1693. gene_symbols_all = gene_symbols_all[gene_symbols_all != "NA"]
  1694. return(gene_symbols_all)
  1695. })
  1696. gene_names_with_covar = unlist(gene_names_with_covar)
  1697. gene_names_with_covar = unique(gene_names_with_covar)
  1698. gene_names_from_sv = lapply(data_list_SV, function(x){
  1699. gene_symbols = x$Gene_symbol
  1700. gene_symbols_non_HGNC = x$Gene_symbol_non_hgnc
  1701. gene_symbols_all = c(gene_symbols, gene_symbols_non_HGNC)
  1702. gene_symbols_all = unlist(gene_symbols_all)
  1703. gene_symbols_all = unique(gene_symbols_all)
  1704. gene_symbols_all = unlist(stri_split_fixed(gene_symbols_all, pattern = ";"))
  1705. gene_symbols_all = gene_symbols_all[!is.na(gene_symbols_all)]
  1706. gene_symbols_all = gene_symbols_all[gene_symbols_all != ""]
  1707. gene_symbols_all = gene_symbols_all[gene_symbols_all != " "]
  1708. gene_symbols_all = gene_symbols_all[gene_symbols_all != "NA"]
  1709. return(gene_symbols_all)
  1710. })
  1711. gene_names_from_sv = unlist(gene_names_from_sv)
  1712. gene_names_from_sv = unique(gene_names_from_sv)
  1713. gene_names_full = c(gene_names_no_covar, gene_names_with_covar, gene_names_from_sv)
  1714. gene_names_full = unique(gene_names_full)
  1715. harmoniz_genes_check = check_gene_symbol_NIH(PRF_gene_symbols = gene_names_full,
  1716. PRF_ref_NIH_expanded = Homo_Sapiens_Gene_info_NIH_expanded,
  1717. PRF_replace_NA_with_old = TRUE)
  1718. harmoniz_genes_check_dict = harmoniz_genes_check$Suggested.Symbol
  1719. names(harmoniz_genes_check_dict) = harmoniz_genes_check$x
  1720. combined_df_no_covar = do.call(rbind, data_list_no_covar)
  1721. combined_df_wth_covar = do.call(rbind, data_list_with_covar)
  1722. combined_df_cell_types = do.call(rbind, data_list_cell_types)
  1723. combined_df_no_covar$Corrected_symbol = mapply(function(x,y){
  1724. combined_symbols = c(x, y)
  1725. combined_symbols = combined_symbols[!is.na(combined_symbols)]
  1726. if (length(combined_symbols)<1){
  1727. return(NA)
  1728. }
  1729. combined_symbols = stri_split_fixed(combined_symbols, pattern = ";")
  1730. combined_symbols = unlist(combined_symbols)
  1731. combined_symbols = combined_symbols[combined_symbols!= ""]
  1732. combined_symbols = combined_symbols[combined_symbols!= " "]
  1733. combined_symbols = combined_symbols[combined_symbols!= "NA"]
  1734. verified_symbols = sapply(combined_symbols, function(x) harmoniz_genes_check_dict[x])
  1735. verified_symbols = unique(verified_symbols)
  1736. verified_symbols = paste0(verified_symbols, collapse = ";")
  1737. return(verified_symbols)
  1738. }, combined_df_no_covar$Gene_symbol, combined_df_no_covar$Gene_symbol_non_hgnc)
  1739. combined_df_wth_covar$Corrected_symbol = mapply(function(x,y){
  1740. combined_symbols = c(x, y)
  1741. combined_symbols = combined_symbols[!is.na(combined_symbols)]
  1742. if (length(combined_symbols)<1){
  1743. return(NA)
  1744. }
  1745. combined_symbols = stri_split_fixed(combined_symbols, pattern = ";")
  1746. combined_symbols = unlist(combined_symbols)
  1747. combined_symbols = combined_symbols[combined_symbols!= ""]
  1748. combined_symbols = combined_symbols[combined_symbols!= " "]
  1749. combined_symbols = combined_symbols[combined_symbols!= "NA"]
  1750. verified_symbols = sapply(combined_symbols, function(x) harmoniz_genes_check_dict[x])
  1751. verified_symbols = unique(verified_symbols)
  1752. verified_symbols = paste0(verified_symbols, collapse = ";")
  1753. return(verified_symbols)
  1754. }, combined_df_wth_covar$Gene_symbol, combined_df_wth_covar$Gene_symbol_non_hgnc)
  1755. combined_df_cell_types$Corrected_symbol = mapply(function(x,y){
  1756. combined_symbols = c(x, y)
  1757. combined_symbols = combined_symbols[!is.na(combined_symbols)]
  1758. if (length(combined_symbols)<1){
  1759. return(NA)
  1760. }
  1761. combined_symbols = stri_split_fixed(combined_symbols, pattern = ";")
  1762. combined_symbols = unlist(combined_symbols)
  1763. combined_symbols = combined_symbols[combined_symbols!= ""]
  1764. combined_symbols = combined_symbols[combined_symbols!= " "]
  1765. combined_symbols = combined_symbols[combined_symbols!= "NA"]
  1766. verified_symbols = sapply(combined_symbols, function(x) harmoniz_genes_check_dict[x])
  1767. verified_symbols = unique(verified_symbols)
  1768. verified_symbols = paste0(verified_symbols, collapse = ";")
  1769. return(verified_symbols)
  1770. }, combined_df_cell_types$Gene_symbol, combined_df_cell_types$Gene_symbol_non_hgnc)
  1771. # Harmonizing symbols for SV dataset
  1772. combined_df_SV = do.call(rbind, data_list_SV)
  1773. dim(combined_df_no_covar)[1] == dim(combined_df_SV)[1] # TRUE -> All genes are already covered in harmoniz_genes_check_dict
  1774. combined_df_SV$Corrected_symbol = mapply(function(x,y){
  1775. combined_symbols = c(x, y)
  1776. combined_symbols = combined_symbols[!is.na(combined_symbols)]
  1777. if (length(combined_symbols)<1){
  1778. return(NA)
  1779. }
  1780. combined_symbols = stri_split_fixed(combined_symbols, pattern = ";")
  1781. combined_symbols = unlist(combined_symbols)
  1782. combined_symbols = combined_symbols[combined_symbols!= ""]
  1783. combined_symbols = combined_symbols[combined_symbols!= " "]
  1784. combined_symbols = combined_symbols[combined_symbols!= "NA"]
  1785. verified_symbols = sapply(combined_symbols, function(x) harmoniz_genes_check_dict[x])
  1786. verified_symbols = unique(verified_symbols)
  1787. verified_symbols = paste0(verified_symbols, collapse = ";")
  1788. return(verified_symbols)
  1789. }, combined_df_SV$Gene_symbol, combined_df_SV$Gene_symbol_non_hgnc)
  1790. ################### Correcting cell type df ###################
  1791. combined_df_cell_types$Cell_type = stri_replace_all_fixed(combined_df_cell_types$Tissue, pattern = "Dorsolateral prefrontal cortex (BA9): ", replacement = "")
  1792. combined_df_cell_types$Study_Cell = paste0(combined_df_cell_types$Study, ": ", combined_df_cell_types$Cell_type)
  1793. table(combined_df_cell_types$Cell_type)
  1794. "
  1795. Ast End ExN InN Mic Mix Oli OPC
  1796. 8510 6145 34875 26001 2093 1305 9025 6806
  1797. "
  1798. # Ast -astrocyte
  1799. # End - endothelial
  1800. # ExN - excitatory neuron
  1801. # InN - inhibitory neuron
  1802. # Mic - microglia
  1803. # Mix - mixed expression profile
  1804. # Oli - oligodendrocytes
  1805. # OPC - oligodendrocyte precursor cells
  1806. combined_df_cell_types_meta = combined_df_cell_types %>%
  1807. group_by(.,Study_Cell, Corrected_symbol) %>%
  1808. summarise(.,avgLog2FC = mean(logFC),
  1809. maxSE = max(SE))
  1810. combined_df_cell_types_meta = ungroup(combined_df_cell_types_meta)
  1811. combined_df_cell_types_meta = as.data.frame(combined_df_cell_types_meta)
  1812. ################### Cohort stats on individual datasets ###################
  1813. length(unique(combined_df_no_covar$Study))
  1814. length(unique(combined_df_wth_covar$Study))
  1815. length(unique(combined_df_SV$Study))
  1816. studies = unique(combined_df_no_covar$Study)
  1817. cohort_stats_vector_no_covariates = vector()
  1818. for (i in 1:length(studies)){
  1819. separator_large = "\n\n"
  1820. if (i == 1){
  1821. string_1 = paste0("Total associations without covariates: ", nrow(combined_df_no_covar))
  1822. string_2 = paste0("Total significant associations (nominal) without covariates: ", nrow(combined_df_no_covar[combined_df_no_covar$P.Value<=0.05,]))
  1823. string_3 = paste0("Average absolute effect size (log2FC) without covariates: ", mean(abs(combined_df_no_covar$logFC)))
  1824. string_4 = paste0("Average absolute effect size (log2FC) (nominal significance) without covariates: ", mean(abs(combined_df_no_covar[combined_df_no_covar$P.Value<=0.05,"logFC"])))
  1825. cohort_stats_vector_no_covariates = c(string_1, string_2, string_3, string_4, separator_large)
  1826. }
  1827. TMP_current_cohort = studies[i]
  1828. TMP_current_dataset = combined_df_no_covar[combined_df_no_covar$Study == TMP_current_cohort,]
  1829. TMP_study_type = unique(TMP_current_dataset$Tissue_type)
  1830. TMP_tech_type = unique(TMP_current_dataset$Technology)
  1831. main_header = paste(c(TMP_current_cohort, TMP_study_type, TMP_tech_type), collapse = "\t")
  1832. aggregated_stats = TMP_current_dataset %>%
  1833. group_by(.,Tissue) %>%
  1834. summarise(
  1835. total_associations = length(ID),
  1836. unique_gene_symbols_p_lt_0_05 = n_distinct(Gene_symbol[P.Value <= 0.05]),
  1837. unique_IDs_p_lt_0_05 = n_distinct(ID[P.Value <= 0.05]),
  1838. unique_gene_symbols_adj_p_lt_0_05 = n_distinct(Gene_symbol[adj.P.Val <= 0.05]),
  1839. unique_IDs_adj_p_lt_0_05 = n_distinct(ID[adj.P.Val <= 0.05]),
  1840. mean_abs_log2FC = mean(abs(logFC)),
  1841. mean_abs_log2FC_nomin_signif = mean(abs(logFC[P.Value <= 0.05]))
  1842. )
  1843. aggregated_stats = as.data.frame(aggregated_stats)
  1844. header = paste(colnames(aggregated_stats), collapse = "\t")
  1845. # char_aggregated_stats = apply(aggregated_stats, 1, function(x) paste(x, collapse = "\t"))
  1846. char_aggregated_stats = knitr::kable(aggregated_stats)
  1847. cohort_stats_vector_no_covariates = c(cohort_stats_vector_no_covariates, main_header, char_aggregated_stats, separator_large)
  1848. if (i == length(studies)){
  1849. cohort_stats_vector_no_covariates = c(cohort_stats_vector_no_covariates, separator_large)
  1850. }
  1851. }
  1852. writeLines(text = cohort_stats_vector_no_covariates, con = "individual_DE_stats_no_covar.txt")
  1853. cohort_stats_vector_with_covariates = vector()
  1854. for (i in 1:length(studies)){
  1855. separator_large = "\n\n"
  1856. if (i == 1){
  1857. string_1 = paste0("Total associations with covariates: ", nrow(combined_df_wth_covar))
  1858. string_2 = paste0("Total significant associations (nominal) with covariates: ", nrow(combined_df_wth_covar[combined_df_wth_covar$P.Value<0.05,]))
  1859. string_3 = paste0("Average absolute effect size (log2FC) with covariates: ", mean(abs(combined_df_wth_covar$logFC)))
  1860. string_4 = paste0("Average absolute effect size (log2FC) (nominal significance) with covariates: ", mean(abs(combined_df_wth_covar[combined_df_wth_covar$P.Value<0.05,"logFC"])))
  1861. cohort_stats_vector_with_covariates = c(string_1, string_2, string_3, string_4, separator_large)
  1862. }
  1863. TMP_current_cohort = studies[i]
  1864. TMP_current_dataset = combined_df_wth_covar[combined_df_wth_covar$Study == TMP_current_cohort,]
  1865. TMP_study_type = unique(TMP_current_dataset$Tissue_type)
  1866. TMP_tech_type = unique(TMP_current_dataset$Technology)
  1867. main_header = paste(c(TMP_current_cohort, TMP_study_type, TMP_tech_type), collapse = "\t")
  1868. aggregated_stats = TMP_current_dataset %>%
  1869. group_by(.,Tissue) %>%
  1870. summarise(
  1871. total_associations = length(ID),
  1872. unique_gene_symbols_p_lt_0_05 = n_distinct(Gene_symbol[P.Value < 0.05]),
  1873. unique_IDs_p_lt_0_05 = n_distinct(ID[P.Value < 0.05]),
  1874. unique_gene_symbols_adj_p_lt_0_05 = n_distinct(Gene_symbol[adj.P.Val < 0.05]),
  1875. unique_IDs_adj_p_lt_0_05 = n_distinct(ID[adj.P.Val < 0.05]),
  1876. mean_abs_log2FC = mean(abs(logFC)),
  1877. mean_abs_log2FC_nomin_signif = mean(abs(logFC[P.Value < 0.05]))
  1878. )
  1879. aggregated_stats = as.data.frame(aggregated_stats)
  1880. header = paste(colnames(aggregated_stats), collapse = "\t")
  1881. # char_aggregated_stats = apply(aggregated_stats, 1, function(x) paste(x, collapse = "\t"))
  1882. char_aggregated_stats = knitr::kable(aggregated_stats)
  1883. cohort_stats_vector_with_covariates = c(cohort_stats_vector_with_covariates, main_header, char_aggregated_stats, separator_large)
  1884. if (i == length(studies)){
  1885. cohort_stats_vector_with_covariates = c(cohort_stats_vector_with_covariates, separator_large)
  1886. }
  1887. }
  1888. writeLines(text = cohort_stats_vector_with_covariates, con = "individual_DE_stats_with_covar.txt")
  1889. cohort_stats_vector_SV = vector()
  1890. for (i in 1:length(studies)){
  1891. separator_large = "\n\n"
  1892. if (i == 1){
  1893. string_1 = paste0("Total associations using surrogate varaibles (SVs): ", nrow(combined_df_SV))
  1894. string_2 = paste0("Total significant associations (nominal) with SVs: ", nrow(combined_df_SV[combined_df_SV$P.Value<0.05,]))
  1895. string_3 = paste0("Average absolute effect size (log2FC) with SVs: ", mean(abs(combined_df_SV$logFC)))
  1896. string_4 = paste0("Average absolute effect size (log2FC) (nominal significance) with SVs: ", mean(abs(combined_df_SV[combined_df_SV$P.Value<0.05,"logFC"])))
  1897. cohort_stats_vector_SV = c(string_1, string_2, string_3, string_4, separator_large)
  1898. }
  1899. TMP_current_cohort = studies[i]
  1900. TMP_current_dataset = combined_df_SV[combined_df_SV$Study == TMP_current_cohort,]
  1901. TMP_study_type = unique(TMP_current_dataset$Tissue_type)
  1902. TMP_tech_type = unique(TMP_current_dataset$Technology)
  1903. main_header = paste(c(TMP_current_cohort, TMP_study_type, TMP_tech_type), collapse = "\t")
  1904. aggregated_stats = TMP_current_dataset %>%
  1905. group_by(.,Tissue) %>%
  1906. summarise(
  1907. total_associations = length(ID),
  1908. unique_gene_symbols_p_lt_0_05 = n_distinct(Gene_symbol[P.Value < 0.05]),
  1909. unique_IDs_p_lt_0_05 = n_distinct(ID[P.Value < 0.05]),
  1910. unique_gene_symbols_adj_p_lt_0_05 = n_distinct(Gene_symbol[adj.P.Val < 0.05]),
  1911. unique_IDs_adj_p_lt_0_05 = n_distinct(ID[adj.P.Val < 0.05]),
  1912. mean_abs_log2FC = mean(abs(logFC)),
  1913. mean_abs_log2FC_nomin_signif = mean(abs(logFC[P.Value < 0.05]))
  1914. )
  1915. aggregated_stats = as.data.frame(aggregated_stats)
  1916. header = paste(colnames(aggregated_stats), collapse = "\t")
  1917. # char_aggregated_stats = apply(aggregated_stats, 1, function(x) paste(x, collapse = "\t"))
  1918. char_aggregated_stats = knitr::kable(aggregated_stats)
  1919. cohort_stats_vector_SV = c(cohort_stats_vector_SV, main_header, char_aggregated_stats, separator_large)
  1920. if (i == length(studies)){
  1921. cohort_stats_vector_SV = c(cohort_stats_vector_SV, separator_large)
  1922. }
  1923. }
  1924. writeLines(text = cohort_stats_vector_SV, con = "individual_DE_stats_SV.txt")
  1925. ################### Cohort inspection for specificity ###################
  1926. table(combined_df_no_covar$Tissue, combined_df_no_covar$Study)
  1927. # GSE101521 -> dorsal lateral prefrontal cortex (Brodmann Area 9) "with an attempt to enrich for gray matter" "samples inevitably also contained a small amount of white matter"
  1928. # GSE102556 -> many regions, no specifics on gray/white
  1929. # GSE144136 -> single cell, "Frozen gray matter samples were dissected from Brodmann area 9 (dlPFC)"
  1930. # GSE199536 -> habenula. "4.4 Habenula In 1872 he described a small mass of grey matter", paper does not specify
  1931. # GSE202537 -> several striatal regions, no specifics on gray/white matter content
  1932. # GSE208338 -> no original paper, GEO: "Total RNA was isolated from ∼100 mg frozen gray matter using 1.0 ml TRIzol reagent"
  1933. # GSE213982 -> "Frozen histological grade samples of gray and white matter were dissected from the dlPFC (Brodmann Area 9)" -> mixed matters
  1934. # GSE243356 -> "The temporal pole, Brodmann Area 20, gray and white matter were dissected for the assays" -> mix of matters
  1935. # Since the dissected brain gyri fold in three dimensions, it is impossible to exclude all white matter while still taking the full thickness (~ 3 mm) of the cortical"
  1936. # GSE247998 -> blood
  1937. # GSE248260 -> ventral white matter (BA 47) -> gray matter was not provided
  1938. # GSE5388 -> DLPFC (BA9) no specifics on gray/white matter content
  1939. # GSE5389 -> OFC (BA11) no specifics on gray/white matter content
  1940. # GSE66937 -> no original paper, no specifics on gray/white matter content, has technical replicates!
  1941. # GSE92538_U133A -> predominantly gray matter, has samples on 2 arrays
  1942. # GSE92538_U133_PLUS2 -> predominantly gray matter, has samples on 2 arrays
  1943. ################### GSE92538 inspection ###################
  1944. GSE92538_U133A = read.csv("Data_preprocessing_analysis/GSE92538_U133A_results/GSE92538_pheno_curated.csv")
  1945. rownames(GSE92538_U133A) = GSE92538_U133A$X
  1946. GSE92538_U133A$X = NULL
  1947. nrow(GSE92538_U133A) # 97
  1948. GSE92538_U133_PLUS2 = read.csv("Data_preprocessing_analysis/GSE92538_U133_PLUS2_results/GSE92538_pheno_curated.csv")
  1949. rownames(GSE92538_U133_PLUS2) = GSE92538_U133_PLUS2$X
  1950. GSE92538_U133_PLUS2$X = NULL
  1951. nrow(GSE92538_U133_PLUS2) # 75
  1952. any(duplicated(GSE92538_U133A$SUBJECT_ID)) # FALSE
  1953. any(duplicated(GSE92538_U133_PLUS2$SUBJECT_ID)) # FALSE
  1954. length(intersect(GSE92538_U133A$SUBJECT_ID, GSE92538_U133_PLUS2$SUBJECT_ID))
  1955. # 0 samples are duplicated
  1956. ################### RRA (all brain, no covar, test) ###################
  1957. # This is a non-paramentic approach to aggregate ranked lists
  1958. combined_df_no_covar_RRA_all = combined_df_no_covar
  1959. combined_df_no_covar_RRA_all = combined_df_no_covar_RRA_all[combined_df_no_covar_RRA_all$Tissue_type == "Brain",]
  1960. table(combined_df_no_covar_RRA_all$Tissue, combined_df_no_covar_RRA_all$Study)
  1961. # GSE102556 many tissues
  1962. # GSE202537 many tissues
  1963. # GSE66937 many tissues
  1964. combined_df_no_covar_RRA_all_1 = combined_df_no_covar_RRA_all[combined_df_no_covar_RRA_all$Study %!in% c("GSE102556", "GSE202537", "GSE66937"), ]
  1965. combined_df_no_covar_RRA_all_2 = combined_df_no_covar_RRA_all[combined_df_no_covar_RRA_all$Study %in% c("GSE102556", "GSE202537", "GSE66937"), ]
  1966. # Caudate https://pubmed.ncbi.nlm.nih.gov/39164232/
  1967. # Nac https://pubmed.ncbi.nlm.nih.gov/38894648/ https://pubmed.ncbi.nlm.nih.gov/38965529/ https://pubmed.ncbi.nlm.nih.gov/39167467/
  1968. # GSE102556 -> Dorsolateral prefrontal cortex (dlPFC; BA8/9)
  1969. # GSE202537 -> Nac 22652 (more probes analyzed)
  1970. # GSE66937 -> prefrontal cortex
  1971. combined_df_no_covar_RRA_all_2 = combined_df_no_covar_RRA_all_2[combined_df_no_covar_RRA_all_2$Tissue %in% c("Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  1972. "Nac",
  1973. "prefrontal cortex"),]
  1974. table(combined_df_no_covar_RRA_all_2$Tissue)
  1975. "
  1976. Dorsolateral prefrontal cortex (dlPFC; BA8/9) Nac prefrontal cortex
  1977. 21365 22652 70523
  1978. "
  1979. combined_df_no_covar_RRA_all = rbind(combined_df_no_covar_RRA_all_1, combined_df_no_covar_RRA_all_2)
  1980. table(combined_df_no_covar_RRA_all$Tissue, combined_df_no_covar_RRA_all$Study)
  1981. combined_df_no_covar_RRA_all_list = lapply(unique(combined_df_no_covar_RRA_all$Study), function(x){
  1982. df = combined_df_no_covar_RRA_all[combined_df_no_covar_RRA_all$Study == x,]
  1983. return(df)
  1984. })
  1985. combined_df_no_covar_RRA_all_list_reduced = lapply(combined_df_no_covar_RRA_all_list, function(x){
  1986. orig_df = x
  1987. x = x[!stri_detect_fixed(x$Corrected_symbol, pattern = ";"),]
  1988. x = x[!is.na(x$Corrected_symbol),]
  1989. x = x[x$Corrected_symbol != "",]
  1990. x = x %>%
  1991. dplyr::group_by(., Corrected_symbol)%>%
  1992. dplyr::summarise(.,
  1993. avgLog2FC = mean(logFC),
  1994. maxP = max(P.Value)) # Most conservative
  1995. x = dplyr::ungroup(x)
  1996. x$Tissue = unique(orig_df$Tissue)
  1997. x$Tissue_type = unique(orig_df$Tissue_type)
  1998. x$Technology = unique(orig_df$Technology)
  1999. x$Study = unique(orig_df$Study)
  2000. x = as.data.frame(x)
  2001. x = dplyr::arrange(x, maxP)
  2002. return(x)
  2003. })
  2004. combined_df_no_covar_RRA_all_list_reduced = do.call(rbind, combined_df_no_covar_RRA_all_list_reduced)
  2005. total_number = length(unique(combined_df_no_covar_RRA_all_list_reduced$Corrected_symbol))
  2006. combined_df_no_covar_RRA_all_list_reduced_positive = combined_df_no_covar_RRA_all_list_reduced[combined_df_no_covar_RRA_all_list_reduced$avgLog2FC > 0,]
  2007. combined_df_no_covar_RRA_all_list_reduced_negative = combined_df_no_covar_RRA_all_list_reduced[combined_df_no_covar_RRA_all_list_reduced$avgLog2FC < 0,]
  2008. list_sizes = combined_df_no_covar_RRA_all_list_reduced_positive %>%
  2009. group_by(., Study) %>%
  2010. summarize(N=length(Corrected_symbol)) %>%
  2011. ungroup(.)
  2012. mean(list_sizes$N)
  2013. list_sizes = combined_df_no_covar_RRA_all_list_reduced_negative %>%
  2014. group_by(., Study) %>%
  2015. summarize(N=length(Corrected_symbol)) %>%
  2016. ungroup(.)
  2017. mean(list_sizes$N)
  2018. studies = unique(combined_df_no_covar_RRA_all_list_reduced_positive$Study)
  2019. no_covar_RRA_gene_lists_positive = lapply(studies, function(x){
  2020. tmp_df = combined_df_no_covar_RRA_all_list_reduced_positive[combined_df_no_covar_RRA_all_list_reduced_positive$Study == x,]
  2021. tmp_df = dplyr::arrange(tmp_df, maxP)
  2022. ranked_list = tmp_df$Corrected_symbol
  2023. return(ranked_list)
  2024. })
  2025. no_covar_RRA_gene_lists_positive_top = lapply(studies, function(x){
  2026. tmp_df = combined_df_no_covar_RRA_all_list_reduced_positive[combined_df_no_covar_RRA_all_list_reduced_positive$Study == x,]
  2027. tmp_df = dplyr::arrange(tmp_df, maxP)
  2028. tmp_df = tmp_df[tmp_df$maxP<0.05,]
  2029. ranked_list = tmp_df$Corrected_symbol
  2030. return(ranked_list)
  2031. })
  2032. studies = unique(combined_df_no_covar_RRA_all_list_reduced_negative$Study)
  2033. no_covar_RRA_gene_lists_negative = lapply(studies, function(x){
  2034. tmp_df = combined_df_no_covar_RRA_all_list_reduced_negative[combined_df_no_covar_RRA_all_list_reduced_negative$Study == x,]
  2035. tmp_df = dplyr::arrange(tmp_df, maxP)
  2036. ranked_list = tmp_df$Corrected_symbol
  2037. return(ranked_list)
  2038. })
  2039. no_covar_RRA_gene_lists_negative_top = lapply(studies, function(x){
  2040. tmp_df = combined_df_no_covar_RRA_all_list_reduced_negative[combined_df_no_covar_RRA_all_list_reduced_negative$Study == x,]
  2041. tmp_df = dplyr::arrange(tmp_df, maxP)
  2042. tmp_df = tmp_df[tmp_df$maxP<0.05,]
  2043. ranked_list = tmp_df$Corrected_symbol
  2044. return(ranked_list)
  2045. })
  2046. RRA_no_covar_all_brain_positive = aggregateRanks(glist = no_covar_RRA_gene_lists_positive, full = TRUE)
  2047. RRA_no_covar_all_brain_positive$P.adjusted = p.adjust(RRA_no_covar_all_brain_positive$Score, method = "fdr")
  2048. RRA_no_covar_all_brain_positive$N.cohorts = sapply(RRA_no_covar_all_brain_positive$Name, function(x){
  2049. internal_count = sapply(no_covar_RRA_gene_lists_positive, function(sublist) x %in% sublist)
  2050. internal_count = unlist(internal_count)
  2051. internal_count = as.numeric(internal_count)
  2052. internal_count = sum(internal_count)
  2053. return(internal_count)
  2054. })
  2055. RRA_no_covar_all_brain_negative = aggregateRanks(glist = no_covar_RRA_gene_lists_negative, full = TRUE)
  2056. RRA_no_covar_all_brain_negative$P.adjusted = p.adjust(RRA_no_covar_all_brain_negative$Score, method = "fdr")
  2057. RRA_no_covar_all_brain_negative$N.cohorts = sapply(RRA_no_covar_all_brain_negative$Name, function(x){
  2058. internal_count = sapply(no_covar_RRA_gene_lists_positive, function(sublist) x %in% sublist)
  2059. internal_count = unlist(internal_count)
  2060. internal_count = as.numeric(internal_count)
  2061. internal_count = sum(internal_count)
  2062. return(internal_count)
  2063. })
  2064. # Subset interesting genes
  2065. candidates = c("P2RY12", "AC159540.14", "CX3CR1", "DEPP1", "FOS", "GPR34", "KLF4", "PMP2", "SOX9")
  2066. RRA_no_covar_all_brain_positive[RRA_no_covar_all_brain_positive$Name %in% candidates,]
  2067. RRA_no_covar_all_brain_negative[RRA_no_covar_all_brain_negative$Name %in% candidates,]
  2068. # ---> Add RRA in the meta-calculation as columns
  2069. add_RRA_to_meta_df = function(meta_df, initial_study_df_list){
  2070. # Reduce df for RRA (need p-values)
  2071. print("Reducing df")
  2072. initial_study_df_list_reduced = lapply(initial_study_df_list, function(x){
  2073. orig_df = x
  2074. x = x[!stri_detect_fixed(x$Corrected_symbol, pattern = ";"),]
  2075. x = x[!is.na(x$Corrected_symbol),]
  2076. x = x[x$Corrected_symbol != "",]
  2077. x = x %>%
  2078. dplyr::group_by(., Corrected_symbol)%>%
  2079. dplyr::summarise(.,
  2080. avgLog2FC = mean(logFC),
  2081. maxP = max(P.Value)) # Most conservative
  2082. x = dplyr::ungroup(x)
  2083. x$Tissue = unique(orig_df$Tissue)
  2084. x$Tissue_type = unique(orig_df$Tissue_type)
  2085. x$Technology = unique(orig_df$Technology)
  2086. x$Study = unique(orig_df$Study)
  2087. x = as.data.frame(x)
  2088. x = dplyr::arrange(x, maxP)
  2089. return(x)
  2090. })
  2091. initial_study_df_list_reduced = do.call(rbind, initial_study_df_list_reduced)
  2092. RRA_all_list_reduced_positive = initial_study_df_list_reduced[initial_study_df_list_reduced$avgLog2FC > 0,]
  2093. RRA_all_list_reduced_negative = initial_study_df_list_reduced[initial_study_df_list_reduced$avgLog2FC < 0,]
  2094. # Prepare ranked lists
  2095. studies = unique(RRA_all_list_reduced_positive$Study)
  2096. RRA_gene_lists_positive = lapply(studies, function(x){
  2097. tmp_df = RRA_all_list_reduced_positive[RRA_all_list_reduced_positive$Study == x,]
  2098. tmp_df = dplyr::arrange(tmp_df, maxP)
  2099. ranked_list = tmp_df$Corrected_symbol
  2100. return(ranked_list)
  2101. })
  2102. RRA_gene_lists_negative = lapply(studies, function(x){
  2103. tmp_df = RRA_all_list_reduced_negative[RRA_all_list_reduced_negative$Study == x,]
  2104. tmp_df = dplyr::arrange(tmp_df, maxP)
  2105. ranked_list = tmp_df$Corrected_symbol
  2106. return(ranked_list)
  2107. })
  2108. # Run for positive log2FC
  2109. print("Running RRA")
  2110. RRA_all_brain_positive = aggregateRanks(glist = RRA_gene_lists_positive, full = TRUE)
  2111. RRA_all_brain_positive$P.adjusted.RRA = p.adjust(RRA_all_brain_positive$Score, method = "fdr")
  2112. RRA_all_brain_positive$N.cohorts.RRA = sapply(RRA_all_brain_positive$Name, function(x){
  2113. internal_count = sapply(RRA_gene_lists_positive, function(sublist) x %in% sublist)
  2114. internal_count = unlist(internal_count)
  2115. internal_count = as.numeric(internal_count)
  2116. internal_count = sum(internal_count)
  2117. return(internal_count)
  2118. })
  2119. colnames(RRA_all_brain_positive) = c("Name_RRA", "P_RRA", "FDR_RRA", "N_cohorts_RRA")
  2120. # Run for negative log2FC
  2121. RRA_all_brain_negative = aggregateRanks(glist = RRA_gene_lists_negative, full = TRUE)
  2122. RRA_all_brain_negative$P.adjusted.RRA = p.adjust(RRA_all_brain_negative$Score, method = "fdr")
  2123. RRA_all_brain_negative$N.cohorts.RRA = sapply(RRA_all_brain_negative$Name, function(x){
  2124. internal_count = sapply(RRA_gene_lists_negative, function(sublist) x %in% sublist)
  2125. internal_count = unlist(internal_count)
  2126. internal_count = as.numeric(internal_count)
  2127. internal_count = sum(internal_count)
  2128. return(internal_count)
  2129. })
  2130. colnames(RRA_all_brain_negative) = c("Name_RRA", "P_RRA", "FDR_RRA", "N_cohorts_RRA")
  2131. # Attach stats to meta_df
  2132. print("Preparing attachment")
  2133. attachment = mclapply(meta_df$gene, function(x){
  2134. selected_subset = meta_df[meta_df$gene == x,]
  2135. selected_subset = selected_subset[1,] # always ensure 1st row
  2136. meta_LFc = selected_subset$meta_LFc[1]
  2137. cohorts_up = selected_subset$cohorts_up[1]
  2138. cohorts_down = selected_subset$cohorts_down[1]
  2139. if (is.na(meta_LFc)){
  2140. # Number of cohorts less than 5
  2141. # Consider cohort counts only
  2142. if (cohorts_up >= cohorts_down){
  2143. # Positive analysis
  2144. P_RRA = RRA_all_brain_positive[RRA_all_brain_positive$Name_RRA == x, "P_RRA"]
  2145. FDR_RRA = RRA_all_brain_positive[RRA_all_brain_positive$Name_RRA == x, "FDR_RRA"]
  2146. N_cohorts_RRA = RRA_all_brain_positive[RRA_all_brain_positive$Name_RRA == x, "N_cohorts_RRA"]
  2147. } else {
  2148. # Negative analysis
  2149. P_RRA = RRA_all_brain_negative[RRA_all_brain_negative$Name_RRA == x, "P_RRA"]
  2150. FDR_RRA = RRA_all_brain_negative[RRA_all_brain_negative$Name_RRA == x, "FDR_RRA"]
  2151. N_cohorts_RRA = RRA_all_brain_negative[RRA_all_brain_negative$Name_RRA == x, "N_cohorts_RRA"]
  2152. }
  2153. } else {
  2154. if (meta_LFc >= 0){
  2155. # Positive analysis
  2156. P_RRA = RRA_all_brain_positive[RRA_all_brain_positive$Name_RRA == x, "P_RRA"]
  2157. FDR_RRA = RRA_all_brain_positive[RRA_all_brain_positive$Name_RRA == x, "FDR_RRA"]
  2158. N_cohorts_RRA = RRA_all_brain_positive[RRA_all_brain_positive$Name_RRA == x, "N_cohorts_RRA"]
  2159. } else {
  2160. # Negative analysis
  2161. P_RRA = RRA_all_brain_negative[RRA_all_brain_negative$Name_RRA == x, "P_RRA"]
  2162. FDR_RRA = RRA_all_brain_negative[RRA_all_brain_negative$Name_RRA == x, "FDR_RRA"]
  2163. N_cohorts_RRA = RRA_all_brain_negative[RRA_all_brain_negative$Name_RRA == x, "N_cohorts_RRA"]
  2164. }
  2165. }
  2166. att_df_row = data.frame(
  2167. P_RRA = P_RRA,
  2168. FDR_RRA = FDR_RRA,
  2169. N_cohorts_RRA = N_cohorts_RRA
  2170. )
  2171. return(att_df_row)
  2172. }, mc.cores = 9)
  2173. attachment = do.call(rbind, attachment)
  2174. meta_df = cbind(meta_df, attachment)
  2175. return(meta_df)
  2176. }
  2177. ################### Meta-functions ###################
  2178. run_meta_SJ = function(initial_study_list, blood_df_to_compare){
  2179. # Reducing df for meta-analysis
  2180. print("Aggregating Log2FC and SE per gene per study")
  2181. initial_study_list_reduced = lapply(initial_study_list, function(x){
  2182. orig_df = x
  2183. x = x[!stri_detect_fixed(x$Corrected_symbol, pattern = ";"),]
  2184. x = x[!is.na(x$Corrected_symbol),]
  2185. x = x[x$Corrected_symbol != "",]
  2186. x = x %>%
  2187. dplyr::group_by(., Corrected_symbol)%>%
  2188. dplyr::summarise(.,
  2189. avgLog2FC = mean(logFC),
  2190. maxSE = max(SE))
  2191. x = dplyr::ungroup(x)
  2192. x$Tissue = unique(orig_df$Tissue)
  2193. x$Tissue_type = unique(orig_df$Tissue_type)
  2194. x$Technology = unique(orig_df$Technology)
  2195. x$Study = unique(orig_df$Study)
  2196. x = as.data.frame(x)
  2197. return(x)
  2198. })
  2199. initial_study_list_reduced = do.call(rbind, initial_study_list_reduced)
  2200. unique_genes_meta = unique(initial_study_list_reduced$Corrected_symbol)
  2201. print("Total genes: ")
  2202. print(length(unique_genes_meta))
  2203. print("Running meta-analysis per gene")
  2204. meta_analysis_list = mclapply(unique_genes_meta, function(x){
  2205. # meta df
  2206. tmp_df_genes = initial_study_list_reduced[initial_study_list_reduced$Corrected_symbol == x,]
  2207. tmp_cohorts_up = length(tmp_df_genes$avgLog2FC[tmp_df_genes$avgLog2FC > 0])
  2208. tmp_cohorts_down = length(tmp_df_genes$avgLog2FC[tmp_df_genes$avgLog2FC < 0])
  2209. cohorts_total = nrow(tmp_df_genes)
  2210. # blood df
  2211. tmp_df_blood = blood_df_to_compare[blood_df_to_compare$Corrected_symbol == x, ]
  2212. if (nrow(tmp_df_blood) > 0){
  2213. tmp_blood_lfc = mean(tmp_df_blood$logFC)
  2214. if (all(tmp_df_blood$logFC < 0)){
  2215. tmp_lfc_blood_dir = "all negative"
  2216. } else {
  2217. tmp_lfc_blood_dir = "all positive"
  2218. }
  2219. if (all(tmp_df_blood$P.Value < 0.05)){
  2220. tmp_blood_signif = "significant"
  2221. } else {
  2222. tmp_blood_signif = "mixed/non-significant"
  2223. }
  2224. } else {
  2225. tmp_blood_lfc = NA
  2226. tmp_lfc_blood_dir = "Not detected/analyzed"
  2227. tmp_blood_signif = "Not detected/analyzed"
  2228. }
  2229. if (cohorts_total < 5){
  2230. tmp_output_df = data.frame(
  2231. gene = x,
  2232. detected_cohorts = cohorts_total,
  2233. cohorts_up = tmp_cohorts_up,
  2234. cohorts_down = tmp_cohorts_down,
  2235. commentary = "Number of cohorts < 5: gene is excluded",
  2236. meta_LFc = NA,
  2237. meta_se = NA,
  2238. meta_pval = NA,
  2239. tau2 = NA,
  2240. I2 = NA,
  2241. H2 = NA,
  2242. Q = NA,
  2243. Q.p = NA,
  2244. mean_blood_lfc = tmp_blood_lfc,
  2245. blood_dir = tmp_lfc_blood_dir,
  2246. blood_signif = tmp_blood_signif,
  2247. matching_with_blood = NA)
  2248. return(tmp_output_df)
  2249. }
  2250. tmp_meta_model = rma.uni(yi = avgLog2FC,
  2251. vi = maxSE^2,
  2252. data = tmp_df_genes,
  2253. method = "SJ",
  2254. weighted = TRUE)
  2255. logFCcompar = c(tmp_blood_lfc, tmp_meta_model$b)
  2256. if (any(is.na(logFCcompar))){
  2257. matching = NA
  2258. } else if (all(logFCcompar > 0)){
  2259. matching = "Match"
  2260. } else if (all(logFCcompar < 0)){
  2261. matching = "Match"
  2262. } else {
  2263. matching = "Mismatch"
  2264. }
  2265. tmp_output_df = data.frame(
  2266. gene = x,
  2267. detected_cohorts = cohorts_total,
  2268. cohorts_up = tmp_cohorts_up,
  2269. cohorts_down = tmp_cohorts_down,
  2270. commentary = "Number of cohorts >= 5: gene is analyzed",
  2271. meta_LFc = tmp_meta_model$b,
  2272. meta_se = tmp_meta_model$se,
  2273. meta_pval = tmp_meta_model$pval,
  2274. tau2 = tmp_meta_model$tau2,
  2275. I2 = tmp_meta_model$I2,
  2276. H2 = tmp_meta_model$H2,
  2277. Q = tmp_meta_model$QE,
  2278. Q.p = tmp_meta_model$QEp,
  2279. mean_blood_lfc = tmp_blood_lfc,
  2280. blood_dir = tmp_lfc_blood_dir,
  2281. blood_signif = tmp_blood_signif,
  2282. matching_with_blood = matching)
  2283. return(tmp_output_df)
  2284. }, mc.cores = 9)
  2285. meta_analysis_df = do.call(rbind, meta_analysis_list)
  2286. rownames(meta_analysis_df) = NULL
  2287. rm(list = ls(pattern = "tmp_"))
  2288. meta_analysis_df = dplyr::arrange(meta_analysis_df, meta_pval)
  2289. meta_analysis_df$meta_FDR = p.adjust(meta_analysis_df$meta_pval, method = "fdr")
  2290. meta_analysis_df = meta_analysis_df[,c("gene",
  2291. "detected_cohorts",
  2292. "cohorts_up",
  2293. "cohorts_down",
  2294. "commentary",
  2295. "meta_LFc",
  2296. "meta_se",
  2297. "meta_pval",
  2298. "meta_FDR",
  2299. "tau2",
  2300. "I2",
  2301. "H2" ,
  2302. "Q",
  2303. "Q.p",
  2304. "mean_blood_lfc",
  2305. "blood_dir",
  2306. "blood_signif",
  2307. "matching_with_blood")]
  2308. out_list = list()
  2309. out_list[[1]] = meta_analysis_df
  2310. out_list[[2]] = initial_study_list_reduced
  2311. names(out_list) = c("meta_analysis_df", "initial_study_list_reduced")
  2312. return(out_list)
  2313. }
  2314. run_single_gene_meta_SJ = function(gene,
  2315. initial_study_list){
  2316. # Reducing df for meta-analysis
  2317. print("Aggregating Log2FC and SE per gene per study")
  2318. initial_study_list_reduced = lapply(initial_study_list, function(x){
  2319. orig_df = x
  2320. x = x[!stri_detect_fixed(x$Corrected_symbol, pattern = ";"),]
  2321. x = x[!is.na(x$Corrected_symbol),]
  2322. x = x[x$Corrected_symbol != "",]
  2323. x = x %>%
  2324. dplyr::group_by(., Corrected_symbol)%>%
  2325. dplyr::summarise(.,
  2326. avgLog2FC = mean(logFC),
  2327. maxSE = max(SE))
  2328. x = dplyr::ungroup(x)
  2329. x$Tissue = unique(orig_df$Tissue)
  2330. x$Tissue_type = unique(orig_df$Tissue_type)
  2331. x$Technology = unique(orig_df$Technology)
  2332. x$Study = unique(orig_df$Study)
  2333. x = as.data.frame(x)
  2334. return(x)
  2335. })
  2336. initial_study_list_reduced = do.call(rbind, initial_study_list_reduced)
  2337. unique_genes_meta = unique(initial_study_list_reduced$Corrected_symbol)
  2338. print("Running meta-analysis for gene")
  2339. # meta df
  2340. tmp_df_genes = initial_study_list_reduced[initial_study_list_reduced$Corrected_symbol == gene,]
  2341. tmp_cohorts_up = length(tmp_df_genes$avgLog2FC[tmp_df_genes$avgLog2FC > 0])
  2342. tmp_cohorts_down = length(tmp_df_genes$avgLog2FC[tmp_df_genes$avgLog2FC < 0])
  2343. cohorts_total = nrow(tmp_df_genes)
  2344. if (cohorts_total < 5){
  2345. print("N cohorts < 5")
  2346. } else {
  2347. tmp_meta_model = rma.uni(yi = avgLog2FC,
  2348. vi = maxSE^2,
  2349. data = tmp_df_genes,
  2350. method = "SJ",
  2351. weighted = TRUE)
  2352. print(summary(tmp_meta_model))
  2353. }
  2354. }
  2355. run_meta_REML = function(initial_study_list, blood_df_to_compare){
  2356. # Reducing df for meta-analysis
  2357. print("Aggregating Log2FC and SE per gene per study")
  2358. initial_study_list_reduced = lapply(initial_study_list, function(x){
  2359. orig_df = x
  2360. x = x[!stri_detect_fixed(x$Corrected_symbol, pattern = ";"),]
  2361. x = x[!is.na(x$Corrected_symbol),]
  2362. x = x[x$Corrected_symbol != "",]
  2363. x = x %>%
  2364. dplyr::group_by(., Corrected_symbol)%>%
  2365. dplyr::summarise(.,
  2366. avgLog2FC = mean(logFC),
  2367. maxSE = max(SE))
  2368. x = dplyr::ungroup(x)
  2369. x$Tissue = unique(orig_df$Tissue)
  2370. x$Tissue_type = unique(orig_df$Tissue_type)
  2371. x$Technology = unique(orig_df$Technology)
  2372. x$Study = unique(orig_df$Study)
  2373. x = as.data.frame(x)
  2374. return(x)
  2375. })
  2376. initial_study_list_reduced = do.call(rbind, initial_study_list_reduced)
  2377. unique_genes_meta = unique(initial_study_list_reduced$Corrected_symbol)
  2378. print("Running meta-analysis per gene")
  2379. meta_analysis_list = mclapply(unique_genes_meta, function(x){
  2380. # meta df
  2381. tmp_df_genes = initial_study_list_reduced[initial_study_list_reduced$Corrected_symbol == x,]
  2382. tmp_cohorts_up = length(tmp_df_genes$avgLog2FC[tmp_df_genes$avgLog2FC > 0])
  2383. tmp_cohorts_down = length(tmp_df_genes$avgLog2FC[tmp_df_genes$avgLog2FC < 0])
  2384. cohorts_total = nrow(tmp_df_genes)
  2385. # blood df
  2386. tmp_df_blood = blood_df_to_compare[blood_df_to_compare$Corrected_symbol == x, ]
  2387. if (nrow(tmp_df_blood) > 0){
  2388. tmp_blood_lfc = mean(tmp_df_blood$logFC)
  2389. if (all(tmp_df_blood$logFC < 0)){
  2390. tmp_lfc_blood_dir = "all negative"
  2391. } else {
  2392. tmp_lfc_blood_dir = "all positive"
  2393. }
  2394. if (all(tmp_df_blood$P.Value < 0.05)){
  2395. tmp_blood_signif = "significant"
  2396. } else {
  2397. tmp_blood_signif = "mixed/non-significant"
  2398. }
  2399. } else {
  2400. tmp_blood_lfc = NA
  2401. tmp_lfc_blood_dir = "Not detected/analyzed"
  2402. tmp_blood_signif = "Not detected/analyzed"
  2403. }
  2404. if (cohorts_total < 5){
  2405. tmp_output_df = data.frame(
  2406. gene = x,
  2407. detected_cohorts = cohorts_total,
  2408. cohorts_up = tmp_cohorts_up,
  2409. cohorts_down = tmp_cohorts_down,
  2410. commentary = "Number of cohorts < 5: gene is excluded",
  2411. meta_LFc = NA,
  2412. meta_se = NA,
  2413. meta_pval = NA,
  2414. tau2 = NA,
  2415. I2 = NA,
  2416. H2 = NA,
  2417. Q = NA,
  2418. Q.p = NA,
  2419. mean_blood_lfc = tmp_blood_lfc,
  2420. blood_dir = tmp_lfc_blood_dir,
  2421. blood_signif = tmp_blood_signif,
  2422. matching_with_blood = NA)
  2423. return(tmp_output_df)
  2424. }
  2425. tmp_meta_model = rma.uni(yi = avgLog2FC,
  2426. vi = maxSE^2,
  2427. data = tmp_df_genes,
  2428. method = "REML",
  2429. control=list(stepadj=0.5, maxiter=10000),
  2430. test="knha", weighted = TRUE)
  2431. logFCcompar = c(tmp_blood_lfc, tmp_meta_model$b)
  2432. if (any(is.na(logFCcompar))){
  2433. matching = NA
  2434. } else if (all(logFCcompar > 0)){
  2435. matching = "Match"
  2436. } else if (all(logFCcompar < 0)){
  2437. matching = "Match"
  2438. } else {
  2439. matching = "Mismatch"
  2440. }
  2441. tmp_output_df = data.frame(
  2442. gene = x,
  2443. detected_cohorts = cohorts_total,
  2444. cohorts_up = tmp_cohorts_up,
  2445. cohorts_down = tmp_cohorts_down,
  2446. commentary = "Number of cohorts >= 5: gene is analyzed",
  2447. meta_LFc = tmp_meta_model$b,
  2448. meta_se = tmp_meta_model$se,
  2449. meta_pval = tmp_meta_model$pval,
  2450. tau2 = tmp_meta_model$tau2,
  2451. I2 = tmp_meta_model$I2,
  2452. H2 = tmp_meta_model$H2,
  2453. Q = tmp_meta_model$QE,
  2454. Q.p = tmp_meta_model$QEp,
  2455. mean_blood_lfc = tmp_blood_lfc,
  2456. blood_dir = tmp_lfc_blood_dir,
  2457. blood_signif = tmp_blood_signif,
  2458. matching_with_blood = matching)
  2459. return(tmp_output_df)
  2460. }, mc.cores = 9)
  2461. meta_analysis_df = do.call(rbind, meta_analysis_list)
  2462. rownames(meta_analysis_df) = NULL
  2463. rm(list = ls(pattern = "tmp_"))
  2464. meta_analysis_df = dplyr::arrange(meta_analysis_df, meta_pval)
  2465. meta_analysis_df$meta_FDR = p.adjust(meta_analysis_df$meta_pval, method = "fdr")
  2466. meta_analysis_df = meta_analysis_df[,c("gene",
  2467. "detected_cohorts",
  2468. "cohorts_up",
  2469. "cohorts_down",
  2470. "commentary",
  2471. "meta_LFc",
  2472. "meta_se",
  2473. "meta_pval",
  2474. "meta_FDR",
  2475. "tau2",
  2476. "I2",
  2477. "H2" ,
  2478. "Q",
  2479. "Q.p",
  2480. "mean_blood_lfc",
  2481. "blood_dir",
  2482. "blood_signif",
  2483. "matching_with_blood")]
  2484. out_list = list()
  2485. out_list[[1]] = meta_analysis_df
  2486. out_list[[2]] = initial_study_list_reduced
  2487. names(out_list) = c("meta_analysis_df", "initial_study_list_reduced")
  2488. return(out_list)
  2489. }
  2490. ################### Meta (no covar) all brain data ###################
  2491. combined_df_no_covar_meta_all = combined_df_no_covar
  2492. combined_df_no_covar_meta_all = combined_df_no_covar_meta_all[combined_df_no_covar_meta_all$Tissue_type == "Brain",]
  2493. blood_df_no_covar = combined_df_no_covar[combined_df_no_covar$Tissue_type == "Blood",]
  2494. table(combined_df_no_covar_meta_all$Tissue, combined_df_no_covar_meta_all$Study)
  2495. # GSE102556 many tissues
  2496. # GSE202537 many tissues
  2497. # GSE66937 many tissues
  2498. combined_df_no_covar_meta_all_1 = combined_df_no_covar_meta_all[combined_df_no_covar_meta_all$Study %!in% c("GSE102556", "GSE202537", "GSE66937"), ]
  2499. combined_df_no_covar_meta_all_2 = combined_df_no_covar_meta_all[combined_df_no_covar_meta_all$Study %in% c("GSE102556", "GSE202537", "GSE66937"), ]
  2500. # Caudate https://pubmed.ncbi.nlm.nih.gov/39164232/
  2501. # Nac https://pubmed.ncbi.nlm.nih.gov/38894648/ https://pubmed.ncbi.nlm.nih.gov/38965529/ https://pubmed.ncbi.nlm.nih.gov/39167467/
  2502. # GSE102556 -> Dorsolateral prefrontal cortex (dlPFC; BA8/9)
  2503. # GSE202537 -> Nac 22652 (more probes analyzed)
  2504. # GSE66937 -> prefrontal cortex
  2505. combined_df_no_covar_meta_all_2 = combined_df_no_covar_meta_all_2[combined_df_no_covar_meta_all_2$Tissue %in% c("Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  2506. "Nac",
  2507. "prefrontal cortex"),]
  2508. table(combined_df_no_covar_meta_all_2$Tissue)
  2509. "
  2510. Dorsolateral prefrontal cortex (dlPFC; BA8/9) Nac prefrontal cortex
  2511. 21365 22652 70523
  2512. "
  2513. combined_df_no_covar_meta_full = rbind(combined_df_no_covar_meta_all_1, combined_df_no_covar_meta_all_2)
  2514. table(combined_df_no_covar_meta_full$Tissue, combined_df_no_covar_meta_full$Study)
  2515. combined_df_no_covar_meta_full_list = lapply(unique(combined_df_no_covar_meta_full$Study), function(x){
  2516. df = combined_df_no_covar_meta_full[combined_df_no_covar_meta_full$Study == x,]
  2517. return(df)
  2518. })
  2519. # Run meta-analysis
  2520. analysis_container_no_covar_all_brain = run_meta_SJ(initial_study_list = combined_df_no_covar_meta_full_list,
  2521. blood_df_to_compare = blood_df_no_covar)
  2522. meta_no_covar_all_brain = analysis_container_no_covar_all_brain[["meta_analysis_df"]]
  2523. combined_df_no_covar_meta_full_list_reduced = analysis_container_no_covar_all_brain[["initial_study_list_reduced"]]
  2524. meta_no_covar_all_brain = add_RRA_to_meta_df(meta_no_covar_all_brain, combined_df_no_covar_meta_full_list)
  2525. non_na_substet = meta_no_covar_all_brain[!is.na(meta_no_covar_all_brain$meta_LFc), ]
  2526. cor.test(non_na_substet$meta_pval, non_na_substet$P_RRA, method = "spearman") # 0.1461325
  2527. meta_no_covar_all_brain_signif = meta_no_covar_all_brain[meta_no_covar_all_brain$meta_pval < 0.05,]
  2528. meta_no_covar_all_brain_signif = meta_no_covar_all_brain_signif[!is.na(meta_no_covar_all_brain_signif$meta_pval),]
  2529. nrow(meta_no_covar_all_brain_signif)
  2530. # P2RY12
  2531. # https://pubmed.ncbi.nlm.nih.gov/37396924/
  2532. # https://www.ingentaconnect.com/content/ben/cnr/2022/00000019/00000003/art00004
  2533. # https://pubmed.ncbi.nlm.nih.gov/31739114/
  2534. # https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8908792/
  2535. # https://www.mdpi.com/1422-0067/25/11/5750
  2536. # https://psychiatryonline.org/doi/10.1176/appi.ajp.2021.22010026
  2537. plot_forest_simple_gene(gene_name = "P2RY12", meta_df = combined_df_cell_types_meta, study_column_char = "Study_Cell")
  2538. plot_forest_meta_gene(gene_name = "P2RY12", meta_df = combined_df_no_covar_meta_full_list_reduced)
  2539. # making plots
  2540. dir.create("forest_plots")
  2541. folder = "forest_plots/meta_no_covar_all_brain"
  2542. dir.create(folder)
  2543. for (i in 1:nrow(meta_no_covar_all_brain_signif)){
  2544. gene = meta_no_covar_all_brain_signif$gene[i]
  2545. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  2546. pdf(file = plot_path, width = 10, height = 7)
  2547. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_no_covar_meta_full_list_reduced))
  2548. dev.off()
  2549. }
  2550. # Heterogeneity summary (28644 were excluded from meta due to Ncohorts <5)
  2551. summary(meta_no_covar_all_brain$I2)
  2552. "
  2553. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  2554. 0.059 34.431 49.216 48.750 63.528 98.581 28644
  2555. "
  2556. summary(meta_no_covar_all_brain_signif$I2)
  2557. "
  2558. Min. 1st Qu. Median Mean 3rd Qu. Max.
  2559. 0.8334 20.4189 32.9392 34.0485 45.3801 78.5286
  2560. "
  2561. ################### Meta (with covar) all brain data ###################
  2562. combined_df_with_covar_meta_all = combined_df_wth_covar
  2563. combined_df_with_covar_meta_all = combined_df_with_covar_meta_all[combined_df_with_covar_meta_all$Tissue_type == "Brain",]
  2564. blood_df_with_covar = combined_df_wth_covar[combined_df_wth_covar$Tissue_type == "Blood",]
  2565. table(combined_df_with_covar_meta_all$Tissue, combined_df_with_covar_meta_all$Study)
  2566. # GSE102556 many tissues
  2567. # GSE202537 many tissues
  2568. # GSE66937 many tissues
  2569. combined_df_with_covar_meta_all_1 = combined_df_with_covar_meta_all[combined_df_with_covar_meta_all$Study %!in% c("GSE102556", "GSE202537", "GSE66937"), ]
  2570. combined_df_with_covar_meta_all_2 = combined_df_with_covar_meta_all[combined_df_with_covar_meta_all$Study %in% c("GSE102556", "GSE202537", "GSE66937"), ]
  2571. combined_df_with_covar_meta_all_2 = combined_df_with_covar_meta_all_2[combined_df_with_covar_meta_all_2$Tissue %in% c("Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  2572. "Nac",
  2573. "prefrontal cortex"),]
  2574. table(combined_df_with_covar_meta_all_2$Tissue)
  2575. "
  2576. Dorsolateral prefrontal cortex (dlPFC; BA8/9) Nac prefrontal cortex
  2577. 23331 23919 70523
  2578. "
  2579. combined_df_with_covar_meta_full = rbind(combined_df_with_covar_meta_all_1, combined_df_with_covar_meta_all_2)
  2580. table(combined_df_with_covar_meta_full$Tissue, combined_df_with_covar_meta_full$Study)
  2581. combined_df_with_covar_meta_full_list = lapply(unique(combined_df_with_covar_meta_full$Study), function(x){
  2582. df = combined_df_with_covar_meta_full[combined_df_with_covar_meta_full$Study == x,]
  2583. return(df)
  2584. })
  2585. # Run meta-analysis
  2586. analysis_container_with_covar_all_brain = run_meta_SJ(initial_study_list = combined_df_with_covar_meta_full_list,
  2587. blood_df_to_compare = blood_df_with_covar)
  2588. meta_with_covar_all_brain = analysis_container_with_covar_all_brain[["meta_analysis_df"]]
  2589. combined_df_with_covar_meta_full_list_reduced = analysis_container_with_covar_all_brain[["initial_study_list_reduced"]]
  2590. meta_with_covar_all_brain = add_RRA_to_meta_df(meta_with_covar_all_brain, combined_df_with_covar_meta_full_list)
  2591. meta_with_covar_all_brain_signif = meta_with_covar_all_brain[meta_with_covar_all_brain$meta_pval < 0.05,]
  2592. meta_with_covar_all_brain_signif = meta_with_covar_all_brain_signif[!is.na(meta_with_covar_all_brain_signif$meta_pval),]
  2593. nrow(meta_with_covar_all_brain_signif)
  2594. plot_forest_meta_gene(gene_name = "RB1", meta_df = combined_df_with_covar_meta_full_list_reduced)
  2595. plot_forest_meta_gene(gene_name = "P2RY12", meta_df = combined_df_with_covar_meta_full_list_reduced)
  2596. # Overlap full analysis
  2597. overlapping_genes_meta_full = intersect(meta_no_covar_all_brain_signif$gene, meta_with_covar_all_brain_signif$gene)
  2598. overlapping_genes_meta_full = unique(overlapping_genes_meta_full)
  2599. length(overlapping_genes_meta_full) # 57 genes overlap
  2600. overlapping_subset_allbrain_ncv = meta_no_covar_all_brain_signif[meta_no_covar_all_brain_signif$gene %in% overlapping_genes_meta_full, ]
  2601. overlapping_subset_allbrain_ncv = dplyr::arrange(overlapping_subset_allbrain_ncv, gene)
  2602. overlapping_subset_allbrain_cv = meta_with_covar_all_brain_signif[meta_with_covar_all_brain_signif$gene %in% overlapping_genes_meta_full, ]
  2603. overlapping_subset_allbrain_cv = dplyr::arrange(overlapping_subset_allbrain_cv, gene)
  2604. overlapping_subset_allbrain_stat = cbind(
  2605. overlapping_subset_allbrain_ncv$gene,
  2606. overlapping_subset_allbrain_ncv$meta_LFc,
  2607. overlapping_subset_allbrain_cv$gene,
  2608. overlapping_subset_allbrain_cv$meta_LFc
  2609. )
  2610. overlapping_subset_allbrain_stat = as.data.frame(overlapping_subset_allbrain_stat)
  2611. overlapping_subset_allbrain_stat$V2 = as.numeric(overlapping_subset_allbrain_stat$V2)
  2612. overlapping_subset_allbrain_stat$V4 = as.numeric(overlapping_subset_allbrain_stat$V4)
  2613. overlapping_subset_allbrain_stat$mean = mapply(function(x,y) mean(x,y),overlapping_subset_allbrain_stat$V2, overlapping_subset_allbrain_stat$V4)
  2614. # making plots
  2615. dir.create("forest_plots")
  2616. folder = "forest_plots/meta_with_covar_all_brain"
  2617. dir.create(folder)
  2618. for (i in 1:nrow(meta_with_covar_all_brain_signif)){
  2619. gene = meta_with_covar_all_brain_signif$gene[i]
  2620. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  2621. pdf(file = plot_path, width = 10, height = 7)
  2622. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_with_covar_meta_full_list_reduced))
  2623. dev.off()
  2624. }
  2625. # Heterogeneity estimates
  2626. summary(meta_with_covar_all_brain$I2)
  2627. " Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  2628. 0.001 25.237 39.893 41.247 56.093 99.471 29942
  2629. "
  2630. ################### Meta cortical regions (no covar) ###################
  2631. combined_df_no_covar_meta_cortical = combined_df_no_covar
  2632. combined_df_no_covar_meta_cortical = combined_df_no_covar_meta_cortical[combined_df_no_covar_meta_cortical$Tissue_type == "Brain",]
  2633. blood_df_no_covar = combined_df_no_covar[combined_df_no_covar$Tissue_type == "Blood",]
  2634. table(combined_df_no_covar_meta_cortical$Tissue, combined_df_no_covar_meta_cortical$Study)
  2635. # Tissues to include
  2636. # Cingulate gyrus 25 (Cg25) is also cortical but Dorsolateral prefrontal cortex (dlPFC; BA8/9) was used instead
  2637. combined_df_no_covar_meta_cortical = combined_df_no_covar_meta_cortical[combined_df_no_covar_meta_cortical$Tissue %in%
  2638. c("DLPFC",
  2639. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  2640. "Dorsolateral Prefrontal Cortex",
  2641. "Dorsolateral prefrontal cortex (BA9)",
  2642. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  2643. "Orbitofrontal cortex",
  2644. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  2645. "prefrontal cortex",
  2646. "temporal cortex (BA20 and BA36)"),]
  2647. table(combined_df_no_covar_meta_cortical$Tissue, combined_df_no_covar_meta_cortical$Study)
  2648. "
  2649. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE243356 GSE5388 GSE5389 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  2650. DLPFC 0 0 0 0 0 0 22283 0 0 0 0
  2651. dorsal lateral prefrontal cortex (Brodmann Area 9) 18677 0 0 0 0 0 0 0 0 0 0
  2652. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 0 0 54675 22283
  2653. Dorsolateral prefrontal cortex (BA9) 0 0 19271 0 19191 0 0 0 0 0 0
  2654. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 21365 0 0 0 0 0 0 0 0 0
  2655. Orbitofrontal cortex 0 0 0 0 0 0 0 22283 0 0 0
  2656. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0 0 0
  2657. prefrontal cortex 0 0 0 0 0 0 0 0 70523 0 0
  2658. temporal cortex (BA20 and BA36) 0 0 0 0 0 20955 0 0 0 0 0
  2659. "
  2660. combined_df_no_covar_meta_cortical_list = lapply(unique(combined_df_no_covar_meta_cortical$Study), function(x){
  2661. df = combined_df_no_covar_meta_cortical[combined_df_no_covar_meta_cortical$Study == x,]
  2662. return(df)
  2663. })
  2664. # Run meta-analysis
  2665. analysis_container_no_covar_cortical = run_meta_SJ(initial_study_list = combined_df_no_covar_meta_cortical_list,
  2666. blood_df_to_compare = blood_df_no_covar)
  2667. meta_no_covar_cortical = analysis_container_no_covar_cortical[["meta_analysis_df"]]
  2668. combined_df_no_covar_meta_cortical_list_reduced = analysis_container_no_covar_cortical[["initial_study_list_reduced"]]
  2669. meta_no_covar_cortical = add_RRA_to_meta_df(meta_no_covar_cortical, combined_df_no_covar_meta_cortical_list)
  2670. meta_no_covar_cortical_signif = meta_no_covar_cortical[meta_no_covar_cortical$meta_pval < 0.05,]
  2671. meta_no_covar_cortical_signif = meta_no_covar_cortical_signif[!is.na(meta_no_covar_cortical_signif$meta_pval),]
  2672. meta_no_covar_cortical[meta_no_covar_cortical$gene == "P2RY12",]
  2673. nrow(meta_no_covar_cortical_signif)
  2674. # making plots
  2675. dir.create("forest_plots")
  2676. folder = "forest_plots/meta_no_covar_cortical"
  2677. dir.create(folder)
  2678. for (i in 1:nrow(meta_no_covar_cortical_signif)){
  2679. gene = meta_no_covar_cortical_signif$gene[i]
  2680. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  2681. pdf(file = plot_path, width = 10, height = 7)
  2682. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_no_covar_meta_cortical_list_reduced))
  2683. dev.off()
  2684. }
  2685. # Heterogeneity summary (31325 were excluded from meta due to Ncohorts <5)
  2686. summary(meta_no_covar_cortical$I2)
  2687. "
  2688. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  2689. 0.021 31.841 48.919 48.347 65.182 98.987 31325
  2690. "
  2691. summary(meta_no_covar_cortical_signif$I2)
  2692. "
  2693. Min. 1st Qu. Median Mean 3rd Qu. Max.
  2694. 1.215 22.009 34.357 35.388 48.552 83.960
  2695. "
  2696. ################### Meta cortical regions (with covar) ###################
  2697. combined_df_with_covar_meta_cortical = combined_df_wth_covar
  2698. combined_df_with_covar_meta_cortical = combined_df_with_covar_meta_cortical[combined_df_with_covar_meta_cortical$Tissue_type == "Brain",]
  2699. blood_df_with_covar = combined_df_wth_covar[combined_df_wth_covar$Tissue_type == "Blood",]
  2700. # Tissues to include
  2701. combined_df_with_covar_meta_cortical = combined_df_with_covar_meta_cortical[combined_df_with_covar_meta_cortical$Tissue %in%
  2702. c("DLPFC",
  2703. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  2704. "Dorsolateral Prefrontal Cortex",
  2705. "Dorsolateral prefrontal cortex (BA9)",
  2706. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  2707. "Orbitofrontal cortex",
  2708. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  2709. "prefrontal cortex",
  2710. "temporal cortex (BA20 and BA36)"),]
  2711. table(combined_df_with_covar_meta_cortical$Tissue, combined_df_with_covar_meta_cortical$Study)
  2712. "
  2713. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE243356 GSE5388 GSE5389 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  2714. DLPFC 0 0 0 0 0 0 22283 0 0 0 0
  2715. dorsal lateral prefrontal cortex (Brodmann Area 9) 21197 0 0 0 0 0 0 0 0 0 0
  2716. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 0 0 54675 22283
  2717. Dorsolateral prefrontal cortex (BA9) 0 0 22389 0 24182 0 0 0 0 0 0
  2718. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 23331 0 0 0 0 0 0 0 0 0
  2719. Orbitofrontal cortex 0 0 0 0 0 0 0 22283 0 0 0
  2720. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0 0 0
  2721. prefrontal cortex 0 0 0 0 0 0 0 0 70523 0 0
  2722. temporal cortex (BA20 and BA36) 0 0 0 0 0 20955 0 0 0 0 0
  2723. "
  2724. combined_df_with_covar_meta_cortical_list = lapply(unique(combined_df_with_covar_meta_cortical$Study), function(x){
  2725. df = combined_df_with_covar_meta_cortical[combined_df_with_covar_meta_cortical$Study == x,]
  2726. return(df)
  2727. })
  2728. # Run meta-analysis
  2729. analysis_container_with_covar_cortical = run_meta_SJ(initial_study_list = combined_df_with_covar_meta_cortical_list,
  2730. blood_df_to_compare = blood_df_with_covar)
  2731. meta_with_covar_cortical = analysis_container_with_covar_cortical[["meta_analysis_df"]]
  2732. combined_df_with_covar_meta_cortical_list_reduced = analysis_container_with_covar_cortical[["initial_study_list_reduced"]]
  2733. meta_with_covar_cortical = add_RRA_to_meta_df(meta_with_covar_cortical, combined_df_with_covar_meta_cortical_list)
  2734. meta_with_covar_cortical_signif = meta_with_covar_cortical[meta_with_covar_cortical$meta_pval < 0.05,]
  2735. meta_with_covar_cortical_signif = meta_with_covar_cortical_signif[!is.na(meta_with_covar_cortical_signif$meta_pval),]
  2736. nrow(meta_with_covar_cortical_signif) # 205
  2737. meta_with_covar_cortical[meta_with_covar_cortical$gene == "P2RY12",]
  2738. # making plots
  2739. dir.create("forest_plots")
  2740. folder = "forest_plots/meta_with_covar_cortical"
  2741. dir.create(folder)
  2742. for (i in 1:nrow(meta_with_covar_cortical_signif)){
  2743. gene = meta_with_covar_cortical_signif$gene[i]
  2744. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  2745. pdf(file = plot_path, width = 10, height = 7)
  2746. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_with_covar_meta_cortical_list_reduced))
  2747. dev.off()
  2748. }
  2749. # Heterogeneity estimates
  2750. summary(meta_with_covar_cortical$I2)
  2751. " Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  2752. 0.03 22.37 37.90 39.75 55.92 99.57 33360
  2753. "
  2754. ################### Meta prefrontal regions (no covar) ###################
  2755. combined_df_no_covar_meta_prefrontal = combined_df_no_covar
  2756. combined_df_no_covar_meta_prefrontal = combined_df_no_covar_meta_prefrontal[combined_df_no_covar_meta_prefrontal$Tissue_type == "Brain",]
  2757. blood_df_no_covar = combined_df_no_covar[combined_df_no_covar$Tissue_type == "Blood",]
  2758. table(combined_df_no_covar_meta_prefrontal$Tissue, combined_df_no_covar_meta_prefrontal$Study)
  2759. # Tissues to include
  2760. combined_df_no_covar_meta_prefrontal = combined_df_no_covar_meta_prefrontal[combined_df_no_covar_meta_prefrontal$Tissue %in%
  2761. c("DLPFC",
  2762. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  2763. "Dorsolateral Prefrontal Cortex",
  2764. "Dorsolateral prefrontal cortex (BA9)",
  2765. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  2766. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  2767. "prefrontal cortex"),]
  2768. table(combined_df_no_covar_meta_prefrontal$Tissue, combined_df_no_covar_meta_prefrontal$Study)
  2769. "
  2770. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE5388 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  2771. DLPFC 0 0 0 0 0 22283 0 0 0
  2772. dorsal lateral prefrontal cortex (Brodmann Area 9) 18677 0 0 0 0 0 0 0 0
  2773. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 54675 22283
  2774. Dorsolateral prefrontal cortex (BA9) 0 0 19271 0 19191 0 0 0 0
  2775. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 21365 0 0 0 0 0 0 0
  2776. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0
  2777. prefrontal cortex 0 0 0 0 0 0 70523 0 0
  2778. "
  2779. combined_df_no_covar_meta_prefrontal_list = lapply(unique(combined_df_no_covar_meta_prefrontal$Study), function(x){
  2780. df = combined_df_no_covar_meta_prefrontal[combined_df_no_covar_meta_prefrontal$Study == x,]
  2781. return(df)
  2782. })
  2783. # Run meta-analysis
  2784. analysis_container_no_covar_prefrontal = run_meta_SJ(initial_study_list = combined_df_no_covar_meta_prefrontal_list,
  2785. blood_df_to_compare = blood_df_no_covar)
  2786. meta_no_covar_prefrontal = analysis_container_no_covar_prefrontal[["meta_analysis_df"]]
  2787. combined_df_no_covar_meta_prefrontal_list_reduced = analysis_container_no_covar_prefrontal[["initial_study_list_reduced"]]
  2788. meta_no_covar_prefrontal = add_RRA_to_meta_df(meta_no_covar_prefrontal, combined_df_no_covar_meta_prefrontal_list)
  2789. meta_no_covar_prefrontal_signif = meta_no_covar_prefrontal[meta_no_covar_prefrontal$meta_pval < 0.05,]
  2790. meta_no_covar_prefrontal_signif = meta_no_covar_prefrontal_signif[!is.na(meta_no_covar_prefrontal_signif$meta_pval),]
  2791. nrow(meta_no_covar_prefrontal_signif)
  2792. meta_no_covar_prefrontal[meta_no_covar_prefrontal$gene == "P2RY12",]
  2793. # making plots
  2794. dir.create("forest_plots")
  2795. folder = "forest_plots/meta_no_covar_prefrontal"
  2796. dir.create(folder)
  2797. for (i in 1:nrow(meta_no_covar_prefrontal_signif)){
  2798. gene = meta_no_covar_prefrontal_signif$gene[i]
  2799. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  2800. pdf(file = plot_path, width = 10, height = 7)
  2801. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_no_covar_meta_prefrontal_list_reduced))
  2802. dev.off()
  2803. }
  2804. # Heterogeneity summary (33247 were excluded from meta due to Ncohorts <5)
  2805. summary(meta_no_covar_prefrontal$I2)
  2806. "
  2807. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  2808. 0.00 30.27 48.05 47.93 65.83 99.22 33247
  2809. "
  2810. summary(meta_no_covar_prefrontal_signif$I2)
  2811. "
  2812. Min. 1st Qu. Median Mean 3rd Qu. Max.
  2813. 0.28 21.44 35.29 37.44 50.67 90.73
  2814. "
  2815. ################### Meta prefrontal regions (with covar) ###################
  2816. combined_df_with_covar_meta_prefrontal = combined_df_wth_covar
  2817. combined_df_with_covar_meta_prefrontal = combined_df_with_covar_meta_prefrontal[combined_df_with_covar_meta_prefrontal$Tissue_type == "Brain",]
  2818. blood_df_with_covar = combined_df_wth_covar[combined_df_wth_covar$Tissue_type == "Blood",]
  2819. # Tissues to include
  2820. combined_df_with_covar_meta_prefrontal = combined_df_with_covar_meta_prefrontal[combined_df_with_covar_meta_prefrontal$Tissue %in%
  2821. c("DLPFC",
  2822. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  2823. "Dorsolateral Prefrontal Cortex",
  2824. "Dorsolateral prefrontal cortex (BA9)",
  2825. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  2826. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  2827. "prefrontal cortex"),]
  2828. table(combined_df_with_covar_meta_prefrontal$Tissue, combined_df_with_covar_meta_prefrontal$Study)
  2829. "
  2830. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE5388 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  2831. DLPFC 0 0 0 0 0 22283 0 0 0
  2832. dorsal lateral prefrontal cortex (Brodmann Area 9) 21197 0 0 0 0 0 0 0 0
  2833. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 54675 22283
  2834. Dorsolateral prefrontal cortex (BA9) 0 0 22389 0 24182 0 0 0 0
  2835. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 23331 0 0 0 0 0 0 0
  2836. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0
  2837. prefrontal cortex 0 0 0 0 0 0 70523 0 0
  2838. "
  2839. combined_df_with_covar_meta_prefrontal_list = lapply(unique(combined_df_with_covar_meta_prefrontal$Study), function(x){
  2840. df = combined_df_with_covar_meta_prefrontal[combined_df_with_covar_meta_prefrontal$Study == x,]
  2841. return(df)
  2842. })
  2843. # Run meta-analysis
  2844. analysis_container_with_covar_prefrontal = run_meta_SJ(initial_study_list = combined_df_with_covar_meta_prefrontal_list,
  2845. blood_df_to_compare = blood_df_with_covar)
  2846. meta_with_covar_prefrontal = analysis_container_with_covar_prefrontal[["meta_analysis_df"]]
  2847. combined_df_with_covar_meta_prefrontal_list_reduced = analysis_container_with_covar_prefrontal[["initial_study_list_reduced"]]
  2848. meta_with_covar_prefrontal = add_RRA_to_meta_df(meta_with_covar_prefrontal, combined_df_with_covar_meta_prefrontal_list)
  2849. meta_with_covar_prefrontal_signif = meta_with_covar_prefrontal[meta_with_covar_prefrontal$meta_pval < 0.05,]
  2850. meta_with_covar_prefrontal_signif = meta_with_covar_prefrontal_signif[!is.na(meta_with_covar_prefrontal_signif$meta_pval),]
  2851. nrow(meta_with_covar_prefrontal_signif)
  2852. meta_with_covar_prefrontal[meta_with_covar_prefrontal$gene == "P2RY12",]
  2853. # plots
  2854. dir.create("forest_plots")
  2855. folder = "forest_plots/meta_with_covar_prefrontal"
  2856. dir.create(folder)
  2857. for (i in 1:nrow(meta_with_covar_prefrontal_signif)){
  2858. gene = meta_with_covar_prefrontal_signif$gene[i]
  2859. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  2860. pdf(file = plot_path, width = 10, height = 7)
  2861. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_with_covar_meta_prefrontal_list_reduced))
  2862. dev.off()
  2863. }
  2864. # Heterogeneity estimates
  2865. summary(meta_with_covar_prefrontal$I2)
  2866. " Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  2867. 0.03 19.87 35.90 38.37 55.02 99.65 35343
  2868. "
  2869. ################### Volcano plot for every meta-analysis ###################
  2870. plot_meta_volcano = function(meta_df, figure_path, title){
  2871. meta_df = meta_df[!is.na(meta_df$meta_pval),]
  2872. meta_df$adj.P.Val = p.adjust(meta_df$meta_pval, method = "fdr")
  2873. Pval_treshold = meta_df[meta_df$adj.P.Val < 0.05,]
  2874. Pval_treshold = max(Pval_treshold$meta_pval)
  2875. Pval_treshold = -log10(Pval_treshold)
  2876. if (is.na(Pval_treshold)){
  2877. Pval_treshold = -log10(0.001)
  2878. }
  2879. PREFIX_logFC_threshold = 0.2
  2880. meta_df$is.highlight = sapply(meta_df$meta_LFc, function(x){
  2881. if (x > PREFIX_logFC_threshold){
  2882. x = "Up"
  2883. } else if (x < - PREFIX_logFC_threshold){
  2884. x = "Down"
  2885. } else {
  2886. x = "None"
  2887. }
  2888. })
  2889. meta_df = mutate(meta_df, is_annotate = ifelse(-log10(meta_pval) >= -log10(0.05) & is.highlight != "None", "yes", "no"))
  2890. # Make the plot
  2891. plot = ggplot(meta_df, aes(x=meta_LFc, y=-log10(meta_pval))) +
  2892. # Show all points
  2893. geom_point(aes(color= factor(is.highlight, levels = c("None", "Down", "Up"))), alpha=0.6, size=4) +
  2894. scale_color_manual(values = c("grey", "skyblue", "red"))
  2895. # Add standard scale for plot
  2896. plot = plot + scale_x_continuous(limits = c(-1.5,1.5))
  2897. plot = plot + scale_y_continuous(limits = c(0,5))
  2898. # Add title
  2899. plot = plot + ggtitle(label = title)
  2900. # Add pval line
  2901. if (!is.null(Pval_treshold)){
  2902. plot = plot + geom_hline(yintercept=Pval_treshold, linetype="dashed",
  2903. color = "red", size=0.5)
  2904. }
  2905. # Add pval line 0.05
  2906. plot = plot + geom_hline(yintercept= -log10(0.05), linetype="dashed",
  2907. color = "blue", size=0.5)
  2908. # Add logFC lines
  2909. if (min(meta_df$meta_LFc) < -PREFIX_logFC_threshold){
  2910. plot = plot + geom_vline(xintercept= -PREFIX_logFC_threshold, linetype="dashed",
  2911. color = "grey", size=0.5)
  2912. }
  2913. if (max(meta_df$meta_LFc) > PREFIX_logFC_threshold){
  2914. plot = plot + geom_vline(xintercept= PREFIX_logFC_threshold, linetype="dashed",
  2915. color = "grey", size=0.5)
  2916. }
  2917. # Add label using ggrepel to avoid overlapping
  2918. if (any(meta_df$is_annotate == "yes")){
  2919. plot = plot +
  2920. geom_label_repel(data=subset(meta_df, is_annotate=="yes"), aes(label=gene), size=4, force = 10,
  2921. max.overlaps = 50)
  2922. }
  2923. plot = plot +
  2924. labs(x = "meta-estimated Log2FC", y = "-log10 p-value") +
  2925. # Custom the theme:
  2926. theme(
  2927. legend.position="none",
  2928. panel.border = element_blank(),
  2929. panel.grid.major.x = element_blank(),
  2930. panel.grid.major.y = element_line(size = 0.1, linetype = 2, color = "black"), # Modifying horizontal lines in the plot
  2931. panel.background = element_blank(),
  2932. plot.title = element_text(size = 20, face = "bold", hjust = 0.5),
  2933. axis.text.x = element_text(size = 12),
  2934. axis.text.y = element_text(size = 12),
  2935. axis.title.x = element_text(size = 14, face = "bold"),
  2936. axis.title.y = element_text(size = 14, face = "bold")
  2937. )
  2938. ggsave(file = figure_path, plot = plot, width=2560, height=1440, units = "px", scale = 2)
  2939. }
  2940. # making volcanos in a loop
  2941. joined_list_all_metas = list(
  2942. meta_no_covar_all_brain,
  2943. meta_no_covar_cortical,
  2944. meta_no_covar_prefrontal,
  2945. meta_with_covar_all_brain,
  2946. meta_with_covar_cortical,
  2947. meta_with_covar_prefrontal
  2948. )
  2949. names_for_list_all = c("All brain", "Cortical", "DLPFC", "All brain (covar)", "Cortical (covar)", "DLPFC (covar)")
  2950. dir.create("volcano_plots")
  2951. for (i in 1:6){
  2952. curr_df = joined_list_all_metas[[i]]
  2953. plot_path = paste0("volcano_plots/", names_for_list_all[i], ".png")
  2954. plot_meta_volcano(curr_df, figure_path = plot_path, title = names_for_list_all[i])
  2955. }
  2956. ################### Sensitivity analysis ###################
  2957. ################### REML Meta (no covar) all brain data ###################
  2958. combined_df_no_covar_meta_all = combined_df_no_covar
  2959. combined_df_no_covar_meta_all = combined_df_no_covar_meta_all[combined_df_no_covar_meta_all$Tissue_type == "Brain",]
  2960. blood_df_no_covar = combined_df_no_covar[combined_df_no_covar$Tissue_type == "Blood",]
  2961. table(combined_df_no_covar_meta_all$Tissue, combined_df_no_covar_meta_all$Study)
  2962. # GSE102556 many tissues
  2963. # GSE202537 many tissues
  2964. # GSE66937 many tissues
  2965. combined_df_no_covar_meta_all_1 = combined_df_no_covar_meta_all[combined_df_no_covar_meta_all$Study %!in% c("GSE102556", "GSE202537", "GSE66937"), ]
  2966. combined_df_no_covar_meta_all_2 = combined_df_no_covar_meta_all[combined_df_no_covar_meta_all$Study %in% c("GSE102556", "GSE202537", "GSE66937"), ]
  2967. # Caudate https://pubmed.ncbi.nlm.nih.gov/39164232/
  2968. # Nac https://pubmed.ncbi.nlm.nih.gov/38894648/ https://pubmed.ncbi.nlm.nih.gov/38965529/ https://pubmed.ncbi.nlm.nih.gov/39167467/
  2969. # GSE102556 -> Dorsolateral prefrontal cortex (dlPFC; BA8/9)
  2970. # GSE202537 -> Nac 22652 (more probes analyzed)
  2971. # GSE66937 -> prefrontal cortex
  2972. combined_df_no_covar_meta_all_2 = combined_df_no_covar_meta_all_2[combined_df_no_covar_meta_all_2$Tissue %in% c("Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  2973. "Nac",
  2974. "prefrontal cortex"),]
  2975. table(combined_df_no_covar_meta_all_2$Tissue)
  2976. "
  2977. Dorsolateral prefrontal cortex (dlPFC; BA8/9) Nac prefrontal cortex
  2978. 21365 22652 70523
  2979. "
  2980. combined_df_no_covar_meta_full = rbind(combined_df_no_covar_meta_all_1, combined_df_no_covar_meta_all_2)
  2981. table(combined_df_no_covar_meta_full$Tissue, combined_df_no_covar_meta_full$Study)
  2982. combined_df_no_covar_meta_full_list = lapply(unique(combined_df_no_covar_meta_full$Study), function(x){
  2983. df = combined_df_no_covar_meta_full[combined_df_no_covar_meta_full$Study == x,]
  2984. return(df)
  2985. })
  2986. # Run meta-analysis
  2987. REML_analysis_container_no_covar_all_brain = run_meta_REML(initial_study_list = combined_df_no_covar_meta_full_list,
  2988. blood_df_to_compare = blood_df_no_covar)
  2989. REML_meta_no_covar_all_brain = REML_analysis_container_no_covar_all_brain[["meta_analysis_df"]]
  2990. REML_meta_no_covar_all_brain = add_RRA_to_meta_df(REML_meta_no_covar_all_brain, combined_df_no_covar_meta_full_list)
  2991. REML_meta_no_covar_all_brain_signif = REML_meta_no_covar_all_brain[REML_meta_no_covar_all_brain$meta_pval < 0.05,]
  2992. REML_meta_no_covar_all_brain_signif = REML_meta_no_covar_all_brain_signif[!is.na(REML_meta_no_covar_all_brain_signif$meta_pval),]
  2993. nrow(REML_meta_no_covar_all_brain_signif)
  2994. # Heterogeneity
  2995. summary(REML_meta_no_covar_all_brain$I2)
  2996. "
  2997. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  2998. 0.00 0.00 12.71 20.95 39.31 94.73 28644
  2999. "
  3000. ################### REML Meta (with covar) all brain data ###################
  3001. combined_df_with_covar_meta_all = combined_df_wth_covar
  3002. combined_df_with_covar_meta_all = combined_df_with_covar_meta_all[combined_df_with_covar_meta_all$Tissue_type == "Brain",]
  3003. blood_df_with_covar = combined_df_wth_covar[combined_df_wth_covar$Tissue_type == "Blood",]
  3004. table(combined_df_with_covar_meta_all$Tissue, combined_df_with_covar_meta_all$Study)
  3005. # GSE102556 many tissues
  3006. # GSE202537 many tissues
  3007. # GSE66937 many tissues
  3008. combined_df_with_covar_meta_all_1 = combined_df_with_covar_meta_all[combined_df_with_covar_meta_all$Study %!in% c("GSE102556", "GSE202537", "GSE66937"), ]
  3009. combined_df_with_covar_meta_all_2 = combined_df_with_covar_meta_all[combined_df_with_covar_meta_all$Study %in% c("GSE102556", "GSE202537", "GSE66937"), ]
  3010. combined_df_with_covar_meta_all_2 = combined_df_with_covar_meta_all_2[combined_df_with_covar_meta_all_2$Tissue %in% c("Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3011. "Nac",
  3012. "prefrontal cortex"),]
  3013. table(combined_df_with_covar_meta_all_2$Tissue)
  3014. "
  3015. Dorsolateral prefrontal cortex (dlPFC; BA8/9) Nac prefrontal cortex
  3016. 23331 23919 70523
  3017. "
  3018. combined_df_with_covar_meta_full = rbind(combined_df_with_covar_meta_all_1, combined_df_with_covar_meta_all_2)
  3019. table(combined_df_with_covar_meta_full$Tissue, combined_df_with_covar_meta_full$Study)
  3020. combined_df_with_covar_meta_full_list = lapply(unique(combined_df_with_covar_meta_full$Study), function(x){
  3021. df = combined_df_with_covar_meta_full[combined_df_with_covar_meta_full$Study == x,]
  3022. return(df)
  3023. })
  3024. # Run meta-analysis
  3025. REML_analysis_container_with_covar_all_brain = run_meta_REML(initial_study_list = combined_df_with_covar_meta_full_list,
  3026. blood_df_to_compare = blood_df_with_covar)
  3027. REML_meta_with_covar_all_brain = REML_analysis_container_with_covar_all_brain[["meta_analysis_df"]]
  3028. REML_meta_with_covar_all_brain = add_RRA_to_meta_df(REML_meta_with_covar_all_brain, combined_df_with_covar_meta_full_list)
  3029. REML_meta_with_covar_all_brain_signif = REML_meta_with_covar_all_brain[REML_meta_with_covar_all_brain$meta_pval < 0.05,]
  3030. REML_meta_with_covar_all_brain_signif = REML_meta_with_covar_all_brain_signif[!is.na(REML_meta_with_covar_all_brain_signif$meta_pval),]
  3031. nrow(REML_meta_with_covar_all_brain_signif)
  3032. ################### REML Meta cortical regions (no covar) ###################
  3033. combined_df_no_covar_meta_cortical = combined_df_no_covar
  3034. combined_df_no_covar_meta_cortical = combined_df_no_covar_meta_cortical[combined_df_no_covar_meta_cortical$Tissue_type == "Brain",]
  3035. blood_df_no_covar = combined_df_no_covar[combined_df_no_covar$Tissue_type == "Blood",]
  3036. table(combined_df_no_covar_meta_cortical$Tissue, combined_df_no_covar_meta_cortical$Study)
  3037. # Tissues to include
  3038. # Cingulate gyrus 25 (Cg25) is also cortical but Dorsolateral prefrontal cortex (dlPFC; BA8/9) was used instead
  3039. combined_df_no_covar_meta_cortical = combined_df_no_covar_meta_cortical[combined_df_no_covar_meta_cortical$Tissue %in%
  3040. c("DLPFC",
  3041. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  3042. "Dorsolateral Prefrontal Cortex",
  3043. "Dorsolateral prefrontal cortex (BA9)",
  3044. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3045. "Orbitofrontal cortex",
  3046. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  3047. "prefrontal cortex",
  3048. "temporal cortex (BA20 and BA36)"),]
  3049. table(combined_df_no_covar_meta_cortical$Tissue, combined_df_no_covar_meta_cortical$Study)
  3050. "
  3051. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE243356 GSE5388 GSE5389 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  3052. DLPFC 0 0 0 0 0 0 22283 0 0 0 0
  3053. dorsal lateral prefrontal cortex (Brodmann Area 9) 18677 0 0 0 0 0 0 0 0 0 0
  3054. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 0 0 54675 22283
  3055. Dorsolateral prefrontal cortex (BA9) 0 0 19271 0 19191 0 0 0 0 0 0
  3056. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 21365 0 0 0 0 0 0 0 0 0
  3057. Orbitofrontal cortex 0 0 0 0 0 0 0 22283 0 0 0
  3058. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0 0 0
  3059. prefrontal cortex 0 0 0 0 0 0 0 0 70523 0 0
  3060. temporal cortex (BA20 and BA36) 0 0 0 0 0 20955 0 0 0 0 0
  3061. "
  3062. combined_df_no_covar_meta_cortical_list = lapply(unique(combined_df_no_covar_meta_cortical$Study), function(x){
  3063. df = combined_df_no_covar_meta_cortical[combined_df_no_covar_meta_cortical$Study == x,]
  3064. return(df)
  3065. })
  3066. # Run meta-analysis
  3067. REML_analysis_container_no_covar_cortical = run_meta_REML(initial_study_list = combined_df_no_covar_meta_cortical_list,
  3068. blood_df_to_compare = blood_df_no_covar)
  3069. REML_meta_no_covar_cortical = REML_analysis_container_no_covar_cortical[["meta_analysis_df"]]
  3070. REML_meta_no_covar_cortical = add_RRA_to_meta_df(REML_meta_no_covar_cortical, combined_df_no_covar_meta_cortical_list)
  3071. REML_meta_no_covar_cortical_signif = REML_meta_no_covar_cortical[REML_meta_no_covar_cortical$meta_pval < 0.05,]
  3072. REML_meta_no_covar_cortical_signif = REML_meta_no_covar_cortical_signif[!is.na(REML_meta_no_covar_cortical_signif$meta_pval),]
  3073. nrow(REML_meta_no_covar_cortical_signif)
  3074. # Heterogeneity
  3075. summary(REML_meta_no_covar_cortical$I2)
  3076. "
  3077. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  3078. 0.00 0.00 12.86 22.62 42.70 95.93 31325
  3079. "
  3080. ################### REML Meta cortical regions (with covar) ###################
  3081. combined_df_with_covar_meta_cortical = combined_df_wth_covar
  3082. combined_df_with_covar_meta_cortical = combined_df_with_covar_meta_cortical[combined_df_with_covar_meta_cortical$Tissue_type == "Brain",]
  3083. blood_df_with_covar = combined_df_wth_covar[combined_df_wth_covar$Tissue_type == "Blood",]
  3084. # Tissues to include
  3085. combined_df_with_covar_meta_cortical = combined_df_with_covar_meta_cortical[combined_df_with_covar_meta_cortical$Tissue %in%
  3086. c("DLPFC",
  3087. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  3088. "Dorsolateral Prefrontal Cortex",
  3089. "Dorsolateral prefrontal cortex (BA9)",
  3090. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3091. "Orbitofrontal cortex",
  3092. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  3093. "prefrontal cortex",
  3094. "temporal cortex (BA20 and BA36)"),]
  3095. table(combined_df_with_covar_meta_cortical$Tissue, combined_df_with_covar_meta_cortical$Study)
  3096. "
  3097. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE243356 GSE5388 GSE5389 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  3098. DLPFC 0 0 0 0 0 0 22283 0 0 0 0
  3099. dorsal lateral prefrontal cortex (Brodmann Area 9) 21197 0 0 0 0 0 0 0 0 0 0
  3100. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 0 0 54675 22283
  3101. Dorsolateral prefrontal cortex (BA9) 0 0 22389 0 24182 0 0 0 0 0 0
  3102. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 23331 0 0 0 0 0 0 0 0 0
  3103. Orbitofrontal cortex 0 0 0 0 0 0 0 22283 0 0 0
  3104. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0 0 0
  3105. prefrontal cortex 0 0 0 0 0 0 0 0 70523 0 0
  3106. temporal cortex (BA20 and BA36) 0 0 0 0 0 20955 0 0 0 0 0
  3107. "
  3108. combined_df_with_covar_meta_cortical_list = lapply(unique(combined_df_with_covar_meta_cortical$Study), function(x){
  3109. df = combined_df_with_covar_meta_cortical[combined_df_with_covar_meta_cortical$Study == x,]
  3110. return(df)
  3111. })
  3112. # Run meta-analysis
  3113. REML_analysis_container_with_covar_cortical = run_meta_REML(initial_study_list = combined_df_with_covar_meta_cortical_list,
  3114. blood_df_to_compare = blood_df_with_covar)
  3115. REML_meta_with_covar_cortical = REML_analysis_container_with_covar_cortical[["meta_analysis_df"]]
  3116. REML_meta_with_covar_cortical = add_RRA_to_meta_df(REML_meta_with_covar_cortical, combined_df_with_covar_meta_cortical_list)
  3117. REML_meta_with_covar_cortical_signif = REML_meta_with_covar_cortical[REML_meta_with_covar_cortical$meta_pval < 0.05,]
  3118. REML_meta_with_covar_cortical_signif = REML_meta_with_covar_cortical_signif[!is.na(REML_meta_with_covar_cortical_signif$meta_pval),]
  3119. nrow(REML_meta_with_covar_cortical_signif)
  3120. ################### REML Meta prefrontal regions (no covar) ###################
  3121. combined_df_no_covar_meta_prefrontal = combined_df_no_covar
  3122. combined_df_no_covar_meta_prefrontal = combined_df_no_covar_meta_prefrontal[combined_df_no_covar_meta_prefrontal$Tissue_type == "Brain",]
  3123. blood_df_no_covar = combined_df_no_covar[combined_df_no_covar$Tissue_type == "Blood",]
  3124. table(combined_df_no_covar_meta_prefrontal$Tissue, combined_df_no_covar_meta_prefrontal$Study)
  3125. # Tissues to include
  3126. combined_df_no_covar_meta_prefrontal = combined_df_no_covar_meta_prefrontal[combined_df_no_covar_meta_prefrontal$Tissue %in%
  3127. c("DLPFC",
  3128. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  3129. "Dorsolateral Prefrontal Cortex",
  3130. "Dorsolateral prefrontal cortex (BA9)",
  3131. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3132. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  3133. "prefrontal cortex"),]
  3134. table(combined_df_no_covar_meta_prefrontal$Tissue, combined_df_no_covar_meta_prefrontal$Study)
  3135. "
  3136. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE5388 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  3137. DLPFC 0 0 0 0 0 22283 0 0 0
  3138. dorsal lateral prefrontal cortex (Brodmann Area 9) 18677 0 0 0 0 0 0 0 0
  3139. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 54675 22283
  3140. Dorsolateral prefrontal cortex (BA9) 0 0 19271 0 19191 0 0 0 0
  3141. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 21365 0 0 0 0 0 0 0
  3142. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0
  3143. prefrontal cortex 0 0 0 0 0 0 70523 0 0
  3144. "
  3145. combined_df_no_covar_meta_prefrontal_list = lapply(unique(combined_df_no_covar_meta_prefrontal$Study), function(x){
  3146. df = combined_df_no_covar_meta_prefrontal[combined_df_no_covar_meta_prefrontal$Study == x,]
  3147. return(df)
  3148. })
  3149. # Run meta-analysis
  3150. REML_analysis_container_no_covar_prefrontal = run_meta_REML(initial_study_list = combined_df_no_covar_meta_prefrontal_list,
  3151. blood_df_to_compare = blood_df_no_covar)
  3152. REML_meta_no_covar_prefrontal = REML_analysis_container_no_covar_prefrontal[["meta_analysis_df"]]
  3153. REML_meta_no_covar_prefrontal = add_RRA_to_meta_df(REML_meta_no_covar_prefrontal, combined_df_no_covar_meta_prefrontal_list)
  3154. REML_meta_no_covar_prefrontal_signif = REML_meta_no_covar_prefrontal[REML_meta_no_covar_prefrontal$meta_pval < 0.05,]
  3155. REML_meta_no_covar_prefrontal_signif = REML_meta_no_covar_prefrontal_signif[!is.na(REML_meta_no_covar_prefrontal_signif$meta_pval),]
  3156. nrow(REML_meta_no_covar_prefrontal_signif)
  3157. # Heterogeneity
  3158. summary(REML_meta_no_covar_prefrontal$I2)
  3159. "
  3160. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  3161. 0.00 0.00 14.48 24.13 45.66 97.75 33247
  3162. "
  3163. ################### REML Meta prefrontal regions (with covar) ###################
  3164. combined_df_with_covar_meta_prefrontal = combined_df_wth_covar
  3165. combined_df_with_covar_meta_prefrontal = combined_df_with_covar_meta_prefrontal[combined_df_with_covar_meta_prefrontal$Tissue_type == "Brain",]
  3166. blood_df_with_covar = combined_df_wth_covar[combined_df_wth_covar$Tissue_type == "Blood",]
  3167. # Tissues to include
  3168. combined_df_with_covar_meta_prefrontal = combined_df_with_covar_meta_prefrontal[combined_df_with_covar_meta_prefrontal$Tissue %in%
  3169. c("DLPFC",
  3170. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  3171. "Dorsolateral Prefrontal Cortex",
  3172. "Dorsolateral prefrontal cortex (BA9)",
  3173. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3174. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  3175. "prefrontal cortex"),]
  3176. table(combined_df_with_covar_meta_prefrontal$Tissue, combined_df_with_covar_meta_prefrontal$Study)
  3177. "
  3178. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE5388 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  3179. DLPFC 0 0 0 0 0 22283 0 0 0
  3180. dorsal lateral prefrontal cortex (Brodmann Area 9) 21197 0 0 0 0 0 0 0 0
  3181. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 54675 22283
  3182. Dorsolateral prefrontal cortex (BA9) 0 0 22389 0 24182 0 0 0 0
  3183. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 23331 0 0 0 0 0 0 0
  3184. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0
  3185. prefrontal cortex 0 0 0 0 0 0 70523 0 0
  3186. "
  3187. combined_df_with_covar_meta_prefrontal_list = lapply(unique(combined_df_with_covar_meta_prefrontal$Study), function(x){
  3188. df = combined_df_with_covar_meta_prefrontal[combined_df_with_covar_meta_prefrontal$Study == x,]
  3189. return(df)
  3190. })
  3191. # Run meta-analysis
  3192. REML_analysis_container_with_covar_prefrontal = run_meta_REML(initial_study_list = combined_df_with_covar_meta_prefrontal_list,
  3193. blood_df_to_compare = blood_df_with_covar)
  3194. REML_meta_with_covar_prefrontal = REML_analysis_container_with_covar_prefrontal[["meta_analysis_df"]]
  3195. REML_meta_with_covar_prefrontal = add_RRA_to_meta_df(REML_meta_with_covar_prefrontal, combined_df_with_covar_meta_prefrontal_list)
  3196. REML_meta_with_covar_prefrontal_signif = REML_meta_with_covar_prefrontal[REML_meta_with_covar_prefrontal$meta_pval < 0.05,]
  3197. REML_meta_with_covar_prefrontal_signif = REML_meta_with_covar_prefrontal_signif[!is.na(REML_meta_with_covar_prefrontal_signif$meta_pval),]
  3198. nrow(REML_meta_with_covar_prefrontal_signif)
  3199. ################### Saving REML sensitivity ###################
  3200. significant_genes_var = ls(pattern = "REML_meta_")
  3201. significant_genes_var = significant_genes_var[stri_detect_regex(significant_genes_var, pattern = "signif")]
  3202. significant_genes_var = significant_genes_var[!stri_detect_regex(significant_genes_var, pattern = "meta_list")]
  3203. significant_genes_counts = sapply(significant_genes_var, function(x) nrow(get(x)))
  3204. stats_meta = paste0("Signifi gene counts for: ", significant_genes_var)
  3205. stats_meta = paste0(stats_meta, " = ", significant_genes_counts)
  3206. writeLines(stats_meta, "stats_meta_REML.txt")
  3207. # saving files
  3208. REML_meta_list_no_covar_signif = list(
  3209. "REML_meta_no_covar_all_brain_signif" = REML_meta_no_covar_all_brain_signif,
  3210. "REML_meta_no_covar_cortical_signif" = REML_meta_no_covar_cortical_signif,
  3211. "REML_meta_no_covar_prefrontal_signif" = REML_meta_no_covar_prefrontal_signif
  3212. )
  3213. REML_meta_list_with_covar_signif = list(
  3214. "REML_meta_with_covar_all_brain_signif" = REML_meta_with_covar_all_brain_signif,
  3215. "REML_meta_with_covar_cortical_signif" = REML_meta_with_covar_cortical_signif,
  3216. "REML_meta_with_covar_prefrontal_signif" = REML_meta_with_covar_prefrontal_signif
  3217. )
  3218. REML_joined_list_significant = c(REML_meta_list_no_covar_signif, REML_meta_list_with_covar_signif)
  3219. REML_joined_list_significant = lapply(REML_joined_list_significant, function(x){
  3220. x = dplyr::arrange(x, -meta_LFc)
  3221. return(x)
  3222. })
  3223. names_for_list = c(
  3224. "REML All brain",
  3225. "REML Cortical regions",
  3226. "REML DLPFC",
  3227. "REML All brain (covar)",
  3228. "REML Cortical regions (covar)",
  3229. "REML DLPFC (covar)"
  3230. )
  3231. names(REML_joined_list_significant)
  3232. wb = createWorkbook()
  3233. for (i in 1:6) {
  3234. # Add a new worksheet with the sheet name
  3235. addWorksheet(wb, names_for_list[i])
  3236. # Write the data frame to the worksheet
  3237. writeData(wb, sheet = names_for_list[i], REML_joined_list_significant[[i]])
  3238. # Adjust column widths to fit the text
  3239. setColWidths(wb, sheet = names_for_list[i], cols = 1:ncol(REML_joined_list_significant[[i]]), widths = "auto")
  3240. }
  3241. saveWorkbook(wb, "Meta_suicide_significant_genes_REML.xlsx", overwrite = TRUE)
  3242. ################### SV meta (all brain) ###################
  3243. combined_df_SV_meta_all = combined_df_SV
  3244. combined_df_SV_meta_all = combined_df_SV_meta_all[combined_df_SV_meta_all$Tissue_type == "Brain",]
  3245. blood_df_SV = combined_df_SV[combined_df_SV$Tissue_type == "Blood",]
  3246. table(combined_df_SV_meta_all$Tissue, combined_df_SV_meta_all$Study)
  3247. # GSE102556 many tissues
  3248. # GSE202537 many tissues
  3249. # GSE66937 many tissues
  3250. combined_df_SV_meta_all_1 = combined_df_SV_meta_all[combined_df_SV_meta_all$Study %!in% c("GSE102556", "GSE202537", "GSE66937"), ]
  3251. combined_df_SV_meta_all_2 = combined_df_SV_meta_all[combined_df_SV_meta_all$Study %in% c("GSE102556", "GSE202537", "GSE66937"), ]
  3252. # Caudate https://pubmed.ncbi.nlm.nih.gov/39164232/
  3253. # Nac https://pubmed.ncbi.nlm.nih.gov/38894648/ https://pubmed.ncbi.nlm.nih.gov/38965529/ https://pubmed.ncbi.nlm.nih.gov/39167467/
  3254. # GSE102556 -> Dorsolateral prefrontal cortex (dlPFC; BA8/9)
  3255. # GSE202537 -> Nac 22652 (more probes analyzed)
  3256. # GSE66937 -> prefrontal cortex
  3257. combined_df_SV_meta_all_2 = combined_df_SV_meta_all_2[combined_df_SV_meta_all_2$Tissue %in% c("Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3258. "Nac",
  3259. "prefrontal cortex"),]
  3260. table(combined_df_SV_meta_all_2$Tissue)
  3261. "
  3262. Dorsolateral prefrontal cortex (dlPFC; BA8/9) Nac prefrontal cortex
  3263. 21365 22652 70523
  3264. "
  3265. combined_df_SV_meta_full = rbind(combined_df_SV_meta_all_1, combined_df_SV_meta_all_2)
  3266. table(combined_df_SV_meta_full$Tissue, combined_df_SV_meta_full$Study)
  3267. combined_df_SV_meta_full_list = lapply(unique(combined_df_SV_meta_full$Study), function(x){
  3268. df = combined_df_SV_meta_full[combined_df_SV_meta_full$Study == x,]
  3269. return(df)
  3270. })
  3271. # Run meta-analysis
  3272. analysis_container_SV_all_brain = run_meta_SJ(initial_study_list = combined_df_SV_meta_full_list,
  3273. blood_df_to_compare = blood_df_SV)
  3274. meta_SV_all_brain = analysis_container_SV_all_brain[["meta_analysis_df"]]
  3275. combined_df_SV_meta_full_list_reduced = analysis_container_SV_all_brain[["initial_study_list_reduced"]]
  3276. meta_SV_all_brain = add_RRA_to_meta_df(meta_SV_all_brain, combined_df_SV_meta_full_list)
  3277. meta_SV_all_brain_signif = meta_SV_all_brain[meta_SV_all_brain$meta_pval < 0.05,]
  3278. meta_SV_all_brain_signif = meta_SV_all_brain_signif[!is.na(meta_SV_all_brain_signif$meta_pval),]
  3279. meta_SV_all_brain_signif = arrange(meta_SV_all_brain_signif, -meta_LFc)
  3280. nrow(meta_SV_all_brain_signif)
  3281. # Heterogeneity
  3282. summary(meta_SV_all_brain$I2)
  3283. "
  3284. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  3285. 0.031 25.926 40.445 41.201 55.704 98.730 28644
  3286. "
  3287. # plots
  3288. dir.create("forest_plots")
  3289. folder = "forest_plots/meta_SV_all_brain"
  3290. dir.create(folder)
  3291. for (i in 1:nrow(meta_SV_all_brain_signif)){
  3292. gene = meta_SV_all_brain$gene[i]
  3293. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  3294. pdf(file = plot_path, width = 10, height = 7)
  3295. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_SV_meta_full_list_reduced))
  3296. dev.off()
  3297. }
  3298. ################### SV meta (cortical) ###################
  3299. combined_df_SV_meta_cortical = combined_df_SV
  3300. combined_df_SV_meta_cortical = combined_df_SV_meta_cortical[combined_df_SV_meta_cortical$Tissue_type == "Brain",]
  3301. blood_df_SV = combined_df_SV[combined_df_SV$Tissue_type == "Blood",]
  3302. table(combined_df_SV_meta_cortical$Tissue, combined_df_SV_meta_cortical$Study)
  3303. combined_df_SV_meta_cortical = combined_df_SV_meta_cortical[combined_df_SV_meta_cortical$Tissue %in%
  3304. c("DLPFC",
  3305. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  3306. "Dorsolateral Prefrontal Cortex",
  3307. "Dorsolateral prefrontal cortex (BA9)",
  3308. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3309. "Orbitofrontal cortex",
  3310. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  3311. "prefrontal cortex",
  3312. "temporal cortex (BA20 and BA36)"),]
  3313. table(combined_df_SV_meta_cortical$Tissue, combined_df_SV_meta_cortical$Study)
  3314. "
  3315. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE243356 GSE5388 GSE5389 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  3316. DLPFC 0 0 0 0 0 0 22283 0 0 0 0
  3317. dorsal lateral prefrontal cortex (Brodmann Area 9) 18677 0 0 0 0 0 0 0 0 0 0
  3318. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 0 0 54675 22283
  3319. Dorsolateral prefrontal cortex (BA9) 0 0 19271 0 19191 0 0 0 0 0 0
  3320. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 21365 0 0 0 0 0 0 0 0 0
  3321. Orbitofrontal cortex 0 0 0 0 0 0 0 22283 0 0 0
  3322. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0 0 0
  3323. prefrontal cortex 0 0 0 0 0 0 0 0 70523 0 0
  3324. temporal cortex (BA20 and BA36) 0 0 0 0 0 20955 0 0 0 0 0
  3325. "
  3326. combined_df_SV_meta_cortical_list = lapply(unique(combined_df_SV_meta_cortical$Study), function(x){
  3327. df = combined_df_SV_meta_cortical[combined_df_SV_meta_cortical$Study == x,]
  3328. return(df)
  3329. })
  3330. # Run meta-analysis
  3331. analysis_container_SV_cortical = run_meta_SJ(initial_study_list = combined_df_SV_meta_cortical_list,
  3332. blood_df_to_compare = blood_df_SV)
  3333. meta_SV_cortical = analysis_container_SV_cortical[["meta_analysis_df"]]
  3334. combined_df_SV_meta_cortical_list_reduced = analysis_container_SV_cortical[["initial_study_list_reduced"]]
  3335. meta_SV_cortical = add_RRA_to_meta_df(meta_SV_cortical, combined_df_SV_meta_cortical_list)
  3336. meta_SV_cortical_signif = meta_SV_cortical[meta_SV_cortical$meta_pval < 0.05,]
  3337. meta_SV_cortical_signif = meta_SV_cortical_signif[!is.na(meta_SV_cortical_signif$meta_pval),]
  3338. meta_SV_cortical_signif = arrange(meta_SV_cortical_signif, -meta_LFc)
  3339. nrow(meta_SV_cortical_signif)
  3340. summary(meta_SV_cortical$I2)
  3341. "
  3342. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  3343. 0.033 22.011 37.720 39.168 54.900 97.410 31325
  3344. "
  3345. dir.create("forest_plots")
  3346. folder = "forest_plots/meta_SV_cortical"
  3347. dir.create(folder)
  3348. for (i in 1:nrow(meta_SV_cortical_signif)){
  3349. gene = meta_SV_cortical$gene[i]
  3350. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  3351. pdf(file = plot_path, width = 10, height = 7)
  3352. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_SV_meta_cortical_list_reduced))
  3353. dev.off()
  3354. }
  3355. ################### SV meta (prefrontal) ###################
  3356. combined_df_SV_meta_prefrontal = combined_df_SV
  3357. combined_df_SV_meta_prefrontal = combined_df_SV_meta_prefrontal[combined_df_SV_meta_prefrontal$Tissue_type == "Brain",]
  3358. blood_df_SV = combined_df_SV[combined_df_SV$Tissue_type == "Blood",]
  3359. table(combined_df_SV_meta_prefrontal$Tissue, combined_df_SV_meta_prefrontal$Study)
  3360. combined_df_SV_meta_prefrontal = combined_df_SV_meta_prefrontal[combined_df_SV_meta_prefrontal$Tissue %in%
  3361. c("DLPFC",
  3362. "dorsal lateral prefrontal cortex (Brodmann Area 9)",
  3363. "Dorsolateral Prefrontal Cortex",
  3364. "Dorsolateral prefrontal cortex (BA9)",
  3365. "Dorsolateral prefrontal cortex (dlPFC; BA8/9)",
  3366. "postmortem dorsolateral prefrontal cortex (DLPFC)",
  3367. "prefrontal cortex"),]
  3368. table(combined_df_SV_meta_prefrontal$Tissue, combined_df_SV_meta_prefrontal$Study)
  3369. "
  3370. GSE101521 GSE102556 GSE144136 GSE208338 GSE213982 GSE5388 GSE66937 GSE92538_U133_PLUS2 GSE92538_U133A
  3371. DLPFC 0 0 0 0 0 22283 0 0 0
  3372. dorsal lateral prefrontal cortex (Brodmann Area 9) 18677 0 0 0 0 0 0 0 0
  3373. Dorsolateral Prefrontal Cortex 0 0 0 0 0 0 0 54675 22283
  3374. Dorsolateral prefrontal cortex (BA9) 0 0 19271 0 19191 0 0 0 0
  3375. Dorsolateral prefrontal cortex (dlPFC; BA8/9) 0 21365 0 0 0 0 0 0 0
  3376. postmortem dorsolateral prefrontal cortex (DLPFC) 0 0 0 750011 0 0 0 0 0
  3377. prefrontal cortex 0 0 0 0 0 0 70523 0 0
  3378. "
  3379. combined_df_SV_meta_prefrontal_list = lapply(unique(combined_df_SV_meta_prefrontal$Study), function(x){
  3380. df = combined_df_SV_meta_prefrontal[combined_df_SV_meta_prefrontal$Study == x,]
  3381. return(df)
  3382. })
  3383. # Run meta-analysis
  3384. analysis_container_SV_prefrontal = run_meta_SJ(initial_study_list = combined_df_SV_meta_prefrontal_list,
  3385. blood_df_to_compare = blood_df_SV)
  3386. meta_SV_prefrontal = analysis_container_SV_prefrontal[["meta_analysis_df"]]
  3387. combined_df_SV_meta_prefrontal_list_reduced = analysis_container_SV_prefrontal[["initial_study_list_reduced"]]
  3388. meta_SV_prefrontal = add_RRA_to_meta_df(meta_SV_prefrontal, combined_df_SV_meta_prefrontal_list)
  3389. meta_SV_prefrontal_signif = meta_SV_prefrontal[meta_SV_prefrontal$meta_pval < 0.05,]
  3390. meta_SV_prefrontal_signif = meta_SV_prefrontal_signif[!is.na(meta_SV_prefrontal_signif$meta_pval),]
  3391. meta_SV_prefrontal_signif = arrange(meta_SV_prefrontal_signif, -meta_LFc)
  3392. nrow(meta_SV_prefrontal_signif)
  3393. summary(meta_SV_prefrontal$I2)
  3394. "
  3395. Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
  3396. 0.02 18.40 33.37 35.54 50.55 98.13 33247
  3397. "
  3398. dir.create("forest_plots")
  3399. folder = "forest_plots/meta_SV_prefrontal"
  3400. dir.create(folder)
  3401. for (i in 1:nrow(meta_SV_prefrontal_signif)){
  3402. gene = meta_SV_prefrontal$gene[i]
  3403. plot_path = paste0(folder, "/", gene, "_forest.pdf")
  3404. pdf(file = plot_path, width = 10, height = 7)
  3405. print(plot_forest_meta_gene(gene_name = gene, meta_df = combined_df_SV_meta_prefrontal_list_reduced))
  3406. dev.off()
  3407. }
  3408. ################### Saving SV sensitivity ###################
  3409. # SV numbers
  3410. # GSE208338 -> 1 suggested
  3411. # GSE5388 -> 5 suggested and 5 used
  3412. # GSE5389 -> 0 suggested
  3413. # GSE66937 -> DLPFC 0 suggested
  3414. # GSE199536 -> 5 suggested and 5 used
  3415. # GSE92538_U133A -> 3 suggested
  3416. # GSE92538_U133_PLUS2 -> 2 suggested
  3417. # GSE102556 -> very large number -> 5 used
  3418. # GSE243356 -> very large number (59) -> 5 used
  3419. # GSE248260 -> very large number (22) -> 5 used
  3420. # GSE247998 -> very large number (98) -> 5 used
  3421. # GSE202537 -> very large number (>60) -> 5 used
  3422. # GSE101521 -> very large number (57) -> 5 used
  3423. # GSE144136 -> very large number (30) -> 5 used
  3424. # GSE213982 -> very large number (34) -> 5 used
  3425. significant_genes_var = ls(pattern = "meta_SV")
  3426. significant_genes_var = significant_genes_var[stri_detect_regex(significant_genes_var, pattern = "signif")]
  3427. significant_genes_var = significant_genes_var[!stri_detect_regex(significant_genes_var, pattern = "meta_list")]
  3428. significant_genes_counts = sapply(significant_genes_var, function(x) nrow(get(x)))
  3429. stats_meta = paste0("Signifi gene counts for: ", significant_genes_var)
  3430. stats_meta = paste0(stats_meta, " = ", significant_genes_counts)
  3431. writeLines(stats_meta, "stats_meta_SV.txt")
  3432. # saving files
  3433. meta_list_SV_signif = list(
  3434. "meta_SV_all_brain_signif" = meta_SV_all_brain_signif,
  3435. "meta_SV_cortical_signif" = meta_SV_cortical_signif,
  3436. "meta_SV_prefrontal_signif" = meta_SV_prefrontal_signif
  3437. )
  3438. names_for_list = c(
  3439. "Meta all brain (SVs)",
  3440. "Meta cortical (SVs)",
  3441. "Meta prefrontal cortex (SVs)"
  3442. )
  3443. wb = createWorkbook()
  3444. for (i in 1:3) {
  3445. # Add a new worksheet with the sheet name
  3446. addWorksheet(wb, names_for_list[i])
  3447. # Write the data frame to the worksheet
  3448. writeData(wb, sheet = names_for_list[i], meta_list_SV_signif[[i]])
  3449. # Adjust column widths to fit the text
  3450. setColWidths(wb, sheet = names_for_list[i], cols = 1:ncol(meta_list_SV_signif[[i]]), widths = "auto")
  3451. }
  3452. saveWorkbook(wb, "Meta_suicide_significant_genes_SV.xlsx", overwrite = TRUE)
  3453. ## Save volcano plots
  3454. # making volcanos in a loop
  3455. joined_list_all_metas_SV = list(
  3456. meta_SV_all_brain,
  3457. meta_SV_cortical,
  3458. meta_SV_prefrontal
  3459. )
  3460. names_for_list_all = c("All brain (SVs)", "Cortical (SVs)", "DLPFC (SVs)")
  3461. for (i in 1:3){
  3462. curr_df = joined_list_all_metas_SV[[i]]
  3463. plot_path = paste0("volcano_plots/", names_for_list_all[i], ".png")
  3464. plot_meta_volcano(curr_df, figure_path = plot_path, title = names_for_list_all[i])
  3465. }
  3466. ################### Venn diagrams for SVs ###################
  3467. meta_list_SV_signif = list(
  3468. meta_SV_all_brain_signif,
  3469. meta_SV_cortical_signif,
  3470. meta_SV_prefrontal_signif
  3471. )
  3472. meta_gene_list_overlaps_SV = lapply(meta_list_SV_signif, function(x){
  3473. x = x$gene
  3474. return(x)
  3475. })
  3476. names(meta_gene_list_overlaps_SV) = c(
  3477. "All brain",
  3478. "Cortical regions",
  3479. "DLPFC"
  3480. )
  3481. make_Venn_digram_list(named_list = meta_gene_list_overlaps_SV, palette = 9, plot_full_path = "Venn_SV.pdf")
  3482. dir.create("analyses_comparison_covar_SV_nothing_venn")
  3483. meta_gene_list_SVs = list(
  3484. meta_no_covar_all_brain_signif,
  3485. meta_SV_all_brain_signif,
  3486. meta_with_covar_all_brain_signif
  3487. )
  3488. meta_gene_list_SVs = lapply(meta_gene_list_SVs, function(x){
  3489. x = x$gene
  3490. return(x)
  3491. })
  3492. names(meta_gene_list_SVs) = c(
  3493. "All brain (no covar)",
  3494. "All brain (SVs)",
  3495. "All brain (covar)"
  3496. )
  3497. make_Venn_digram_list(named_list = meta_gene_list_SVs,
  3498. palette = 5,
  3499. label_text_size = 7,
  3500. plot_full_path = "analyses_comparison_covar_SV_nothing_venn/1_Venn_SVs_vs_other_all.png")
  3501. meta_gene_list_SVs = list(
  3502. meta_no_covar_cortical_signif,
  3503. meta_SV_cortical_signif,
  3504. meta_with_covar_cortical_signif
  3505. )
  3506. meta_gene_list_SVs = lapply(meta_gene_list_SVs, function(x){
  3507. x = x$gene
  3508. return(x)
  3509. })
  3510. names(meta_gene_list_SVs) = c(
  3511. "Cortical (no covar)",
  3512. "Cortical (SVs)",
  3513. "Cortical (covar)"
  3514. )
  3515. make_Venn_digram_list(named_list = meta_gene_list_SVs,
  3516. label_text_size = 7,
  3517. palette = 4, plot_full_path = "analyses_comparison_covar_SV_nothing_venn/2_Venn_SVs_vs_other_cortical.png")
  3518. meta_gene_list_SVs = list(
  3519. meta_no_covar_prefrontal_signif,
  3520. meta_SV_prefrontal_signif,
  3521. meta_with_covar_prefrontal_signif
  3522. )
  3523. meta_gene_list_SVs = lapply(meta_gene_list_SVs, function(x){
  3524. x = x$gene
  3525. return(x)
  3526. })
  3527. names(meta_gene_list_SVs) = c(
  3528. "Prefrontal (no covar)",
  3529. "Prefrontal (SVs)",
  3530. "Prefrontal (covar)"
  3531. )
  3532. make_Venn_digram_list(named_list = meta_gene_list_SVs,
  3533. label_text_size = 7,
  3534. palette = 3, plot_full_path = "analyses_comparison_covar_SV_nothing_venn/3_Venn_SVs_vs_other_prefrontal.png")
  3535. # Define cropping function
  3536. crop_image <- function(img, row_range, col_range) {
  3537. # img: 3D array (height, width, channels)
  3538. img[row_range, col_range, , drop = FALSE]
  3539. }
  3540. images_in_folder = list.files("analyses_comparison_covar_SV_nothing_venn", full.names = TRUE)
  3541. images_in_folder = images_in_folder[!grepl("combined_image", images_in_folder)]
  3542. image_list = lapply(images_in_folder, png::readPNG)
  3543. # Define cropping region
  3544. row_range = 50:950
  3545. col_range = 50:950
  3546. cropped_list = lapply(image_list, crop_image, row_range, col_range)
  3547. image_grobs = lapply(cropped_list, rasterGrob)
  3548. # Combine
  3549. height = length(row_range)
  3550. width = length(col_range)
  3551. combined_file_name = "analyses_comparison_covar_SV_nothing_venn/Venn_DE_comparison_combined_image.png"
  3552. png(filename = combined_file_name, width = width*3, height = height, units = "px")
  3553. grid.arrange(grobs = image_grobs[1:3], ncol = 3)
  3554. dev.off()
  3555. ################### Moderator analysis for RE with SJ ###################
  3556. cohort_moderators_data = openxlsx::read.xlsx("Cohort_moderators.xlsx")
  3557. colnames(cohort_moderators_data)[1] = "Study"
  3558. cohort_moderators_data = cohort_moderators_data[cohort_moderators_data$Study != "GSE66937", ]
  3559. cohort_moderators_data$Platform_binary = factor(cohort_moderators_data$Platform_binary, levels = c( "Array", "RNAseq"))
  3560. cohort_moderators_data$Primary_tissue_group = factor(cohort_moderators_data$Primary_tissue_group,
  3561. levels = c( "Cortical", "Non_cortical")) # Better to stratify
  3562. # Moderators to include
  3563. cohort_moderators_data$Platform_binary
  3564. cohort_moderators_data$Mean_PMI_hours
  3565. cohort_moderators_data$Percent_male
  3566. cohort_moderators_data$Percent_Depr
  3567. cohort_mode

OLINK_PSY_SUICIDE_SCRIPT.R at commit 63e5b8e, under GPL-3.0 · at the source

Overview

Authors: Aleksandr V. Sokolov1, Muataz S. Lafta1, Jussi Jokinen2,3, Helgi B. Schiöth1,4
  1. Department of Surgical Sciences, Functional Pharmacology and Neuroscience, Uppsala University,Uppsala, Sweden
  2. Department of Clinical Neuroscience/Center for Psychiatric Research, Karolinska Institutet,Stockholm, Sweden
  3. Department of Clinical Sciences/Psychiatry, Umeå University,Umeå, Sweden
  4. Laboratory of Pharmaceutical Pharmacology, Latvian Institute of Organic Synthesis,Riga, Latvia
Journal: Translational psychiatry, volume 16, issue 1, article 222
Dates: received 14 March 2025; accepted 10 March 2026; published online 31 March 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s41398-026-03978-8 · PMID 41916959 · PMCID PMC13039836 · OpenAlex W7144332257
Open access: gold, a free copy (OpenAlex)
Status: code verified (how the code is found and verified)
Categories: genetics / omics (modality), human (organism), cellular / molecular (subfield)
Methods: Statistics
Keywords: Molecular neuroscience, Biomarkers
MeSH: Brain*, Suicide*, Transcriptome*, Cohort Studies, CX3C Chemokine Receptor 1, Gene Expression Profiling, Humans, RNA, Long Noncoding, Single-Cell Gene Expression Analysis, SOX9 Transcription Factor (* major topic)
Topic: Tryptophan and brain disorders (Biological Psychiatry, Neuroscience), according to OpenAlex
Citations: cited by 2 papers (Europe PMC); 123 references in the paper

Abstract

Suicide remains a critical global public health issue, accounting for nearly one million deaths annually and imposing profound societal and economic burdens. Despite its urgency, the lack of diagnostic and predictive biomarkers continues to hinder the development of effective prevention and treatment strategies. This study presents a comprehensive meta-analysis that integrates publicly available postmortem brain transcriptomic datasets and a domestic cohort, encompassing 16 cohorts. The transcriptomic data, sourced from the Gene Expression Omnibus repository, were generated using various techniques, including traditional RNA sequencing, microarray methods, and single-cell RNA sequencing. Differential expression analyses were performed across multiple brain regions, with meta-analyses stratified by cortical regions, the dorsolateral prefrontal cortex (DLPFC), and combined. We further analyzed whether covariates may affect the identified genes. Three meta-analytic approaches were employed, complemented by pathway and cell-set enrichment analyses. The unadjusted meta-analysis consistently identified several genes with altered expression, including upregulated P2RY12, CX3CR1, and GPR34, and downregulated SOX9 and PMP2, all at nominal significance. Additionally, multiple genes encoding long non-coding RNAs (lncRNAs) exhibited nominally altered expression in suicide, including RP5-837J1.4, AC159540.14, DNM1P47, AC004158.2, EEF1A1P30, and RP11-339B21.8. Several alternative strategies to run meta-analysis were performed and moderators were investigated. Cell-type-specific expression deconvolution and meta-analysis identified several genes overlapping with bulk expression meta-analysis, and genes were attributed to neuronal lineages. These findings highlight plausible molecular targets for future validation studies, suggesting the involvement of microglia (P2RY12 and CX3CR1), astrocytes (SOX9), immune responses (GPR34), myelin regulation (PMP2), and epigenetic modulation via lncRNAs. This research advances the understanding of the molecular architecture of suicide and provides a foundation for future studies focused on targeted prevention and therapeutic interventions.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 23 matches between paragraphs and lines of code.

AleksandrVSokolov/suicide_meta

License: GPL-3.0
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: 63e5b8ed9b68270cd9b39a74f6031239e177fc49, 10 April 2026
Languages: R (7), Jupyter (5), Python (4), Shell (3)
Size: 21 files, 19 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file, 5 notebooks
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: pandas (8 files), clusterProfiler (6 files), data.table (6 files), ggplot2 (6 files), igraph (6 files), limma (6 files), tidyverse (6 files), metafor (4 files), Seurat (4 files), edgeR (3 files)
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
21 files

Code availability

The source code for all stages of the work is publicly-available at https://github.com/AleksandrVSokolov/suicide_meta.

Reproduced under the paper's license (CC BY), from the paper cited above.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 19 scripts, each with its path and the digest of its content;
  • 23 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data availability

This analysis is based on open-access transcriptomic datasets available at GEO.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 30 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 4 authors, 2 keywords, 10 MeSH terms, 1 funder, 118 references.

Cite

This paper

Sokolov, A. V., Lafta, M. S., Jokinen, J., & Schiöth, H. B. (2026). Identification of suicide brain transcriptomic signatures using meta-analysis of multiple cohorts. Translational psychiatry, 16(1), 222. https://doi.org/10.1038/s41398-026-03978-8

BibTeX

@article{sokolov2026identification,
author = {Sokolov, Aleksandr V. and Lafta, Muataz S. and Jokinen, Jussi and Schiöth, Helgi B.},
title = {{Identification of suicide brain transcriptomic signatures using meta-analysis of multiple cohorts}},
journal = {Translational psychiatry},
year = {2026},
month = mar,
volume = {16},
number = {1},
pages = {222},
publisher = {Nature Publishing Group},
issn = {2158-3188},
doi = {10.1038/s41398-026-03978-8},
url = {https://doi.org/10.1038/s41398-026-03978-8},
pmid = {41916959},
pmcid = {PMC13039836}
}

RIS

TY - JOUR
AU - Sokolov, Aleksandr V.
AU - Lafta, Muataz S.
AU - Jokinen, Jussi
AU - Schiöth, Helgi B.
TI - Identification of suicide brain transcriptomic signatures using meta-analysis of multiple cohorts
T2 - Translational psychiatry
J2 - Transl Psychiatry
PY - 2026
DA - 2026/03/31
VL - 16
IS - 1
SP - 222
SN - 2158-3188
PB - Nature Publishing Group
DO - 10.1038/s41398-026-03978-8
UR - https://doi.org/10.1038/s41398-026-03978-8
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41398-026-03978-8",
"type": "article-journal",
"title": "Identification of suicide brain transcriptomic signatures using meta-analysis of multiple cohorts",
"container-title": "Translational psychiatry",
"author": [
{
"family": "Sokolov",
"given": "Aleksandr V."
},
{
"family": "Lafta",
"given": "Muataz S."
},
{
"family": "Jokinen",
"given": "Jussi"
},
{
"family": "Schiöth",
"given": "Helgi B."
}
],
"container-title-short": "Transl Psychiatry",
"volume": "16",
"issue": "1",
"page": "222",
"DOI": "10.1038/s41398-026-03978-8",
"PMID": "41916959",
"PMCID": "PMC13039836",
"ISSN": "2158-3188",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41398-026-03978-8",
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
31
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41467-026-71542-5 [code]
Astrocyte fatty acid metabolism as a driver of risk for major depressive disorder.
Journal: Nature communications
In common: edgeR, limma, igraph, 4 other tools, genetics / omics, cellular / molecular, 6 references
[2] doi:10.1186/s12888-026-08170-2
Gene expression meta-analysis in the prefrontal cortex: unraveling biological underpinnings of suicidal risk.
Journal: BMC psychiatry
In common: genetics / omics, 11 references
[3] doi:10.1038/s41467-025-59115-4 [code]
Large-scale transcriptomic analyses of major depressive disorder reveal convergent dysregulation of synaptic pathways in excitatory neurons.
Journal: Nature communications
In common: edgeR, limma, clusterProfiler, 5 other tools, genetics / omics, cellular / molecular, 5 references
[4] doi:10.1007/s00401-026-03035-0
Expression of GPR34 in microglia remains stable in human Alzheimer's disease.
Journal: Acta neuropathologica
In common: cellular / molecular, 9 references
[5] doi:10.1038/s41467-023-38530-5 [code]
Cell type specific transcriptomic differences in depression show similar patterns between males and females but implicate distinct cell types and genes.
Journal: Nature communications
In common: edgeR, limma, clusterProfiler, 5 other tools, genetics / omics, cellular / molecular, 4 references
[6] doi:10.1038/s41593-026-02367-0 [code]
A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes.
Journal: Nature neuroscience
In common: edgeR, limma, clusterProfiler, 5 other tools, cellular / molecular, 3 references
[7] doi:10.1038/s41586-025-10047-5 [code]
Developmental convergence and divergence in human stem cell models of autism.
Journal: Nature
In common: metafor, edgeR, limma, 6 other tools, genetics / omics, 1 reference
[8] doi:10.3390/ijms27136068 [code]
Loss of Neuropeptide Y Signaling Accompanies the Neural-to-Mesenchymal Transcriptional Transition in Glioblastoma: A Multi-Scale Transcriptomic Analysis.
Journal: International journal of molecular sciences
In common: metafor, edgeR, limma, 5 other tools, genetics / omics, cellular / molecular, 2 references
[9] doi:10.1126/sciadv.adu0726 [code]
CHCHD2 mutant mice link mitochondrial deficits to PD pathophysiology.
Journal: Science advances
In common: metafor, edgeR, limma, 5 other tools, cellular / molecular, 1 reference
[10] doi:10.1038/s41591-024-03150-z [code]
A brain cell atlas integrating single-cell transcriptomes across human brain regions.
Journal: Nature medicine
In common: edgeR, clusterProfiler, igraph, 5 other tools, genetics / omics, 2 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.1038/s41398-026-03978-8.svg)](https://openscicode.org/badge/doi/10.1038/s41398-026-03978-8)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.1038/s41398-026-03978-8.svg
   :target: https://openscicode.org/badge/doi/10.1038/s41398-026-03978-8
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1038/s41398-026-03978-8"><img src="https://openscicode.org/badge/doi/10.1038/s41398-026-03978-8.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.