OSCR

Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms.

Code ↔ Paper

40 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 40 matches · 10 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § Methods › Analysis of differential gene and transcript expression › Differential transcript usage (DTU) and expression (DTE) ↔ analysis/Figure3_IsoformSwitchAnalyzeR.qmd, lines 93–127 · score 0.88 · geneExpressionCutoff, isoformExpressionCutoff, importRdata, IFcutoff, pre filtering, imported
  2. [2] § Methods › Analysis of differential gene and transcript expression › Differential transcript usage (DTU) and expression (DTE) ↔ scripts/figures/figure_4/IsoformSwitchAnalyzeR.R, lines 114–152 · score 0.85 · geneExpressionCutoff, isoformExpressionCutoff, IFcutoff, pre filtering, imported, DTE
  3. [3] § Methods › Functional genomics data analysis › Ribosome profiling reanalysis ↔ scripts/generate_STAR_scripts.sh, the whole file · a weak match · score 0.83 · SortedByCoordinate, outSAMtype, readFilesCommand, runThreadN, STAR, BAM
  4. [4] § Methods › Analysis of differential gene and transcript expression › Identification and characterization of alternative transcript processing event coordination ↔ bin/spearman_per_sample.py, lines 68–137 · score 0.79 · chromEnd, chromStart, CAGE peak, polyA site, intersected, strand
  5. [5] § Methods › Functional genomics data analysis › Open reading frame prediction and classification ↔ scripts/figures/supplementary/Fig_S7.R, the whole file · a weak match · score 0.78 · pISM, pFSM, pNIC, pNNC, minimal, ORFanage
  6. [6] § Methods › Functional genomics data analysis › Long-read RNA-seq data processing ↔ bin/plot_lrs_comparison.py, lines 284–410 · score 0.77 · splice junction support, transcript models, Iso Seq, polyA, Bambu, tool
  7. [7] § Methods › Analysis of differential gene and transcript expression › Analysis of differential protein expression ↔ scripts/figures/figure_3/CPM_DESeq2_clusters.R, lines 408–459 · score 0.76 · groupComparisonTMT, proteinSummarization, MSstatsTMT, intensity, channel, peptides
  8. [8] § Methods › Analysis of differential gene and transcript expression › Identification and characterization of alternative transcript processing event coordination ↔ bin/spearman_per_sample.py, lines 68–137 · score 0.76 · soloT, dualT, CAGE peak, polyA site, Spearman, exon
  9. [9] § Methods › Functional genomics data analysis › Open reading frame prediction and classification ↔ scripts/figures/figure_2/peotein_classification.R, the whole file · a weak match · score 0.75 · pISM, pFSM, pNIC, pNNC, classification, ORFanage
  10. [10] § Methods › Analysis of differential gene and transcript expression › Preprocessing and differential gene expression (DGE) ↔ scripts/figures/figure_5/event_TSS_categorization.R, lines 87–135 · score 0.75 · PB IDs, NNC categories, predicted ORFs, ORFanage, FSM, sum
  11. [11] § Methods › Analysis of differential gene and transcript expression › Preprocessing and differential gene expression (DGE) ↔ scripts/figures/figure_5/event_pA_categorization.R, lines 83–131 · score 0.75 · PB IDs, NNC categories, predicted ORFs, ORFanage, FSM, sum
  12. [12] § Methods › Functional genomics data analysis › Long-read RNA-seq data processing ↔ bin/plot_sr_cage_support.py, lines 202–308 · score 0.73 · Iso Seq transcript, splice junction support, polyA, Bambu, CAGE, tool
  13. [13] § Methods › Analysis of differential gene and transcript expression › Gene set and functional enrichment analysis ↔ scripts_for_Nuo/making_figures/Figures.R, lines 309–392 · score 0.72 · term enrichment, ASD risk gene, GO terms, protein expression, cluster
  14. [14] § Methods › Analysis of differential gene and transcript expression › Identification and characterization of alternative transcript processing event coordination ↔ bin/plot_sr_cage_support.py, lines 202–308 · score 0.71 · refTSS, CAGE peak, atlas clusters, polyA, strand, transcript
  15. [15] § Methods › Functional genomics data analysis › Long-read RNA-seq data processing ↔ bin/filter_by_exp_ext.py, lines 77–178 · score 0.70 · refTSS, CAGE peaks, polyA, priming, incomplete, fragments
  16. [16] § Methods › Functional genomics data analysis › Quantification of known proteins ↔ bin/filter_scan_number.py, the whole file · a weak match · score 0.67 · mzXML, precursor, cysteine, scans, modifications, TMT
  17. [17] § Methods › Functional genomics data analysis › Long-read RNA-seq data processing ↔ bin/plot_lrs_comparison.py, lines 1–36 · score 0.66 · intron chains, Iso Seq, novel transcripts, Bambu, modeling, filtering
  18. [18] § Results › Widespread isoform switching reveals dynamic regulation of splicing during neuronal differentiation ↔ scripts/figures/figure_4/IsoformSwitchAnalyzeR.R, lines 114–152 · score 0.64 · DESeq2, Isoform switching, gene expression, novel isoform, DTE, DGE
  19. [19] § Methods › Analysis of differential gene and transcript expression › Quasi-binomial approach ↔ scripts/APA_AS_coordination_beta_binomial.R, lines 281–362 · score 0.63 · confidence intervals, emmeans, marginal, ratio, Interaction, Global
  20. [20] § Methods › Analysis of differential gene and transcript expression › Identification and characterization of alternative transcript processing event coordination ↔ bin/plot_pita_coupling.py, lines 42–94 · score 0.62 · soloT, dualT, KDE, Spearman, density, coupling
  21. [21] § Methods › Functional genomics data analysis › Long-read RNA-seq data processing ↔ scripts/submit_sqanti3_qc.sh, the whole file · a weak match · score 0.61 · CAGE peaks, polyA, GENCODE V47, SQANTI3, v3, collapsed
  22. [22] § Methods › Analysis of differential gene and transcript expression › Identification and characterization of alternative transcript processing event coordination ↔ scripts/figures/figure_5/event_TSS_categorization.R, lines 87–135 · score 0.61 · NNC categories, ORFanage, transcription start, FSM, ISM, predicted
  23. [23] § Results › Discordant mRNA and protein expression dynamics across neuronal differentiation ↔ scripts_for_Nuo/making_figures/Figures.R, lines 309–392 · score 0.61 · MYO1E, protein expression, mRNA, DPP4, THBS1, genes
  24. [24] § Methods › Mutational constraint and ASD variant burden analysis › ASD De Novo mutation burden analysis ↔ scripts/figures/figure_6/combined_odds_plot.R, the whole file · a weak match · score 0.61 · de novo variant, splice site, burden, unaffected, sibling, ASD
  25. [25] § Methods › Analysis of differential gene and transcript expression › Analysis of alternative polyadenylation (APA) ↔ scripts_for_Nuo/making_figures/Figures.R, lines 2235–2323 · score 0.60 · log2 fold change, Pearson, DESeq2, PPAU, QAPA, gene
  26. [26] § Results › Widespread isoform switching reveals dynamic regulation of splicing during neuronal differentiation ↔ scripts_for_Nuo/making_figures/Figures.R, lines 1541–1606 · score 0.59 · microexon skipping, intron retention, Isoform switching, CI, NMD, IDR
  27. [27] § Methods › Mutational constraint and ASD variant burden analysis › ASD De Novo mutation burden analysis ↔ scripts/variant/trost_2022.R, lines 1–66 · score 0.59 · de novo variant, novel splice site
  28. [28] § Results › Novel exons and splice sites are mutationally constrained and contribute to ASD risk ↔ scripts/figures/figure_6/combined_odds_plot.R, the whole file · a weak match · score 0.59 · Odds Ratio, splice site, unaffected, missense, nonsense, siblings
  29. [29] § Results › Alternative transcript processing events are highly coordinated during neuronal differentiation ↔ bin/plot_pita_coupling.py, lines 42–94 · score 0.58 · PITA coupling, dualT, Spearman, tissues, axis, exons
  30. [30] § Methods › Analysis of differential gene and transcript expression › Analysis of alternative polyadenylation (APA) ↔ scripts/figures/figure_5/APA.R, lines 526–564 · score 0.58 · distal polyA site, sequence clusters, APA, UTR, genes
  31. [31] § Methods › Analysis of differential gene and transcript expression › Analysis of alternative polyadenylation (APA) ↔ scripts/figures/figure_5/QAPA.R, lines 135–181 · score 0.57 · median PAU, qapa, PPAU, proximal, shortening, lengthening
  32. [32] § Results › Experimental evidence confirms the translation of novel isoforms ↔ scripts/figures/figure_2/peotein_classification.R, the whole file · a weak match · score 0.57 · pFSM, pNIC, pNNC, pb, classification, Figure 2
  33. [33] § Methods › Analysis of differential gene and transcript expression › Gene set and functional enrichment analysis ↔ scripts_for_Nuo/making_figures/Figures.R, lines 3099–3161 · score 0.56 · GO term, switch consequences, MF, CC, BP, enrichment
  34. [34] § Methods › Analysis of differential gene and transcript expression › Quasi-binomial approach ↔ scripts/figures/figure_5/quasi_binomial_TSS.R, lines 202–322 · score 0.56 · emmeans, ANOVA, marginal, probability, Interaction, TSS
  35. [35] § Results › Widespread isoform switching reveals dynamic regulation of splicing during neuronal differentiation ↔ scripts_for_Nuo/making_figures/Figures.R, lines 1541–1606 · score 0.56 · intron retention, exon skipping, isoform switch, downstream, UTR, events
  36. [36] § Results › Alternative transcript processing events are highly coordinated during neuronal differentiation ↔ scripts/APA_AS_coordination_beta_binomial.R, lines 1–53 · score 0.56 · Percent Spliced, PolyA, alternatively spliced, AGO1, APA, PSI
  37. [37] § Methods › Functional genomics data analysis › Long-read RNA-seq data processing ↔ code/run_isoQuant.bash, the whole file · a weak match · score 0.56 · merged BAM, CCS, HiFi, isoseq, PacBio, ID
  38. [38] § Results › Deep long-read RNA-seq discovers over 100,000 novel mRNA isoforms in neuronal development ↔ scripts/figures/supplementary/ISM.R, the whole file · a weak match · score 0.55 · ISM transcripts, splice match, GENCODE V47, internal, priming, incomplete
  39. [39] § Methods › Analysis of differential gene and transcript expression › Analysis of alternative polyadenylation (APA) ↔ scripts/figures/figure_5/APA.R, lines 440–483 · score 0.55 · median PAU, PPAU, proximal, shortening, lengthening, CPM
  40. [40] § Methods › Analysis of differential gene and transcript expression › Quasi-binomial approach ↔ scripts/figures/figure_5/quasi_binomial_TSS.R, lines 836–893 · score 0.55 · abundant transcript, coordinated exon, TSS, UTR, Quasi, ORF

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

R · 3,306 lines · 136 KB · MIT · 6 matches

  1. ### MAKING FIGURES ###
  2. library(ggplot2)
  3. library(ggalluvial)
  4. library(dplyr)
  5. library(tidyr)
  6. library(data.table)
  7. library(stringr)
  8. library(readxl)
  9. library(ggpubr)
  10. library(cowplot)
  11. library(ggrepel)
  12. library(arrow)
  13. library(gprofiler2)
  14. setwd("")
  15. # FIGURE 3A ---------------------------------------------------------------
  16. sample_data <- data.frame(timepoint=c("t00", "t04", "t30",
  17. "t00", "t04", "t30",
  18. "t00", "t04", "t30",
  19. "t00", "t04", "t30",
  20. "t00", "t04", "t30",
  21. "t00", "t04", "t30",
  22. "t00", "t04", "t30",
  23. "t00", "t04", "t30",
  24. "t00", "t04", "t30"),
  25. expr=c(2.5, 2.5, 2.5,
  26. 2.5, 2.5, 0.5,
  27. 2.5, 2.5, 4.5,
  28. 4.5, 2.5, 2.5,
  29. 4.5, 2.5, 0.5,
  30. 4, 2, 4,
  31. 0.5, 2.5, 2.5,
  32. 1, 3, 1,
  33. 0.5, 2.5, 4.5),
  34. cluster = c("--", "--", "--",
  35. "-D", "-D", "-D",
  36. "-U", "-U", "-U",
  37. "D-", "D-", "D-",
  38. "DD", "DD", "DD",
  39. "DU", "DU", "DU",
  40. "U-", "U-", "U-",
  41. "UD", "UD", "UD",
  42. "UU", "UU", "UU"))
  43. sample_data$timepoint <- as.factor(sample_data$timepoint)
  44. sample_data$cluster <- as.factor(sample_data$cluster)
  45. safe_colorblind_palette <- c("#88CCEE", "#CC6677", "#DDCC77", "#117733", "#332288", "#AA4499",
  46. "#44AA99", "#999933", "#882255", "#661100", "#6699CC", "#888888")
  47. Fig_3A <- ggplot(data=sample_data, aes(x=timepoint, y=expr, group = 1)) +
  48. geom_line(aes(colour = cluster), linewidth = 1.5) +
  49. geom_point(aes(colour = cluster), size = 2.75) +
  50. scale_y_continuous(limits = c(0, 5), breaks = seq(0, 5, by = 2.5)) +
  51. theme_classic(base_size = 8) +
  52. theme(axis.text.y = element_blank(),
  53. axis.text.x = element_text(size = 8),
  54. axis.line = element_line(linewidth = 1),
  55. axis.ticks = element_line(linewidth = 1),
  56. legend.position = "none",
  57. strip.background = element_blank(),
  58. strip.text = element_text(face="bold", size=8)) +
  59. scale_colour_manual(values = safe_colorblind_palette[1:9]) +
  60. facet_wrap(sample_data$cluster, 3, 3, axes = "all") +
  61. labs(x = "Time", y = "RNA or Protein\nExpression")
  62. Fig_3A
  63. # RIVER PLOT --------------------------------------------------------------
  64. # GENES VS PROTEINS
  65. #Compare genes and proteins. Riverplots each cluster vs each cluster.
  66. safe_colorblind_palette <- c("#88CCEE", "#CC6677", "#DDCC77", "#117733", "#332288", "#AA4499",
  67. "#44AA99", "#999933", "#882255", "#661100", "#6699CC", "#888888")
  68. gene_clusters <- read.csv("./code/expression/output/gene_clusters_v2.csv")
  69. protein_clusters <- read.csv("./code/expression/output/protein_clusters_v3.csv")
  70. genesum_prot_clusters <- gene_clusters[,c(1,11)]
  71. colnames(genesum_prot_clusters) <- c("gene_name", "mRNA")
  72. genesum_prot_clusters <- merge(genesum_prot_clusters, protein_clusters[, c("GeneSymbol", "cluster")],
  73. by.x = "gene_name", by.y = "GeneSymbol", all.x = TRUE)
  74. genesum_prot_clusters <- na.omit(genesum_prot_clusters) #8493 remaining out of 8878
  75. colnames(genesum_prot_clusters)[3] <- "Protein"
  76. genesum_prot_long <- genesum_prot_clusters %>% pivot_longer(cols = c(mRNA, Protein),
  77. names_to = "gene_prot",
  78. values_to = "cluster")
  79. genesum_prot_long$cluster <- as.factor(genesum_prot_long$cluster)
  80. genesum_prot_long$rep <- rep(1:nrow(genesum_prot_clusters), each=2)
  81. label_fix <- data.frame(
  82. gene_prot = c("Protein", "Protein"),
  83. y = c(1131.5, 1012.5),
  84. label = c("DD", "DU"),
  85. x = c(1.95, 2.05))
  86. genesum_prot_long$label <- as.character(genesum_prot_long$cluster)
  87. genesum_prot_long$label[genesum_prot_long$cluster %in% c("DD", "DU") &
  88. genesum_prot_long$gene_prot == "Protein"] <- ""
  89. genesum_river <- ggplot(genesum_prot_long,
  90. aes(x = gene_prot, stratum = cluster, alluvium = rep,
  91. fill = cluster, label = label)) +
  92. geom_alluvium(aes(fill = cluster),
  93. curve_type = "sigmoid") +
  94. geom_stratum() +
  95. geom_text(stat = "stratum",
  96. aes(label = label),
  97. fontface = "bold",
  98. size = 3.75) +
  99. scale_fill_manual(values = safe_colorblind_palette[1:9]) +
  100. scale_y_continuous(expand = c(0, 0), limits = c(0, 8600)) +
  101. scale_x_discrete(expand = c(0, 0)) + #move y axis closer
  102. theme_void(base_size = 8) +
  103. theme(legend.position = "none",
  104. axis.title.x = element_blank(),
  105. axis.text.y = element_text(margin = margin(r = 5)),
  106. axis.text = element_text(size = 8),
  107. axis.ticks.y = element_line(size = 1),
  108. axis.ticks.length.y = unit(3, "pt"),
  109. axis.line.y = element_line(size = 0.75, colour = "black"),
  110. plot.margin = margin(
  111. t = 6,
  112. r = 6,
  113. b = 6,
  114. l = 6,
  115. unit = "pt" ))
  116. genesum_river_updated <- genesum_river +
  117. geom_text(data = label_fix,
  118. aes(x = x, y = y, label = label),
  119. inherit.aes = FALSE,
  120. fontface = "bold", size = 3.75)
  121. genesum_river_updated
  122. #
  123. table(genesum_prot_clusters$mRNA) #59% changing
  124. table(genesum_prot_clusters$Protein) #42% changing
  125. # EXAMPLE GENES -----------------------------------------------------------
  126. ###Assigning concordant (0) and discordant 1 or 2
  127. genesum_prot_clusters$mRNA <- as.character(genesum_prot_clusters$mRNA)
  128. genesum_prot_clusters$Protein <- as.character(genesum_prot_clusters$Protein)
  129. genesum_prot_clusters[,c("Genes_1", "Genes_2")] <- str_split_fixed(genesum_prot_clusters$mRNA, "", 2)
  130. genesum_prot_clusters[,c("Proteins_1", "Proteins_2")] <- str_split_fixed(genesum_prot_clusters$Protein, "", 2)
  131. genesum_prot_clusters$match1 <- ifelse((genesum_prot_clusters$Genes_1 == genesum_prot_clusters$Proteins_1), 0, 1)
  132. genesum_prot_clusters$match2 <- ifelse((genesum_prot_clusters$Genes_2 == genesum_prot_clusters$Proteins_2), 0, 1)
  133. genesum_prot_clusters$Level <- genesum_prot_clusters$match1 + genesum_prot_clusters$match2
  134. sum(genesum_prot_clusters$Level == 0)/nrow(genesum_prot_clusters) #45.5
  135. sum(genesum_prot_clusters$Level == 1)/nrow(genesum_prot_clusters) #42.5
  136. sum(genesum_prot_clusters$Level == 2)/nrow(genesum_prot_clusters) #12.0
  137. #Intersect the level2 with SFARI genes
  138. SFARI <- read.csv("./data/SFARI-Gene_genes_04-03-2025release_04-15-2025export.csv")
  139. level_SFARI <- genesum_prot_clusters[genesum_prot_clusters$gene_name %in% SFARI$gene.symbol, ]
  140. level_SFARI <- level_SFARI %>% filter((mRNA != "--" | Protein != "--"))
  141. #Make example plots for gene to protein fig.
  142. #Prepare gene data.
  143. gene_cpm <- read.csv("./code/expression/output/gene_CPM.csv")
  144. gene_SFARI <- gene_cpm[gene_cpm$gene_name %in% level_SFARI$gene_name,]
  145. gene_SFARI <- merge(gene_SFARI, gene_clusters[, c("gene_name", "cluster")],
  146. by.x = "gene_name", by.y = "gene_name", all.x = TRUE)
  147. #Pivot longer.
  148. gene_summ <- gene_SFARI %>% pivot_longer(
  149. cols = starts_with("sum_"), # Select columns that start with "sum_"
  150. names_to = c("Type", "Group"), # Create two new columns: "Type" (iPSC, NPC, CN) and "Group"
  151. names_sep = "_", # Split the names at "_"
  152. values_to = "Value")
  153. #Log2 transform the data, then calculate mean and 95% CI, and SD
  154. gene_long <- gene_summ %>%
  155. mutate(Value_log2 = log2(Value + 1))
  156. gene_long$Group <- factor(gene_long$Group, levels = c("iPSC", "NPC", "CN"),
  157. labels = c("t00", "t04", "t30"))
  158. # Calculate mean and 95% CI, and SD
  159. gene_summary <- gene_long %>%
  160. group_by(gene_name, Group) %>%
  161. summarise(
  162. Mean = mean(Value_log2),
  163. SE = sd(Value_log2) / sqrt(n()),
  164. CI_Lower = Mean - qt(0.975, df = n() - 1) * SE,
  165. CI_Upper = Mean + qt(0.975, df = n() - 1) * SE,
  166. sd = sd(Value_log2, na.rm = TRUE) )
  167. gene_summary <- merge(gene_summary, gene_clusters[, c("gene_name", "cluster")],
  168. by.x = "gene_name", by.y = "gene_name", all.x = F)
  169. ###Prepare protein data
  170. prot_quant <- read.csv("./code/expression/output/MSstatsTMT_abundance.csv")
  171. final_filtered_diff_prot <- read.csv("./code/expression/output/MSstatsTMT_diff_prot_expr_filtered.csv")
  172. #Calculate median across fractions:
  173. prot_quant_median <- prot_quant %>% group_by(Protein, Channel) %>%
  174. summarise(Median_Abundance = median(Abundance)) %>%
  175. left_join(prot_quant %>% dplyr::select(Channel, Condition) %>% distinct(Channel, Condition) , by = "Channel")
  176. summary_prot_abund <- prot_quant_median %>%
  177. group_by(Protein, Condition) %>%
  178. summarise(
  179. mean = mean(Median_Abundance, na.rm = TRUE),
  180. sd = sd(Median_Abundance, na.rm = TRUE),
  181. n = n()
  182. )
  183. summary_prot_abund <- summary_prot_abund %>%
  184. left_join(final_filtered_diff_prot %>% dplyr::select(Protein, GeneSymbol) %>% distinct(Protein, GeneSymbol), by = "Protein")
  185. summary_prot_abund <- summary_prot_abund %>% left_join(genesum_prot_clusters %>% dplyr::select(gene_name, Protein), by = c("GeneSymbol" = "gene_name"))
  186. summary_prot_abund$Condition <- factor(summary_prot_abund$Condition, levels = c("t00", "t4", "t30"),
  187. labels = c("t00", "t04", "t30"))
  188. #Chosen examples
  189. gene_ex <- gene_summary[gene_summary$gene_name %in% level_SFARI$gene_name,]
  190. prot_ex <- summary_prot_abund[summary_prot_abund$GeneSymbol %in% level_SFARI$gene_name,]
  191. #Make 6 indiv plots per gene b/c I need gene name on the left, and specific scales
  192. THBS1_gene <- gene_ex %>% filter(gene_name == "THBS1") %>% ggplot(aes(x = Group, y = Mean, group = gene_name, color = cluster)) +
  193. geom_line(linewidth = 1.5) +
  194. geom_point(size = 2.75) +
  195. geom_errorbar(aes(ymin = Mean - sd, ymax = Mean + sd), width = 0.2, linewidth = 1) +
  196. scale_y_continuous(limits = c(0, 4.2)) +
  197. theme_classic(base_size = 8) +
  198. labs(title = "mRNA", subtitle = "log2(CPM + 1)", y = "THBS1") +
  199. scale_color_manual(values=safe_colorblind_palette[4],
  200. breaks = c("D-")) +
  201. theme(axis.line = element_line(linewidth = 1),
  202. axis.ticks = element_line(linewidth = 1, colour = "black"),
  203. plot.title = element_text(hjust = 0.5, size = 8, face = "bold"),
  204. plot.subtitle = element_text(hjust = 0.5, size = 6.4),
  205. legend.position = "none",
  206. axis.text = element_text(size = 8),
  207. axis.title.x = element_blank(),
  208. axis.title.y = element_text(face = "bold")) +
  209. geom_text(aes(x=Inf,y=Inf,
  210. hjust=c(1.5),
  211. vjust=c(1.5),
  212. label="D-",
  213. fontface = "bold"),
  214. size = 4)
  215. THBS1_gene
  216. MYO1E_gene <- gene_ex %>% filter(gene_name == "MYO1E") %>% ggplot(aes(x = Group, y = Mean, group = gene_name, color = cluster)) +
  217. geom_line(linewidth = 1.5) +
  218. geom_point(size = 2.75) +
  219. geom_errorbar(aes(ymin = Mean - sd, ymax = Mean + sd), width = 0.2, linewidth = 1) +
  220. scale_y_continuous(limits = c(1, 8)) +
  221. theme_classic(base_size = 8) +
  222. labs(y = "MYO1E") +
  223. scale_color_manual(values=safe_colorblind_palette[4],
  224. breaks = c("D-")) +
  225. theme(axis.line = element_line(linewidth = 1),
  226. axis.ticks = element_line(linewidth = 1, colour = "black"),
  227. legend.position = "none",
  228. axis.text = element_text(size = 8),
  229. axis.title.x = element_blank(),
  230. axis.title.y = element_text(face = "bold")) +
  231. geom_text(aes(x=Inf,y=Inf,hjust=c(1.5),
  232. vjust=c(1.5),label="D-", fontface = "bold"),
  233. size = 4)
  234. MYO1E_gene
  235. DPP4_gene <- gene_ex %>% filter(gene_name == "DPP4") %>% ggplot(aes(x = Group, y = Mean, group = gene_name, color = cluster)) +
  236. geom_line(linewidth = 1.5) +
  237. geom_point(size = 2.75) +
  238. geom_errorbar(aes(ymin = Mean - sd, ymax = Mean + sd), width = 0.2, linewidth = 1) +
  239. scale_y_continuous(limits = c(-0.1, 4)) +
  240. theme_classic(base_size = 8) +
  241. labs(y = "DPP4") +
  242. scale_color_manual(values=safe_colorblind_palette[4],
  243. breaks = c("D-")) +
  244. theme(axis.line = element_line(linewidth = 1),
  245. axis.ticks = element_line(linewidth = 1, colour = "black"),
  246. legend.position = "none",
  247. axis.text = element_text(size = 8),
  248. axis.title.x = element_blank(),
  249. axis.title.y = element_text(face = "bold")) +
  250. geom_text(aes(x=Inf,y=Inf,hjust=c(1.5),
  251. vjust=c(1.5),label="D-", fontface = "bold"),
  252. size = 4)
  253. DPP4_gene
  254. #Proteins
  255. THBS1_prot <- prot_ex %>% filter(GeneSymbol == "THBS1") %>% ggplot(aes(x = Condition, y = mean, group = Protein.y, color = Protein.y)) +
  256. geom_line(linewidth = 1.5) +
  257. geom_point(size = 2.75) +
  258. geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.2, linewidth = 1) +
  259. scale_y_continuous(limits = c(3.8, 7.5)) +
  260. theme_classic(base_size = 8) +
  261. labs(title = "Protein", subtitle = "log2(Abundance)") +
  262. scale_color_manual(values=safe_colorblind_palette[c(4)],
  263. breaks = c("D-")) +
  264. theme(axis.line = element_line(linewidth = 1),
  265. axis.ticks = element_line(linewidth = 1, colour = "black"),
  266. plot.title = element_text(hjust = 0.5, size = 8, face = "bold"),
  267. plot.subtitle = element_text(hjust = 0.5, size = 6.4),
  268. legend.position = "none",
  269. axis.text = element_text(size = 8),
  270. axis.title = element_blank()) +
  271. geom_text(aes(x=Inf,y=Inf,hjust=c(1.5),
  272. vjust=c(1.5),label="D-", fontface = "bold"),
  273. size = 4)
  274. THBS1_prot
  275. MYO1E_prot <- prot_ex %>% filter(GeneSymbol == "MYO1E") %>% ggplot(aes(x = Condition, y = mean, group = Protein.y, color = Protein.y)) +
  276. geom_line(linewidth = 1.5) +
  277. geom_point(size = 2.75) +
  278. geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.2, linewidth = 1) +
  279. scale_y_continuous(limits = c(3.8, 7.5)) +
  280. theme_classic(base_size = 8) +
  281. scale_color_manual(values=safe_colorblind_palette[5],
  282. breaks = c("DD")) +
  283. theme(axis.line = element_line(linewidth = 1),
  284. axis.ticks = element_line(linewidth = 1, colour = "black"),
  285. legend.position = "none",
  286. axis.text = element_text(size = 8),
  287. axis.title = element_blank()) +
  288. geom_text(aes(x=Inf,y=Inf,hjust=c(1.5),
  289. vjust=c(1.5),label="DD", fontface = "bold"),
  290. size = 4)
  291. MYO1E_prot
  292. DPP4_prot <- prot_ex %>% filter(GeneSymbol == "DPP4") %>% ggplot(aes(x = Condition, y = mean, group = Protein.y, color = Protein.y)) +
  293. geom_line(linewidth = 1.5) +
  294. geom_point(size = 2.75) +
  295. geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.2, linewidth = 1) +
  296. scale_y_continuous(limits = c(3.8, 7.5)) +
  297. theme_classic(base_size = 8) +
  298. scale_color_manual(values=safe_colorblind_palette[c(4,1,8)],
  299. breaks = c("D-", "--", "UD")) +
  300. theme(axis.line = element_line(linewidth = 1),
  301. axis.ticks = element_line(linewidth = 1, colour = "black"),
  302. legend.position = "none",
  303. axis.text = element_text(size = 8),
  304. axis.title = element_blank()) +
  305. geom_text(aes(x=Inf,y=Inf,hjust=c(1.5),
  306. vjust=c(1.5),label="UD", fontface = "bold"),
  307. size = 4)
  308. DPP4_prot
  309. combined_plot <- ggarrange(THBS1_gene, THBS1_prot,
  310. MYO1E_gene, MYO1E_prot,
  311. DPP4_gene, DPP4_prot ,
  312. ncol = 2,
  313. nrow = 3,
  314. heights = c(1.32, 1, 1))
  315. combined_plot
  316. # 9 CLUSTER ASD RISK GENE ENRICHMENT------------------------------------------
  317. ####GO term enrichment for 9 protein clusters:
  318. #bg proteins is all genes with mRNA and protein expression
  319. bg.prot <- genesum_prot_clusters %>% pull(gene_name) %>% unique()
  320. #use 0 to replace -
  321. gene_lists <- list(genes_00 = genesum_prot_clusters %>% filter(Protein == "--") %>% pull(gene_name) %>% unique(),
  322. genes_0D = genesum_prot_clusters %>% filter(Protein == "-D") %>% pull(gene_name) %>% unique(),
  323. genes_U0 = genesum_prot_clusters %>% filter(Protein == "U-") %>% pull(gene_name) %>% unique(),
  324. genes_0U = genesum_prot_clusters %>% filter(Protein == "-U") %>% pull(gene_name) %>% unique(),
  325. genes_D0 = genesum_prot_clusters %>% filter(Protein == "D-") %>% pull(gene_name) %>% unique(),
  326. genes_UU = genesum_prot_clusters %>% filter(Protein == "UU") %>% pull(gene_name) %>% unique(),
  327. genes_UD = genesum_prot_clusters %>% filter(Protein == "UD") %>% pull(gene_name) %>% unique(),
  328. genes_DU = genesum_prot_clusters %>% filter(Protein == "DU") %>% pull(gene_name) %>% unique(),
  329. genes_DD = genesum_prot_clusters %>% filter(Protein == "DD") %>% pull(gene_name) %>% unique())
  330. ###Run GO term search:
  331. run_GO_enrichment <- function(gene_list, bg, searches) {
  332. go_result <- gost(gene_list,
  333. organism = "hsapiens",
  334. significant = T,
  335. exclude_iea = F,
  336. user_threshold = 0.05,
  337. correction_method = "fdr",
  338. custom_bg = bg,
  339. sources = searches)
  340. return(go_result)
  341. }
  342. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  343. # Initialize an empty list to store results
  344. enrichment_results <- list()
  345. i = 1
  346. # Loop through each gene list and perform GO enrichment
  347. for (i in seq_along(gene_lists)) {
  348. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  349. bg = bg.prot,
  350. searches = searches)
  351. }
  352. enrichment_results$genes_00$result$query <- "--"
  353. enrichment_results$genes_0D$result$query <- "-D"
  354. enrichment_results$genes_U0$result$query <- "U-"
  355. enrichment_results$genes_0U$result$query <- "-U"
  356. enrichment_results$genes_D0$result$query <- "D-"
  357. enrichment_results$genes_UU$result$query <- "UU"
  358. enrichment_results$genes_UD$result$query <- "UD"
  359. enrichment_results$genes_DU$result$query <- "DU"
  360. enrichment_results$genes_DD$result$query <- "DD"
  361. GO_list <- rbind(enrichment_results$genes_00$result,
  362. enrichment_results$genes_0D$result,
  363. enrichment_results$genes_U0$result,
  364. enrichment_results$genes_0U$result,
  365. enrichment_results$genes_D0$result,
  366. enrichment_results$genes_UU$result,
  367. enrichment_results$genes_UD$result,
  368. enrichment_results$genes_DU$result,
  369. enrichment_results$genes_DD$result)
  370. GO_list$query <- as.character(GO_list$query)
  371. write.csv(GO_list[,-14], "./tables/protein_clusters_GO_terms.csv",
  372. row.names = F)
  373. #########SFARI Gene Enrichment
  374. #SFARI genes subset to only proteins expressed:
  375. SFARI_prot <- SFARI %>% filter(gene.symbol %in% genesum_prot_clusters$gene_name) #805
  376. # Function to compute Fisher's exact test for pairwise comparisons
  377. compute_fisher_enrich <- function(setA, setB, bg) {
  378. # Calculate overlap and unique genes
  379. overlap <- length(intersect(setA, setB))
  380. inAnotB <- length(setdiff(setA, setB))
  381. inBnotA <- length(setdiff(setB, setA))
  382. inNeither <- length(bg) - length(union(setA, setB))
  383. # Create the contingency table
  384. contingency_table <- matrix(c(overlap, inAnotB, inBnotA, inNeither), nrow = 2)
  385. # Perform Fisher's Exact Test
  386. fisher_result <- fisher.test(contingency_table, alternative = "greater")
  387. return(c(overlap = overlap, inAnotB = inAnotB, inBnotA = inBnotA, inNeither = inNeither, p_value = fisher_result$p.value))
  388. }
  389. #Testing for enrichment in the each cluster:
  390. results_list <- list()
  391. i = 1
  392. for (i in 1:9) {
  393. setA <- SFARI_prot$gene.symbol
  394. setB <- gene_lists[[i]]
  395. result <- compute_fisher_enrich(setA, setB, bg.prot)
  396. # Store the results in the list, and create the pair name
  397. pair_name <- paste0("SFARI vs ", names(gene_lists[i]))
  398. results_list[[pair_name]] <- result
  399. }
  400. results_df_SFARI_prot <- do.call(rbind, results_list)
  401. results_df_SFARI_prot <- data.frame(pair = names(results_list), results_df_SFARI_prot)
  402. results_df_SFARI_prot$p_adjusted <- p.adjust(results_df_SFARI_prot$p_value, method = "bonferroni")
  403. results_df_SFARI_prot$gene <- "Protein"
  404. SFARI_gene_enrich <- results_df_SFARI_prot
  405. SFARI_gene_enrich$cluster <- gsub("0", "-", substr(SFARI_gene_enrich$pair, nchar(SFARI_gene_enrich$pair)-1, nchar(SFARI_gene_enrich$pair)))
  406. SFARI_gene_enrich$cluser <- as.factor(SFARI_gene_enrich$cluster)
  407. Fig3d_title <- "SFARI Gene Enrichment"
  408. SFARI_gene_enrich$gene <- as.factor(SFARI_gene_enrich$gene)
  409. Fig_3d <- ggplot(SFARI_gene_enrich, aes(x = cluster, y = -log10(p_adjusted)) ) +
  410. geom_col(aes(x = cluster, y = -log10(p_adjusted), fill = cluster),
  411. colour = "black",
  412. position = position_dodge()) +
  413. labs(y = expression(paste(-log[10], "(adj. ", italic("P"), ")")), title = Fig3d_title) +
  414. coord_cartesian(ylim = c(0, 15.5)) +
  415. scale_y_continuous(expand = c(0, 0)) +
  416. geom_hline(yintercept=-log10(0.05), linetype='dashed', col = "black", linewidth = 0.7) +
  417. theme_classic(base_size = 8) +
  418. scale_fill_manual(values=safe_colorblind_palette) +
  419. theme(axis.title.x = element_blank(),
  420. axis.title.y = element_text(size = 8),
  421. panel.grid.major.x = element_blank(),
  422. plot.title = element_text(hjust = 0.5, size = 8, face = "bold"),
  423. legend.position = "none" )
  424. Fig_3d
  425. #Export figure
  426. Figure_3 <- ggdraw() +
  427. draw_plot(Fig_3A, x = 0, y = 0.63, width = 0.5, height = 0.375) +
  428. draw_plot(genesum_river_updated, x = 0.5, y = 0, width = 0.5, height = 1) +
  429. draw_plot(combined_plot, x = 0, y = 0.19, width = 0.5, height = 0.44) +
  430. draw_plot(Fig_3d, x = 0.0, y = 0, width = 0.5, height = 0.191) +
  431. draw_plot_label(label = c("A", "B", "C", "D"),
  432. size = 14,
  433. x = c(0, 0.5, 0, 0),
  434. y = c(1, 1, 0.63, 0.1911))
  435. #Figure_3
  436. pdf(paste0("./figures/Figure_3.pdf"), height = 6.5, width = 6.5)
  437. print(Figure_3)
  438. dev.off()
  439. svg(paste0("./figures/Figure_3.svg"), height = 6.5, width = 6.5)
  440. print(Figure_3)
  441. dev.off()
  442. # FIGURE 4 --------------------------------------------------------------
  443. classification <- read_parquet("./data/final_classification.parquet") #182371
  444. ###IsoformSwitches
  445. aSwitchList_part2 <- readRDS("./code/IsoformSwitchAnalyzeR/output/isoformswitch_part2_v4.rds")
  446. aSwitchList_part2[["isoformFeatures"]]$gene_name <- aSwitchList_part2[["isoformFeatures"]]$gene_id
  447. # FIGURE 4A ---------------------------------------------------------------
  448. ###DTU PROPORTIONS (bars)
  449. DTU <- read.csv("./code/IsoformSwitchAnalyzeR/output/DTU_table.csv")
  450. DTU_filter <- DTU %>% filter(DTU_qval < 0.05 &
  451. (DTU_dIF < -0.05 | DTU_dIF > 0.05))
  452. DTU_filter <- DTU_filter[,-c(1:3)]
  453. DTU_filter$condition <- paste0(DTU_filter$condition_1, " vs ", DTU_filter$condition_2)
  454. DTU_filter <- merge(DTU_filter, classification[, c("isoform", "structural_category")],
  455. by.x = "isoform_id", by.y = "isoform", all.x = T)
  456. rep_str = c('full-splice_match'='FSM','incomplete-splice_match' = 'ISM', 'novel_in_catalog'='NIC','novel_not_in_catalog'='NNC')
  457. DTU_filter$structural_category <- str_replace_all(DTU_filter$structural_category, rep_str)
  458. #All conditions
  459. DTU_summ <- DTU_filter %>%
  460. group_by(condition, structural_category) %>%
  461. summarise(count = n()) %>%
  462. group_by(condition) %>%
  463. mutate(perc = (count/sum(count))*100) %>%
  464. ungroup()
  465. DTU_summ$percentage = paste0(round(DTU_summ$perc, 0), "%")
  466. ####DTE
  467. res_t30_vs_t00 <- read.csv("./code/expression/output/DESeq2_tr_t30_vs_t00.csv")
  468. res_t30_vs_t00$condition <- "t00 vs t30"
  469. res_t04_vs_t00 <- read.csv("./code/expression/output/DESeq2_tr_t04_vs_t00.csv")
  470. res_t04_vs_t00$condition <- "t00 vs t04"
  471. res_t30_vs_t04 <- read.csv("./code/expression/output/DESeq2_tr_t30_vs_t04.csv")
  472. res_t30_vs_t04$condition <- "t04 vs t30"
  473. DTE_prefilter <- rbind(res_t30_vs_t00, res_t04_vs_t00)
  474. DTE_prefilter <- rbind(DTE_prefilter, res_t30_vs_t04)
  475. DTE_prefilter <- merge(DTE_prefilter, classification[, c("isoform", "associated_gene", "structural_category")],
  476. by.x = "pb_id", by.y = "isoform", all.x = T)
  477. #Just take the transcripts that meet the DTU pre-filter:
  478. prefilter <- aSwitchList_part2$isoformRepIF$isoform_id
  479. DTE_prefilter <- DTE_prefilter %>% filter(pb_id %in% prefilter) #68,801
  480. DTE <- DTE_prefilter %>% filter(padj < 0.05 &
  481. (log2FoldChange < -1 | log2FoldChange > 1))
  482. DTE$structural_category <- str_replace_all(DTE$structural_category, rep_str)
  483. DTE_summ <- DTE %>%
  484. group_by(condition, structural_category) %>%
  485. summarise(count = n()) %>%
  486. group_by(condition) %>%
  487. mutate(perc = (count/sum(count))*100) %>%
  488. ungroup()
  489. DTE_summ$percentage = paste0(round(DTE_summ$perc, 0), "%")
  490. DTE_summ$type <- "DTE"
  491. DTU_summ$type <- "DTU"
  492. DTU_summ <- rbind(DTU_summ, DTE_summ)
  493. #FSM NIC NNC ISM
  494. colours <- c("#009E73", "#D55E00", "#E69F00", "#0072B2")
  495. DTU_summ$condition <- factor(DTU_summ$condition, levels = c("t00 vs t04", "t04 vs t30", "t00 vs t30"))
  496. bars_by_tr <- ggplot(DTU_summ, aes(x = condition, y = count/(1000), fill = structural_category)) +
  497. geom_bar(stat = "identity") +
  498. geom_text(aes(label = percentage), position = position_stack(vjust = 0.5), size = 1.9) +
  499. theme_classic(base_size = 8) +
  500. scale_fill_manual(values = colours[c(1,4,2,3)]) +
  501. theme(
  502. legend.title = element_blank(),
  503. legend.key.size = unit(0.35, 'cm'),
  504. axis.line = element_line(linewidth = 0.6),
  505. axis.ticks = element_line(linewidth = 0.6, colour = "black"),
  506. axis.title.x = element_blank(),
  507. axis.title.y = element_text(size = 8, colour = "black"),
  508. axis.text = element_text(size = 6.4, colour = "black"),
  509. strip.background = element_blank(),
  510. strip.text = element_text(size = 8, face = "bold"),
  511. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1)) +
  512. labs(y = expression(paste("Isoforms (x ", 10^{3}, ")"))) +
  513. guides(y = guide_axis(minor.ticks = TRUE)) +
  514. facet_wrap(~factor(type), scales = "free")
  515. bars_by_tr
  516. #
  517. # FUNC. CONSEQ ENRICHMENT------------------------------------------------------
  518. #Need to run the function fully to extract genes, etc.
  519. switchAnalyzeRlist = aSwitchList_part2
  520. consequencesToAnalyze = 'all'
  521. alpha=0.05
  522. dIFcutoff = 0.05
  523. countGenes = TRUE
  524. analysisOppositeConsequence=FALSE
  525. plot=TRUE
  526. localTheme = theme_bw(base_size = 12)
  527. minEventsForPlotting = 10
  528. returnResult=TRUE
  529. returnSummary=TRUE
  530. ### Consequences to analyze
  531. acceptedTypes <- c(
  532. # Transcript
  533. 'tss',
  534. 'tts',
  535. 'last_exon',
  536. 'isoform_length',
  537. 'exon_number',
  538. 'intron_structure',
  539. 'intron_retention',
  540. 'isoform_class_code',
  541. # cpat
  542. 'coding_potential',
  543. # ORF
  544. 'ORF_genomic',
  545. 'ORF_length',
  546. '5_utr_length',
  547. '3_utr_length',
  548. # seq similarity
  549. 'isoform_seq_similarity',
  550. 'ORF_seq_similarity',
  551. '5_utr_seq_similarity',
  552. '3_utr_seq_similarity',
  553. # ORF
  554. 'NMD_status',
  555. # pfam
  556. 'domains_identified',
  557. 'genomic_domain_position',
  558. 'domain_length',
  559. 'domain_isotype',
  560. # SignalIP
  561. 'signal_peptide_identified',
  562. # IDR
  563. 'IDR_identified',
  564. 'IDR_length',
  565. 'IDR_type',
  566. # sub cell
  567. 'sub_cell_location',
  568. 'sub_cell_shift_to_cell_membrane',
  569. 'sub_cell_shift_to_cytoplasm',
  570. 'sub_cell_shift_to_nucleus',
  571. 'sub_cell_shift_to_Extracellular'
  572. # topology
  573. # 'isoform_topology'
  574. )
  575. consequencesAnalyzed <- unique(switchAnalyzeRlist$switchConsequence$featureCompared)
  576. if ('all' %in% consequencesToAnalyze) {
  577. consequencesToAnalyze <- consequencesAnalyzed
  578. }
  579. consequencesNotAnalyzed <- setdiff(consequencesToAnalyze, consequencesAnalyzed)
  580. if (length(consequencesNotAnalyzed)) {
  581. warning(
  582. paste(
  583. 'The following consequences appear not to have been analyzed and will therefor not be summarized:',
  584. paste(consequencesNotAnalyzed, collapse = ', '),
  585. sep = ' '
  586. )
  587. )
  588. }
  589. ### Extract non-location consequences
  590. if(TRUE) {
  591. localConseq <- switchAnalyzeRlist$switchConsequence[
  592. which( !is.na(
  593. switchAnalyzeRlist$switchConsequence$switchConsequence
  594. ))
  595. ,]
  596. localConseq <- localConseq[which(
  597. ! grepl('switch', localConseq$switchConsequence)
  598. ),]
  599. ### make list with levels
  600. levelList <- list(
  601. tss=c('Tss more upstream','Tss more downstream'),
  602. tts=c('Tts more downstream','Tts more upstream'),
  603. last_exon=c('Last exon more downstream','Last exon more upstream'),
  604. isoform_length=c('Length gain','Length loss'),
  605. isoform_seq_similarity=c('Length gain','Length loss'),
  606. exon_number=c('Exon gain','Exon loss'),
  607. intron_retention=c('Intron retention gain','Intron retention loss'),
  608. ORF_length=c('ORF is longer','ORF is shorter'),
  609. ORF=c('Complete ORF loss','Complete ORF gain'),
  610. x5_utr_length=c('5UTR is longer','5UTR is shorter'),
  611. x3_utr_length=c('3UTR is longer','3UTR is shorter'),
  612. NMD_status=c('NMD sensitive','NMD insensitive'),
  613. coding_potential=c('Transcript is coding','Transcript is Noncoding'),
  614. domains_identified=c('Domain gain','Domain loss'),
  615. domain_length=c('Domain length gain','Domain length loss'),
  616. domain_isotype=c('Domain non-reference isotype gain','Domain non-reference isotype loss'),
  617. IDR_identified = c('IDR gain','IDR loss'),
  618. IDR_length = c('IDR length gain', 'IDR length loss'),
  619. IDR_type = c('IDR w binding region gain', 'IDR w binding region loss'),
  620. signal_peptide_identified=c('Signal peptide gain','Signal peptide loss'),
  621. sub_cell_location = c('SubCell location gain','SubCell location loss'),
  622. sub_cell_shift_to_cell_membrane = c('SubCell location memb gain','SubCell location memb loss'),
  623. sub_cell_shift_to_cytoplasm = c('SubCell location cyto gain','SubCell location cyto loss'),
  624. sub_cell_shift_to_nucleus = c('SubCell location nucl gain','SubCell location nucl loss'),
  625. sub_cell_shift_to_Extracellular = c('SubCell location ext cell gain','SubCell location ext cell loss'),
  626. isoform_topology = c('Topology complexity gain','Topology complexity loss'),
  627. extracellular_region_count = c('Extracellular region gain', 'Extracellular region loss'),
  628. intracellular_region_count = c('Intracellular region gain', 'Intracellular region loss'),
  629. extracellular_region_length = c('Extracellular length gain','Extracellular length loss'),
  630. intracellular_region_length = c('Intracellular length gain','Intracellular length loss')
  631. )
  632. levelListDf <- plyr::ldply(levelList, function(x) data.frame(feature=x, stringsAsFactors = FALSE))
  633. ### Add consequence pairs
  634. localConseq$conseqPair <- levelListDf$.id[match(localConseq$switchConsequence, levelListDf$feature)]
  635. localConseq <- localConseq[which( !is.na(localConseq$conseqPair)),]
  636. ### Subset to consequences analyzed
  637. localConseq <- localConseq[which(
  638. localConseq$featureCompared %in% consequencesToAnalyze
  639. ),]
  640. }
  641. ### Subset to significant features
  642. if(TRUE) {
  643. ### Extract Sig iso
  644. isoResTest <-
  645. any(!is.na(
  646. switchAnalyzeRlist$isoformFeatures$isoform_switch_q_value
  647. ))
  648. if (isoResTest) {
  649. sigIso <- switchAnalyzeRlist$isoformFeatures[which(
  650. switchAnalyzeRlist$isoformFeatures$isoform_switch_q_value < alpha &
  651. abs(switchAnalyzeRlist$isoformFeatures$dIF) > dIFcutoff
  652. ),
  653. c('iso_ref', 'gene_ref')]
  654. } else {
  655. sigIso <- switchAnalyzeRlist$isoformFeatures[which(
  656. switchAnalyzeRlist$isoformFeatures$gene_switch_q_value < alpha &
  657. abs(switchAnalyzeRlist$isoformFeatures$dIF) > dIFcutoff
  658. ),
  659. c('iso_ref', 'gene_ref')]
  660. }
  661. if(isoResTest) {
  662. localConseq <- localConseq[which(
  663. localConseq$iso_ref_down %in% sigIso$iso_ref |
  664. localConseq$iso_ref_up %in% sigIso$iso_ref
  665. ),]
  666. } else {
  667. localConseq <- localConseq[which(
  668. localConseq$gene_ref %in% sigIso$gene_ref
  669. ),]
  670. }
  671. }
  672. ### Summarize gain vs loss for each consequence in each condition
  673. consequenceBalance <- plyr::ddply(
  674. .data = localConseq,
  675. .variables = c('condition_1','condition_2','conseqPair'),
  676. #.inform = TRUE,
  677. .fun = function(aDF) { # aDF <- localConseq[1:20,]
  678. ### Add levels
  679. if(analysisOppositeConsequence) {
  680. localLvl <- rev(sort(
  681. levelList[[ aDF$conseqPair[1] ]]
  682. ))
  683. } else {
  684. localLvl <- sort(
  685. levelList[[ aDF$conseqPair[1] ]]
  686. )
  687. }
  688. aDF$switchConsequence <- factor(
  689. aDF$switchConsequence,
  690. levels=localLvl
  691. )
  692. ### Summarize category
  693. if( countGenes ) {
  694. df2 <- aDF[
  695. which(!is.na(aDF$switchConsequence)),
  696. c('gene_id','switchConsequence')
  697. ]
  698. localNumber <- plyr::ddply(df2, .drop = FALSE, .variables = 'switchConsequence', function(x) {
  699. data.frame(
  700. Freq = length(unique(x$gene_id))
  701. )
  702. })
  703. colnames(localNumber)[1] <- 'Var1'
  704. } else {
  705. localNumber <- as.data.frame(table(aDF$switchConsequence))
  706. }
  707. if(nrow(localNumber) == 2) {
  708. localTest <- suppressWarnings(
  709. stats::binom.test(localNumber$Freq[1], sum(localNumber$Freq))
  710. )
  711. localRes <- data.frame(
  712. feature=stringr::str_c(
  713. localNumber$Var1[1],
  714. ' (paired with ',
  715. localNumber$Var1[2],
  716. ')'
  717. ),
  718. propOfRelevantEvents=localTest$estimate,
  719. stringsAsFactors = FALSE
  720. )
  721. localRes$propCiLo <- min(localTest$conf.int)
  722. localRes$propCiHi <- max(localTest$conf.int)
  723. localRes$propPval <- localTest$p.value
  724. } else {
  725. warning('Somthing strange happend - contact developer with reproducible example')
  726. }
  727. localRes$nUp <- localNumber$Freq[which( localNumber$Var1 == levels(localNumber$Var1)[1] )]
  728. localRes$nDown <- localNumber$Freq[which( localNumber$Var1 == levels(localNumber$Var1)[2] )]
  729. return(localRes)
  730. }
  731. )
  732. consequenceBalance$propQval <- p.adjust(consequenceBalance$propPval, method = 'fdr')
  733. consequenceBalance$Significant <- consequenceBalance$propQval < alpha
  734. consequenceBalance$Significant <- factor(
  735. consequenceBalance$Significant,
  736. levels=c(FALSE,TRUE)
  737. )
  738. #Prep for plotting
  739. consequenceBalance2 <- consequenceBalance[which(
  740. (consequenceBalance$nUp + consequenceBalance$nDown) >= minEventsForPlotting
  741. ),]
  742. if(nrow(consequenceBalance2) == 0) {
  743. stop('No features left for ploting after filtering with via "minEventsForPlotting" argument.')
  744. }
  745. consequenceBalance2$nTot <- consequenceBalance2$nDown + consequenceBalance2$nUp
  746. ### Add comparison
  747. consequenceBalance2$Comparison <- paste(
  748. consequenceBalance2$condition_1,
  749. 'vs',
  750. consequenceBalance2$condition_2,
  751. sep='\n'
  752. )
  753. ### Massage
  754. consequenceBalance2$feature2 <- gsub(' \\(', '\n(', consequenceBalance2$feature)
  755. consequenceBalance2$feature2 <- factor(
  756. consequenceBalance2$feature2,
  757. levels = rev(sort(unique(as.character(consequenceBalance2$feature2))))
  758. )
  759. # SPLICING PLOT -----------------------------------------------------------
  760. extractSwitchPairs <- function(
  761. switchAnalyzeRlist,
  762. alpha = 0.05,
  763. dIFcutoff = 0.05,
  764. onlySigIsoforms = FALSE
  765. ) {
  766. ### Extract and massage data
  767. if (TRUE) {
  768. localData <- switchAnalyzeRlist$isoformFeatures[
  769. which(
  770. switchAnalyzeRlist$isoformFeatures$gene_switch_q_value < alpha &
  771. abs(switchAnalyzeRlist$isoformFeatures$dIF) > dIFcutoff
  772. ),
  773. c(
  774. 'iso_ref',
  775. 'gene_ref',
  776. 'isoform_switch_q_value',
  777. 'gene_switch_q_value',
  778. 'dIF'
  779. )
  780. ]
  781. if (!nrow(localData)) {
  782. stop('No genes were considered switching with the used cutoff values')
  783. }
  784. ### add switch direction
  785. localData$switchDirection <- NA
  786. localData$switchDirection[which(sign(localData$dIF) == 1)] <- 'up'
  787. localData$switchDirection[which(sign(localData$dIF) == -1)] <- 'down'
  788. ### Annotate significant features
  789. isoResTest <-
  790. any(!is.na(
  791. switchAnalyzeRlist$isoformFeatures$isoform_switch_q_value
  792. ))
  793. if (isoResTest) {
  794. localData$isoSig <-
  795. localData$isoform_switch_q_value < alpha &
  796. abs(localData$dIF) > dIFcutoff
  797. } else {
  798. localData$isoSig <-
  799. localData$gene_switch_q_value < alpha &
  800. abs(localData$dIF) > dIFcutoff
  801. }
  802. if(onlySigIsoforms) {
  803. localData <- localData[which( localData$isoSig ),]
  804. }
  805. }
  806. ### Create data sub-sets of interest
  807. if(TRUE) {
  808. sigUpData <- localData[which(
  809. localData$isoSig & localData$switchDirection == 'up'
  810. ),c('iso_ref','gene_ref')]
  811. sigDnData <- localData[which(
  812. localData$isoSig & localData$switchDirection == 'down'
  813. ),c('iso_ref','gene_ref')]
  814. colnames(sigUpData)[1] <- c('iso_ref_up')
  815. colnames(sigDnData)[1] <- c('iso_ref_down')
  816. if( ! onlySigIsoforms ) {
  817. justUpData <- localData[which(
  818. localData$switchDirection == 'up'
  819. ),c('iso_ref','gene_ref')]
  820. justDnData <- localData[which(
  821. localData$switchDirection == 'down'
  822. ),c('iso_ref','gene_ref')]
  823. colnames(justUpData)[1] <- c('iso_ref_up')
  824. colnames(justDnData)[1] <- c('iso_ref_down')
  825. }
  826. }
  827. ### Join datasets to extract pairs
  828. if(TRUE) {
  829. if( onlySigIsoforms ) {
  830. pairwiseIsoComparison <- dplyr::inner_join(
  831. sigUpData,
  832. sigDnData,
  833. by= 'gene_ref',
  834. multiple = "all"
  835. )
  836. } else {
  837. ### Sig up and all down
  838. upPairs <- dplyr::inner_join(
  839. sigUpData,
  840. justDnData,
  841. by= 'gene_ref',
  842. multiple = "all"
  843. )
  844. ### Sig down and all up
  845. dnPairs <- dplyr::inner_join(
  846. justUpData,
  847. sigDnData,
  848. by= 'gene_ref',
  849. multiple = "all"
  850. )
  851. ### Combine
  852. pairwiseIsoComparison <- unique(
  853. rbind(
  854. upPairs,
  855. dnPairs
  856. )
  857. )
  858. pairwiseIsoComparison <- pairwiseIsoComparison[,c(
  859. 'gene_ref','iso_ref_up','iso_ref_down'
  860. )]
  861. ### Reorder
  862. pairwiseIsoComparison <- pairwiseIsoComparison[order(
  863. pairwiseIsoComparison$gene_ref,
  864. pairwiseIsoComparison$iso_ref_up,
  865. pairwiseIsoComparison$iso_ref_down
  866. ),]
  867. }
  868. }
  869. ### Add in additional data
  870. if(TRUE) {
  871. ### Add isoform names
  872. matchVectorUp <- match(
  873. pairwiseIsoComparison$iso_ref_up,
  874. switchAnalyzeRlist$isoformFeatures$iso_ref
  875. )
  876. matchVectorDn <- match(
  877. pairwiseIsoComparison$iso_ref_down,
  878. switchAnalyzeRlist$isoformFeatures$iso_ref
  879. )
  880. pairwiseIsoComparison$isoformUpregulated <-
  881. switchAnalyzeRlist$isoformFeatures$isoform_id[matchVectorUp]
  882. pairwiseIsoComparison$isoformDownregulated <-
  883. switchAnalyzeRlist$isoformFeatures$isoform_id[matchVectorDn]
  884. ### Gene infl
  885. pairwiseIsoComparison$gene_id <-
  886. switchAnalyzeRlist$isoformFeatures$gene_id[matchVectorUp]
  887. pairwiseIsoComparison$gene_name <-
  888. switchAnalyzeRlist$isoformFeatures$gene_name[matchVectorUp]
  889. ### Conditons
  890. pairwiseIsoComparison$condition_1 <-
  891. switchAnalyzeRlist$isoformFeatures$condition_1[matchVectorUp]
  892. pairwiseIsoComparison$condition_2 <-
  893. switchAnalyzeRlist$isoformFeatures$condition_2[matchVectorUp]
  894. }
  895. return( pairwiseIsoComparison )
  896. }
  897. #Use MIC IsoformSwitch object to extract the MICs
  898. aSwitchList_part2_MIC <- readRDS(file="./code/microexons/output/isoformswitch_MIC.rds")
  899. switchAnalyzeRlist = aSwitchList_part2_MIC
  900. splicingToAnalyze = 'all'
  901. alpha = 0.05
  902. dIFcutoff = 0.05
  903. onlySigIsoforms = T
  904. countGenes = T
  905. plot = TRUE
  906. localTheme = theme_bw(base_size = 14)
  907. minEventsForPlotting = 25 ##default = 10
  908. returnResult=TRUE
  909. returnSummary=TRUE
  910. ### Consequences to analyze
  911. acceptedTypes <- c("A3","A5","ATSS","ATTS","ES" ,"IR","MEE","MES", "MIC" )
  912. splicingAnalyzed <-
  913. intersect(
  914. acceptedTypes,
  915. colnames(switchAnalyzeRlist$AlternativeSplicingAnalysis)
  916. )
  917. if ('all' %in% splicingToAnalyze) {
  918. splicingToAnalyze <- splicingAnalyzed
  919. }
  920. splicingNotAnalyzed <-
  921. setdiff(splicingToAnalyze, splicingAnalyzed)
  922. if (length(splicingNotAnalyzed)) {
  923. warning(
  924. paste(
  925. 'The following consequences appear not to have been analyzed and will therefor not be summarized:',
  926. paste(splicingNotAnalyzed, collapse = ', '),
  927. sep = ' '
  928. )
  929. )
  930. }
  931. ### Get pairs
  932. if(TRUE) {
  933. pairwiseIsoComparison <- extractSwitchPairs(
  934. switchAnalyzeRlist,
  935. alpha = alpha,
  936. dIFcutoff = dIFcutoff,
  937. onlySigIsoforms = onlySigIsoforms
  938. )
  939. }
  940. ### Massage AS analysis
  941. if(TRUE) {
  942. localAS <- switchAnalyzeRlist$AlternativeSplicingAnalysis
  943. localAS <- localAS[which(
  944. localAS$isoform_id %in% pairwiseIsoComparison$isoformUpregulated |
  945. localAS$isoform_id %in% pairwiseIsoComparison$isoformDownregulated
  946. ),]
  947. ### Massage
  948. m1 <- reshape2::melt(localAS[,c(
  949. "isoform_id",
  950. "ES_genomic_start",
  951. "MEE_genomic_start",
  952. "MES_genomic_start",
  953. "IR_genomic_start",
  954. "A5_genomic_start",
  955. "A3_genomic_start",
  956. "ATSS_genomic_start",
  957. "ATTS_genomic_start",
  958. "MIC_genomic_start"
  959. )], id.vars = 'isoform_id')
  960. colnames(m1)[3] <- 'genomic_start'
  961. m1$AStype <- sapply(
  962. strsplit(as.character(m1$variable),'_'),
  963. function(x) x[1]
  964. )
  965. m2 <- reshape2::melt(localAS[,c(
  966. "isoform_id",
  967. "ES_genomic_end",
  968. "MEE_genomic_end",
  969. "MES_genomic_end",
  970. "IR_genomic_end",
  971. "A5_genomic_end",
  972. "A3_genomic_end",
  973. "ATSS_genomic_end",
  974. "ATTS_genomic_end",
  975. "MIC_genomic_end"
  976. )], id.vars = 'isoform_id')
  977. colnames(m2)[3] <- 'genomic_end'
  978. m2$AStype <- sapply(
  979. strsplit(as.character(m2$variable),'_'),
  980. function(x) x[1]
  981. )
  982. localAS <- dplyr::inner_join(
  983. m1[,c('isoform_id','AStype','genomic_start')],
  984. m2[,c('isoform_id','AStype','genomic_end')],
  985. by=c('isoform_id','AStype')
  986. )
  987. ### Add in NMD
  988. if('orfAnalysis' %in% names(switchAnalyzeRlist)) {
  989. localNMD <- data.frame(
  990. isoform_id=switchAnalyzeRlist$orfAnalysis$isoform_id,
  991. AStype='NMD',
  992. genomic_start=ifelse(switchAnalyzeRlist$orfAnalysis$PTC, '0,0', '0'),
  993. genomic_end=ifelse(switchAnalyzeRlist$orfAnalysis$PTC, '0,0', '0'),
  994. stringsAsFactors = FALSE
  995. )
  996. localAS <- rbind(localAS , localNMD)
  997. }
  998. }
  999. ### Add AS to pairs
  1000. if(TRUE) {
  1001. localConseq2 <- merge(
  1002. pairwiseIsoComparison,
  1003. localAS,
  1004. by.x='isoformUpregulated',
  1005. by.y='isoform_id'
  1006. )
  1007. localConseq3 <- merge(
  1008. localConseq2,
  1009. localAS,
  1010. by.x=c('isoformDownregulated','AStype'),
  1011. by.y=c('isoform_id','AStype'),
  1012. suffixes = c("_up","_down")
  1013. )
  1014. ### Replace NAs so they can be compared (na just mean same as pre-transcript)
  1015. localConseq3$genomic_start_up[which(
  1016. is.na(localConseq3$genomic_start_up)
  1017. )] <- 0
  1018. localConseq3$genomic_end_up[which(
  1019. is.na(localConseq3$genomic_end_up)
  1020. )] <- 0
  1021. localConseq3$genomic_start_down[which(
  1022. is.na(localConseq3$genomic_start_down)
  1023. )] <- 0
  1024. localConseq3$genomic_end_down[which(
  1025. is.na(localConseq3$genomic_end_down)
  1026. )] <- 0
  1027. ### Identify differences
  1028. localConseq3$coordinatsDifferent <-
  1029. localConseq3$genomic_start_up != localConseq3$genomic_start_down |
  1030. localConseq3$genomic_end_up != localConseq3$genomic_end_down
  1031. localConseq4 <- localConseq3[which(localConseq3$coordinatsDifferent),]
  1032. if(nrow(localConseq4) == 0) {
  1033. stop('No alternative splicing differences were found')
  1034. }
  1035. }
  1036. ### Subset based on input
  1037. if(TRUE) {
  1038. localConseq4 <- localConseq4[which(
  1039. localConseq4$AStype %in% splicingToAnalyze
  1040. ),]
  1041. if (!nrow(localConseq4)) {
  1042. stop('No swithces with consequences were found')
  1043. }
  1044. }
  1045. ### Analyze differences (both start and end coordinats)
  1046. if(TRUE) {
  1047. genomic_start_up <- strsplit(x = localConseq4$genomic_start_up , split = ';')
  1048. genomic_start_down <- strsplit(x = localConseq4$genomic_start_down, split = ';')
  1049. genomic_end_up <- strsplit(x = localConseq4$genomic_end_up , split = ';')
  1050. genomic_end_down <- strsplit(x = localConseq4$genomic_end_down, split = ';')
  1051. localConseq4$nrGain <- 0
  1052. localConseq4$nrLoss <- 0
  1053. for(i in seq_along(genomic_start_up)) {
  1054. # combine start and end of exons
  1055. localUp <- stringr::str_c(genomic_start_up[[i]] , '_', genomic_end_up [[i]])
  1056. localDn <- stringr::str_c(genomic_start_down[[i]], '_', genomic_end_down[[i]])
  1057. # remove coordinats from primary transcripts
  1058. localUp <- localUp[which( localUp != '0_0')]
  1059. localDn <- localDn[which( localDn != '0_0')]
  1060. # calculate difference
  1061. localConseq4$nrGain[i] <- sum(!localUp %in% localDn)
  1062. localConseq4$nrLoss[i] <- sum(!localDn %in% localUp)
  1063. }
  1064. ### Modify ends (can only have 1)
  1065. terminiIndex <- which( localConseq4$AStype %in% c('ATSS','ATTS') )
  1066. localConseq4$nrGain[terminiIndex] <-
  1067. 1 * sign(localConseq4$nrGain[terminiIndex])
  1068. localConseq4$nrLoss[terminiIndex] <-
  1069. 1 * sign(localConseq4$nrLoss[terminiIndex])
  1070. localConseq4$nrDiff <- localConseq4$nrGain - localConseq4$nrLoss
  1071. }
  1072. ### Summarize gain vs loss for each AStype in each condition
  1073. gainLossBalance <- plyr::ddply(
  1074. .data = localConseq4,
  1075. .variables = c('condition_1','condition_2','AStype'),
  1076. .fun = function(aDF) { # aDF <- localConseq4[1:50,]
  1077. if( countGenes ) {
  1078. aDF2 <- plyr::ddply(aDF[,c('gene_ref','nrDiff')], .variables = 'gene_ref', function(aGene) {
  1079. data.frame(
  1080. nrDiff = sum(aGene$nrDiff)
  1081. )
  1082. })
  1083. localRes <- data.frame(
  1084. nUp = sum(aDF2$nrDiff > 0),
  1085. nDown= sum(aDF2$nrDiff < 0)
  1086. )
  1087. } else {
  1088. localRes <- data.frame(
  1089. nUp=sum(aDF$nrDiff > 0),
  1090. nDown=sum(aDF$nrDiff < 0)
  1091. )
  1092. }
  1093. if( localRes$nUp > 0 | localRes$nDown > 0 ) {
  1094. localTest <- suppressWarnings(
  1095. stats::binom.test(localRes$nUp, localRes$nUp + localRes$nDown)
  1096. )
  1097. localRes$propUp <- localTest$estimate
  1098. localRes$propUpCiLo <- min(localTest$conf.int)
  1099. localRes$propUpCiHi <- max(localTest$conf.int)
  1100. localRes$propUpPval <- localTest$p.value
  1101. } else {
  1102. localRes$propUp <- NA
  1103. localRes$propUpCiLo <- NA
  1104. localRes$propUpCiHi <- NA
  1105. localRes$propUpPval <- NA
  1106. }
  1107. return(localRes)
  1108. }
  1109. )
  1110. ### Massage for plotting
  1111. if(TRUE) {
  1112. gainLossBalance <- gainLossBalance[which(
  1113. ! is.na(gainLossBalance$propUp)
  1114. ),]
  1115. gainLossBalance$propUpQval <- p.adjust(gainLossBalance$propUpPval, method = 'fdr')
  1116. gainLossBalance$Significant <- gainLossBalance$propUpQval < alpha
  1117. gainLossBalance$Significant <- factor(
  1118. gainLossBalance$Significant,
  1119. levels=c(FALSE,TRUE)
  1120. )
  1121. gainLossBalance$Comparison <- paste(
  1122. gainLossBalance$condition_1,
  1123. 'vs',
  1124. gainLossBalance$condition_2,
  1125. sep='\n'
  1126. )
  1127. ### Massage splicing type name
  1128. if(TRUE) {
  1129. gainLossBalance$AStype <- paste0(
  1130. gainLossBalance$AStype, ' gain ',
  1131. '(paired with ',gainLossBalance$AStype, ' loss)'
  1132. )
  1133. gainLossBalance$AStype <- gsub('MES gain', 'MES', gainLossBalance$AStype)
  1134. gainLossBalance$AStype <- gsub('MES loss', 'MEI', gainLossBalance$AStype)
  1135. gainLossBalance$AStype <- gsub('ES gain', 'ES', gainLossBalance$AStype)
  1136. gainLossBalance$AStype <- gsub('ES loss', 'EI', gainLossBalance$AStype)
  1137. #gainLossBalance$AStype <- gsub('IR gain', 'IR', gainLossBalance$AStype)
  1138. #gainLossBalance$AStype <- gsub('IR loss', 'IS', gainLossBalance$AStype)
  1139. }
  1140. myOrder <- plyr::ddply(
  1141. gainLossBalance,
  1142. .variables = 'AStype',
  1143. .fun = function(aDF) {
  1144. mean(aDF$propUp)
  1145. })
  1146. myOrder <- myOrder$AStype[sort.list(myOrder$V1, decreasing = TRUE)]
  1147. gainLossBalance$AStype <- factor(
  1148. gainLossBalance$AStype,
  1149. levels = myOrder
  1150. )
  1151. }
  1152. #
  1153. # Prep data for plotting
  1154. gainLossBalance2 <- gainLossBalance[which(
  1155. (gainLossBalance$nUp + gainLossBalance$nDown) >= minEventsForPlotting
  1156. ),]
  1157. gainLossBalance2$nTot <- gainLossBalance2$nUp + gainLossBalance2$nDown
  1158. ####Combining the data to plot:
  1159. opposite <- extractConsequenceEnrichment(
  1160. aSwitchList_part2,
  1161. alpha=0.05,
  1162. dIFcutoff = 0.05,
  1163. countGenes = TRUE,
  1164. analysisOppositeConsequence=T,
  1165. plot=F,
  1166. returnResult=TRUE,
  1167. returnSummary=TRUE)
  1168. opposite <- opposite %>% filter(conseqPair == "NMD_status" |
  1169. conseqPair == "domains_identified" |
  1170. conseqPair == "IDR_identified")
  1171. opposite$Conseq_type <- "Functional Consequence"
  1172. opposite$nTot <- opposite$nUp + opposite$nDown
  1173. opposite$Comparison <- paste0(opposite$condition_1, " vs ", opposite$condition_2)
  1174. opposite <- opposite %>% relocate(c(nUp, nDown), .after = feature)
  1175. opposite <- opposite %>% relocate(Comparison, .before = nTot)
  1176. opposite <- opposite[,-c(3)]
  1177. opposite <- opposite %>% relocate(c(Conseq_type), .after = nTot)
  1178. combined_data <- consequenceBalance2[,-c(3,15)]
  1179. combined_data$Conseq_type <- "Functional Consequence"
  1180. combined_data <- combined_data %>% relocate(c(nUp, nDown), .after = feature)
  1181. combined_data <- combined_data %>% relocate(Comparison, .before = nTot)
  1182. combined_data <- combined_data %>% filter(feature != "NMD insensitive (paired with NMD sensitive)" &
  1183. feature != "Domain gain (paired with Domain loss)" &
  1184. feature != "IDR gain (paired with IDR loss)")
  1185. colnames(combined_data) <- c("condition_1", "condition_2", "feature", "nUp", "nDown",
  1186. "propUp" , "propUpCiLo", "propUpCiHi", "propUpPval",
  1187. "propUpQval", "Significant", "Comparison" , "nTot", "Conseq_type")
  1188. gainLossBalance2$Conseq_type <- "Alternative Splicing"
  1189. colnames(gainLossBalance2) <- c("condition_1", "condition_2", "feature", "nUp", "nDown",
  1190. "propUp" , "propUpCiLo", "propUpCiHi", "propUpPval",
  1191. "propUpQval", "Significant", "Comparison" , "nTot", "Conseq_type")
  1192. colnames(opposite) <- c("condition_1", "condition_2", "feature", "nUp", "nDown",
  1193. "propUp" , "propUpCiLo", "propUpCiHi", "propUpPval",
  1194. "propUpQval", "Significant", "Comparison" , "nTot", "Conseq_type")
  1195. combined_data <- rbind(combined_data, gainLossBalance2)
  1196. combined_data <- rbind(combined_data, opposite)
  1197. combined_data$Comparison <- str_replace(combined_data$Comparison, "t00\nvs\nt04", "t00 vs t04")
  1198. combined_data$Comparison <- str_replace(combined_data$Comparison, "t04\nvs\nt30", "t04 vs t30")
  1199. combined_data$Comparison <- str_replace(combined_data$Comparison, "t00\nvs\nt30", "t00 vs t30")
  1200. combined_data$feature <- as.factor(combined_data$feature)
  1201. library(forcats)
  1202. combined_data$feature <- str_replace(combined_data$feature, "3UTR is longer \\(paired with 3UTR is shorter\\)",
  1203. "3' UTR is longer")
  1204. combined_data$feature <- str_replace(combined_data$feature, "5UTR is longer \\(paired with 5UTR is shorter\\)",
  1205. "5' UTR is longer")
  1206. combined_data$feature <- str_replace(combined_data$feature, "Domain loss \\(paired with Domain gain\\)",
  1207. "Domain loss")
  1208. combined_data$feature <- str_replace(combined_data$feature, "Domain length gain \\(paired with Domain length loss\\)",
  1209. "Domain length gain")
  1210. combined_data$feature <- str_replace(combined_data$feature, "Domain non-reference isotype gain \\(paired with Domain non-reference isotype loss\\)",
  1211. "Domain non-reference isotype gain")
  1212. combined_data$feature <- str_replace(combined_data$feature, "Exon gain \\(paired with Exon loss\\)",
  1213. "Exon number gain")
  1214. combined_data$feature <- str_replace(combined_data$feature, "IDR loss \\(paired with IDR gain\\)",
  1215. "IDR loss")
  1216. combined_data$feature <- str_replace(combined_data$feature, "IDR length gain \\(paired with IDR length loss\\)",
  1217. "IDR is longer")
  1218. combined_data$feature <- str_replace(combined_data$feature, "IDR w binding region gain \\(paired with IDR w binding region loss\\)",
  1219. "IDR with binding region gain")
  1220. combined_data$feature <- str_replace(combined_data$feature, "Last exon more downstream \\(paired with Last exon more upstream\\)",
  1221. "Last exon more downstream")
  1222. combined_data$feature <- str_replace(combined_data$feature, "Length gain \\(paired with Length loss\\)",
  1223. "Isoform is longer")
  1224. combined_data$feature <- str_replace(combined_data$feature, "NMD sensitive \\(paired with NMD insensitive\\)",
  1225. "NMD sensitive")
  1226. combined_data$feature <- str_replace(combined_data$feature, "ORF is longer \\(paired with ORF is shorter\\)",
  1227. "ORF is longer")
  1228. combined_data$feature <- str_replace(combined_data$feature, "Tss more downstream \\(paired with Tss more upstream\\)",
  1229. "TSS more downstream")
  1230. combined_data$feature <- str_replace(combined_data$feature, "Tts more downstream \\(paired with Tts more upstream\\)",
  1231. "TTS more downstream")
  1232. combined_data$feature <- str_replace(combined_data$feature, "A3 gain \\(paired with A3 loss\\)",
  1233. "3' splice site more downstream")
  1234. combined_data$feature <- str_replace(combined_data$feature, "A5 gain \\(paired with A5 loss\\)",
  1235. "5' splice site more upstream")
  1236. combined_data$feature <- str_replace(combined_data$feature, "ATSS gain \\(paired with ATSS loss\\)",
  1237. "ATSS gain")
  1238. combined_data$feature <- str_replace(combined_data$feature, "ATTS gain \\(paired with ATTS loss\\)",
  1239. "ATTS gain")
  1240. combined_data$feature <- str_replace(combined_data$feature, "ES \\(paired with EI\\)",
  1241. "Exon skipping")
  1242. combined_data$feature <- str_replace(combined_data$feature, "MIC gain \\(paired with MIC loss\\)",
  1243. "Microexon skipping")
  1244. combined_data$feature <- str_replace(combined_data$feature, "IR gain \\(paired with IR loss\\)",
  1245. "Intron retention")
  1246. combined_data$feature <- str_replace(combined_data$feature, "MES \\(paired with MEI\\)",
  1247. "Multiple exon skipping")
  1248. combined_data$feature <- str_replace(combined_data$feature, "Signal peptide gain \\(paired with Signal peptide loss\\)",
  1249. "Signal peptide gain")
  1250. combined_data$feature <- str_replace(combined_data$feature, "SubCell location cyto gain \\(paired with SubCell location cyto loss\\)",
  1251. "Shift to cytoplasm localization")
  1252. combined_data$feature <- str_replace(combined_data$feature, "SubCell location ext cell gain \\(paired with SubCell location ext cell loss\\)",
  1253. "Shift to extracellular localization")
  1254. combined_data$feature <- str_replace(combined_data$feature, "SubCell location gain \\(paired with SubCell location loss\\)",
  1255. "Subcellular localization gain")
  1256. combined_data$feature <- str_replace(combined_data$feature, "SubCell location memb gain \\(paired with SubCell location memb loss\\)",
  1257. "Shift to cell membrane localization")
  1258. combined_data$feature <- str_replace(combined_data$feature, "SubCell location nucl gain \\(paired with SubCell location nucl loss\\)",
  1259. "Shift to nuclear localization")
  1260. combined_data$feature <- str_replace(combined_data$feature, "Topology complexity gain \\(paired with Topology complexity loss\\)",
  1261. "Topology complexity gain")
  1262. combined_data$feature <- str_replace(combined_data$feature, "Extracellular length gain \\(paired with Extracellular length loss\\)",
  1263. "Extracellular region length gain")
  1264. combined_data$feature <- str_replace(combined_data$feature, "Extracellular region gain \\(paired with Extracellular region loss\\)",
  1265. "Extracellular region gain")
  1266. combined_data$feature <- str_replace(combined_data$feature, "Intracellular length gain \\(paired with Intracellular length loss\\)",
  1267. "Intracellular region length gain")
  1268. combined_data$feature <- str_replace(combined_data$feature, "Intracellular region gain \\(paired with Intracellular region loss\\)",
  1269. "Intracellular region gain")
  1270. combined_data <- combined_data %>%
  1271. mutate(feature = fct_relevel(feature,
  1272. "3' splice site more downstream", "5' splice site more upstream",
  1273. "ATSS gain", "ATTS gain", "Exon skipping", "Microexon skipping", "Intron retention", "Multiple exon skipping",
  1274. # "Intracellular region gain",
  1275. # "Extracellular region gain",
  1276. # "Intracellular region length gain",
  1277. # "Extracellular region length gain",
  1278. # "Topology complexity gain",
  1279. "Shift to extracellular localization",
  1280. "Shift to cell membrane localization",
  1281. "Shift to nuclear localization",
  1282. "Shift to cytoplasm localization",
  1283. "Subcellular localization gain",
  1284. "Signal peptide gain",
  1285. "IDR with binding region gain",
  1286. "IDR is longer",
  1287. "IDR loss",
  1288. "Domain non-reference isotype gain",
  1289. "Domain length gain",
  1290. "Domain loss",
  1291. "NMD sensitive",
  1292. "ORF is longer",
  1293. "Exon number gain",
  1294. "Isoform is longer",
  1295. "Last exon more downstream",
  1296. "3' UTR is longer",
  1297. "TTS more downstream",
  1298. "5' UTR is longer",
  1299. "TSS more downstream"))
  1300. colnames(combined_data)[13] <- 'Genes'
  1301. library(ggh4x)
  1302. library(extrafont)
  1303. library(scales)
  1304. library(grid)
  1305. font_import(paths = "C:/Windows/Fonts", pattern = "cambria", prompt = F) # This imports all the fonts from your system
  1306. loadfonts(device = "win") # For Windows
  1307. windowsFonts()
  1308. plot_data <- combined_data %>% filter(#feature == "Multiple exon skipping" |
  1309. feature == "Intron retention" |
  1310. feature == "Exon skipping" |
  1311. feature == "Microexon skipping" |
  1312. # feature == "5' splice site more upstream" |
  1313. # feature == "3' splice site more downstream" |
  1314. # feature == "TSS more downstream" |
  1315. feature == "5' UTR is longer" |
  1316. # feature == "TTS more downstream" |
  1317. feature == "3' UTR is longer" |
  1318. # feature == "Isoform is longer" |
  1319. # feature == "ORF is longer" |
  1320. feature == "NMD sensitive" |
  1321. feature == "Domain loss" |
  1322. # feature == "Domain length gain" |
  1323. feature == "IDR loss" #|
  1324. # feature == "IDR is longer"
  1325. )
  1326. desired_order <- c("Exon skipping",
  1327. "Microexon skipping",
  1328. "Intron retention",
  1329. "NMD sensitive",
  1330. "Domain loss",
  1331. "IDR loss",
  1332. "5' UTR is longer",
  1333. "3' UTR is longer")
  1334. plot_data <- plot_data %>%
  1335. mutate(feature = factor(feature, levels = rev(desired_order)))
  1336. combined_plot_1 <- plot_data %>%
  1337. ggplot(aes(y=feature, x=propUp, color=Significant)) +
  1338. geom_errorbarh(aes(xmax = propUpCiLo, xmin=propUpCiHi), height = .3) +
  1339. # geom_point(aes(size=Genes)) +
  1340. geom_text(label = "\u25D6", aes(size=Genes), family = "Cambria") +
  1341. facet_wrap(~ factor(Comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")), scales = "free_x") +
  1342. geom_vline(xintercept=0.5, linetype='dashed') +
  1343. labs(title = "Isoform Switching Consequences",
  1344. x="Fraction of Genes with Switches Primarily Resulting in Each Event") +
  1345. theme_void(base_size = 8) +
  1346. theme(plot.title = element_text(hjust = 0.5, size = 8, face = "bold"),
  1347. strip.text = element_text(size = 8),
  1348. axis.text = element_text(colour = "black", size = 6.4),
  1349. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1),
  1350. legend.position = "top",
  1351. legend.box = "horizontal",
  1352. legend.box.just = "center",
  1353. legend.text = element_text(size = 7),
  1354. legend.key.spacing.y = unit(0, "pt"),
  1355. legend.key.height = unit(-20, "lines"),
  1356. axis.title.y = element_blank(),
  1357. legend.margin = margin(
  1358. t = 0,
  1359. r = 0,
  1360. b = 0,
  1361. l = 0,
  1362. unit = "cm"
  1363. )) +
  1364. scale_color_manual(name = paste0('FDR < ', alpha), values=c('black','red'), drop=FALSE) +
  1365. scale_radius(limits=c(1, max(plot_data$Genes)),
  1366. breaks = c(50, 500, 2000, 4000)) +
  1367. guides(color = guide_legend(order=1, nrow = 2, byrow = T),
  1368. size = guide_legend(order=2, override.aes = list(color = "black"), nrow = 2, byrow = T)) +
  1369. coord_cartesian(xlim=c(0,1))
  1370. combined_plot_1
  1371. # Create a version of the plot for legend extraction
  1372. combined_plot_symbols_only <- combined_plot_1 +
  1373. theme(
  1374. legend.text = element_text(colour = "transparent"), # invisible but still occupies space
  1375. legend.title = element_text(colour = "transparent") # invisible but still occupies space
  1376. )
  1377. legend_1 <- ggpubr::get_legend(combined_plot_symbols_only)
  1378. combined_plot_2 <- plot_data %>%
  1379. ggplot(aes(y=feature, x=propUp, color=Significant)) +
  1380. geom_errorbarh(aes(xmax = propUpCiLo, xmin=propUpCiHi), height = .3) +
  1381. geom_text(label = "\u25D7", aes(size=Genes), family = "Cambria") +
  1382. facet_wrap(~ factor(Comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")), scales = "free_x") +
  1383. geom_vline(xintercept=0.5, linetype='dashed') +
  1384. labs(title = "Isoform Switching Consequences",
  1385. x="Fraction of Genes with Switches Primarily Resulting in Each Event"
  1386. ) +
  1387. theme_void(base_size = 8) +
  1388. theme(plot.title = element_text(hjust = 0.5, size = 8, face = "bold"),
  1389. strip.text = element_text(size = 8),
  1390. axis.text = element_text(colour = "black", size = 6.4),
  1391. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1),
  1392. legend.position = "top",
  1393. legend.box = "horizontal",
  1394. legend.box.just = "center",
  1395. legend.key.height = unit(-10, "lines"),
  1396. legend.key.spacing.y = unit(0, "pt"),
  1397. legend.text = element_text(size = 7),
  1398. axis.title.y = element_blank(),
  1399. legend.margin = margin(
  1400. t = 0,
  1401. r = 0,
  1402. b = 0,
  1403. l = 0,
  1404. unit = "cm"
  1405. )) +
  1406. scale_color_manual(name = paste0('FDR < ', alpha), values=c('black','red'), drop=FALSE) +
  1407. scale_radius(limits=c(1, max((plot_data$Genes))),
  1408. breaks = c(50, 500, 2000, 4000)) +
  1409. guides(color = guide_legend(order=1, nrow = 2, byrow = T),
  1410. size = guide_legend(order=2, override.aes = list(color = "red"), nrow = 2, byrow = T)) +
  1411. coord_cartesian(xlim=c(0,1))
  1412. combined_plot_2
  1413. # Extract the legend from the plot
  1414. legend_2 <- ggpubr::get_legend(combined_plot_2)
  1415. combined_plot <- plot_data %>%
  1416. ggplot(aes(y=feature, x=propUp, color=Significant)) +
  1417. geom_errorbarh(aes(xmax = propUpCiLo, xmin=propUpCiHi), height = .3) +
  1418. # geom_point(aes(size=Genes)) +
  1419. geom_text(label = "\u25CF", aes(size=Genes), family = "Cambria") +
  1420. facet_wrap(~ factor(Comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")), scales = "free_x") +
  1421. geom_vline(xintercept=0.5, linetype='dashed') +
  1422. labs(title = "Isoform Switching Consequences",
  1423. x=str_wrap("Fraction of Genes with Switches Primarily Resulting in Each Event", 40)
  1424. # y='Event/Consequence of Isoform Switch'
  1425. ) +
  1426. theme_bw(base_size = 8) +
  1427. theme(plot.title = element_text(hjust = 0.5, vjust = 17, size = 8, face = "bold"),
  1428. strip.text = element_text(size = 8),
  1429. axis.text = element_text(colour = "black", size = 6.4),
  1430. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1),
  1431. legend.position = "none",
  1432. axis.title.y = element_blank() ) +
  1433. scale_color_manual(name = paste0('FDR < ', alpha), values=c('black','red'), drop=FALSE) +
  1434. scale_radius(limits=c(1, max((plot_data$Genes)))) +
  1435. guides(color = guide_legend(order=1),
  1436. size = guide_legend(order=2)) +
  1437. coord_cartesian(xlim=c(0,1)) +
  1438. scale_y_discrete(labels = label_wrap_gen(width = 17))
  1439. combined_plot
  1440. testp <- ggdraw() +
  1441. draw_plot(combined_plot + theme(plot.margin = margin(t = 15, r = 6, b = 6, l = 10, unit = "pt"))
  1442. , x = 0, y = 0, width = 1, height = 0.94) +
  1443. draw_plot(legend_1, x = 0, y = 0.41, width = 1, height = 1) +
  1444. draw_plot(legend_2, x = 0, y = 0.41, width = 1, height = 1)
  1445. testp
  1446. # PLOTTING SWITCH SUPP FIG ------------------------------------------------
  1447. plot_data_full <- combined_data %>% filter(feature != "Shift to extracellular localization" &
  1448. feature != "Shift to cell membrane localization" &
  1449. feature != "Shift to nuclear localization" &
  1450. feature != "Shift to cytoplasm localization" &
  1451. feature != "Subcellular localization gain" &
  1452. feature != "Signal peptide gain" &
  1453. feature != "MEE gain (paired with MEE loss)" )
  1454. combined_plot_1 <- plot_data_full %>%
  1455. ggplot(aes(y=feature, x=propUp, color=Significant)) +
  1456. geom_errorbarh(aes(xmax = propUpCiLo, xmin=propUpCiHi), height = .3) +
  1457. # geom_point(aes(size=Genes)) +
  1458. geom_text(label = "\u25D6", aes(size=Genes), family = "Cambria") +
  1459. facet_grid(Conseq_type ~ factor(Comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")), scales = "free_y") +
  1460. force_panelsizes(c((plot_data %>% filter(Conseq_type == "Alternative Splicing") %>% tally() /3),
  1461. (plot_data %>% filter(Conseq_type == "Functional Consequence") %>% tally() /3)),
  1462. cols = 3,
  1463. respect = NULL) +
  1464. geom_vline(xintercept=0.5, linetype='dashed') +
  1465. labs(title = "Isoform Switching Consequences",
  1466. x="Fraction of Genes with Switches Primarily Resulting in Each Event") +
  1467. theme_void(base_size = 8) +
  1468. theme(plot.title = element_text(hjust = 0.5, size = 8, face = "bold"),
  1469. strip.text = element_text(size = 8),
  1470. axis.text = element_text(colour = "black", size = 6.4),
  1471. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1),
  1472. legend.position = "top",
  1473. legend.box = "horizontal",
  1474. legend.box.just = "center",
  1475. legend.text = element_text(size = 7),
  1476. # legend.key.size = element_rect(size = 10),
  1477. legend.key.spacing.y = unit(0, "pt"),
  1478. legend.key.height = unit(-20, "lines"),
  1479. axis.title.y = element_blank(),
  1480. legend.margin = margin(
  1481. t = 0,
  1482. r = 0,
  1483. b = 0,
  1484. l = 0,
  1485. unit = "cm"
  1486. )) +
  1487. scale_color_manual(name = paste0('FDR < ', alpha), values=c('black','red'), drop=FALSE) +
  1488. scale_radius(limits=c(1, 6501),
  1489. breaks = c(50, 500, 2500, 6500)) +
  1490. guides(color = guide_legend(order=1, nrow = 2, byrow = T),
  1491. size = guide_legend(order=2, override.aes = list(color = "black"), nrow = 2, byrow = T)) +
  1492. coord_cartesian(xlim=c(0,1))
  1493. combined_plot_1
  1494. # Create a version of the plot for legend extraction
  1495. combined_plot_symbols_only <- combined_plot_1 +
  1496. theme(
  1497. legend.text = element_text(colour = "transparent"), # invisible but still occupies space
  1498. legend.title = element_text(colour = "transparent") # invisible but still occupies space
  1499. )
  1500. legend_1 <- ggpubr::get_legend(combined_plot_symbols_only)
  1501. combined_plot_2 <- plot_data_full %>%
  1502. ggplot(aes(y=feature, x=propUp, color=Significant)) +
  1503. geom_errorbarh(aes(xmax = propUpCiLo, xmin=propUpCiHi), height = .3) +
  1504. geom_text(label = "\u25D7", aes(size=Genes), family = "Cambria") +
  1505. facet_grid(Conseq_type ~ factor(Comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")), scales = "free_y") +
  1506. force_panelsizes(c((plot_data %>% filter(Conseq_type == "Alternative Splicing") %>% tally() /3),
  1507. (plot_data %>% filter(Conseq_type == "Functional Consequence") %>% tally() /3)), #7 AS, 15 func conseq
  1508. cols = 3,
  1509. respect = NULL) +
  1510. geom_vline(xintercept=0.5, linetype='dashed') +
  1511. labs(title = "Isoform Switching Consequences",
  1512. x="Fraction of Genes with Switches Primarily Resulting in Each Event"
  1513. # y='Event/Consequence of Isoform Switch'
  1514. ) +
  1515. theme_void(base_size = 8) +
  1516. theme(plot.title = element_text(hjust = 0.5, size = 8, face = "bold"),
  1517. strip.text = element_text(size = 8),
  1518. axis.text = element_text(colour = "black", size = 6.4),
  1519. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1),
  1520. legend.position = "top",
  1521. legend.box = "horizontal",
  1522. legend.box.just = "center",
  1523. legend.key.height = unit(-10, "lines"),
  1524. legend.key.spacing.y = unit(0, "pt"),
  1525. legend.text = element_text(size = 7),
  1526. axis.title.y = element_blank(),
  1527. legend.margin = margin(
  1528. t = 0,
  1529. r = 0,
  1530. b = 0,
  1531. l = 0,
  1532. unit = "cm"
  1533. )) +
  1534. scale_color_manual(name = paste0('FDR < ', alpha), values=c('black','red'), drop=FALSE) +
  1535. scale_radius(limits=c(1, 6501),
  1536. breaks = c(50, 500, 2500, 6500)) +
  1537. guides(color = guide_legend(order=1, nrow = 2, byrow = T),
  1538. size = guide_legend(order=2, override.aes = list(color = "red"), nrow = 2, byrow = T)) +
  1539. coord_cartesian(xlim=c(0,1))
  1540. combined_plot_2
  1541. # Extract the legend from the plot
  1542. legend_2 <- ggpubr::get_legend(combined_plot_2)
  1543. combined_plot <- plot_data_full %>%
  1544. ggplot(aes(y=feature, x=propUp, color=Significant)) +
  1545. geom_errorbarh(aes(xmax = propUpCiLo, xmin=propUpCiHi), height = .3) +
  1546. # geom_point(aes(size=Genes)) +
  1547. geom_text(label = "\u25CF", aes(size=Genes), family = "Cambria") +
  1548. facet_grid(Conseq_type ~ factor(Comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")), scales = "free_y") +
  1549. force_panelsizes(c((plot_data %>% filter(Conseq_type == "Alternative Splicing") %>% tally() /3),
  1550. (plot_data %>% filter(Conseq_type == "Functional Consequence") %>% tally() /3)), #7 AS, 15 func conseq
  1551. cols = 3,
  1552. respect = NULL) +
  1553. geom_vline(xintercept=0.5, linetype='dashed') +
  1554. labs(title = "Isoform Switching Consequences",
  1555. x=str_wrap("Fraction of Genes with Switches Primarily Resulting in Each Event", 40)
  1556. # y='Event/Consequence of Isoform Switch'
  1557. ) +
  1558. theme_bw(base_size = 8) +
  1559. theme(plot.title = element_text(hjust = 0.5, vjust = 17, size = 8, face = "bold"),
  1560. strip.text = element_text(size = 8),
  1561. axis.text = element_text(colour = "black", size = 6.4),
  1562. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1),
  1563. legend.position = "none",
  1564. axis.title.y = element_blank() ) +
  1565. scale_color_manual(name = paste0('FDR < ', alpha), values=c('black','red'), drop=FALSE) +
  1566. scale_radius(limits=c(1, 6501)) +
  1567. guides(color = guide_legend(order=1),
  1568. size = guide_legend(order=2)) +
  1569. coord_cartesian(xlim=c(0,1)) +
  1570. scale_y_discrete(labels = label_wrap_gen(width = 22))
  1571. combined_plot
  1572. #ggarrange(combined_plot ,legend_2)
  1573. testp <- ggdraw() +
  1574. draw_plot(combined_plot + theme(plot.margin = margin(t = 15, r = 6, b = 6, l = 10, unit = "pt"))
  1575. , x = 0, y = 0, width = 1, height = 0.94) +
  1576. draw_plot(legend_1, x = 0, y = 0.42, width = 1, height = 1) +
  1577. draw_plot(legend_2, x = 0, y = 0.42, width = 1, height = 1)
  1578. testp
  1579. library(Cairo)
  1580. CairoPDF(paste0("./figures/SUPP_switching.pdf"), height = 7, width = 6.5)
  1581. print(testp)
  1582. dev.off()
  1583. svg(paste0("./figures/SUPP_switching.svg"), height = 7, width = 6.5)
  1584. print(testp)
  1585. dev.off()
  1586. # AGO1 PLOT -----------------------------------------------
  1587. #Need to manually run these IsoformSwitchAnalyzeR functions to run the modified function below
  1588. source('./code/figures/Functions.R')
  1589. switchAnalyzeRlist = aSwitchList_part2
  1590. gene = "AGO1"
  1591. isoform_id = NULL
  1592. condition1 = "t00"
  1593. condition2 = "t30"
  1594. ### Advanced arguments
  1595. IFcutoff = 0.05
  1596. dIFcutoff = 0.05
  1597. alphas = c(0.05, 0.001)
  1598. rescaleTranscripts = TRUE
  1599. plotTopology = FALSE
  1600. reverseMinus = TRUE
  1601. addErrorbars = TRUE
  1602. logYaxis = FALSE
  1603. localTheme = theme_bw(base_size = 6.4)
  1604. additionalArguments = list(switchPlotTranscript, switchPlotGeneExp, switchPlotIsoExp, switchPlotIsoUsage)
  1605. # check conditions
  1606. if (TRUE) {
  1607. ### Identify conditions
  1608. allConditionPairs <-
  1609. unique(switchAnalyzeRlist$isoformFeatures[,c(
  1610. 'condition_1', 'condition_2'
  1611. )])
  1612. levelsToMatch <- as.vector(t(allConditionPairs))
  1613. conditionsFound <-
  1614. apply(allConditionPairs, 1, function(x) {
  1615. x[1] == condition1 & x[2] == condition2
  1616. })
  1617. if (!any(conditionsFound)) {
  1618. # the the conditions are not found try revers order
  1619. conditionsFound <-
  1620. apply(allConditionPairs, 1, function(x) {
  1621. x[2] == condition1 & x[1] == condition2
  1622. })
  1623. # if now found change the order of conditions
  1624. if (any(conditionsFound)) {
  1625. temp <- condition1
  1626. condition1 <- condition2
  1627. condition2 <- temp
  1628. } else {
  1629. stop(
  1630. paste(
  1631. 'The wanted comparison: \'',
  1632. condition1,
  1633. ' vs ',
  1634. condition2,
  1635. '\' is not in the data - please revise accordingly'
  1636. )
  1637. )
  1638. }
  1639. }
  1640. } else {
  1641. condition1 <- allConditionPairs$condition_1
  1642. condition2 <- allConditionPairs$condition_2
  1643. }
  1644. levelsToMatch <-
  1645. levelsToMatch[which(
  1646. levelsToMatch %in% c(condition1, condition2)
  1647. )]
  1648. ### Parse additional list argument
  1649. if (TRUE) {
  1650. ### Expression plot arguments
  1651. if (TRUE) {
  1652. ## Make list with default values - can be replaced by as.list(args(expressionPlots)) ?
  1653. eArgList <- list(
  1654. switchAnalyzeRlist = switchAnalyzeRlist,
  1655. gene = gene,
  1656. isoform_id = isoform_id,
  1657. condition1 = condition1,
  1658. condition2 = condition2,
  1659. IFcutoff = IFcutoff,
  1660. addErrorbars = addErrorbars,
  1661. confidenceIntervalErrorbars = TRUE,
  1662. confidenceInterval = 0.95,
  1663. #alphas = c(0.05, 0.001),
  1664. alphas = alphas,
  1665. logYaxis = logYaxis,
  1666. extendFactor = 0.05,
  1667. localTheme = localTheme
  1668. )
  1669. ### Modify default arguments if nessesary
  1670. # subset to only those not already covered by the arguments
  1671. additionalArguments2 <-
  1672. additionalArguments[which(
  1673. names(additionalArguments) %in% c(
  1674. 'confidenceIntervalErrorbars',
  1675. 'confidenceInterval',
  1676. 'alphas',
  1677. 'extendFactor',
  1678. 'rescaleRoot'
  1679. )
  1680. )]
  1681. if (length(additionalArguments2) != 0) {
  1682. newArgNames <- names(additionalArguments2)
  1683. for (i in seq_along(additionalArguments2)) {
  1684. eArgList[[newArgNames[i]]] <- additionalArguments2[[i]]
  1685. }
  1686. }
  1687. }
  1688. }
  1689. ### Make subplots - these functions also check the input thoroughly
  1690. # expression plots
  1691. expressionPlots <- expressionAnalysisPlot(
  1692. switchAnalyzeRlist = eArgList$switchAnalyzeRlist,
  1693. gene = eArgList$gene,
  1694. isoform_id = eArgList$isoform_id,
  1695. condition1 = eArgList$condition1,
  1696. condition2 = eArgList$condition2,
  1697. IFcutoff = eArgList$IFcutoff,
  1698. addErrorbars = eArgList$addErrorbars,
  1699. confidenceIntervalErrorbars = eArgList$confidenceIntervalErrorbars,
  1700. confidenceInterval = eArgList$confidenceInterval,
  1701. alphas = eArgList$alphas,
  1702. optimizeForCombinedPlot = TRUE,
  1703. logYaxis = eArgList$logYaxis,
  1704. extendFactor = eArgList$extendFactor,
  1705. localTheme = eArgList$localTheme
  1706. )
  1707. #
  1708. ### Change plot margin
  1709. marginSize <- 0.1
  1710. expressionPlots2 <-
  1711. lapply(expressionPlots[1:2], function(x) {
  1712. x +
  1713. theme(
  1714. plot.margin = margin(
  1715. t = 6,
  1716. r = 6,
  1717. b = 6,
  1718. l = 6,
  1719. unit = "pt" ),
  1720. legend.position="none"
  1721. )
  1722. })
  1723. expressionPlots3 <-
  1724. lapply(expressionPlots[3], function(x) {
  1725. x +
  1726. theme(
  1727. margin(
  1728. t = 6,
  1729. r = 6,
  1730. b = 6,
  1731. l = 6,
  1732. unit = "pt" ),
  1733. legend.position="none"
  1734. )
  1735. })
  1736. label_new <- c(
  1737. "<span style='color:#009E73'><b>PB.1207.309",
  1738. "<span style='color:#009E73'><b>PB.1207.317",
  1739. "<span style='color:#D55E00'><b>PB.1207.336")
  1740. #Run this file to bring in the edited AGO1 plotting functions
  1741. source("./code/figures/ago_plotting.R")
  1742. myPlot <- AGO1_plotting()
  1743. library(ggtext)
  1744. test <-
  1745. myPlot +
  1746. theme(plot.margin = margin(
  1747. t = 6,
  1748. r = 6,
  1749. b = 6,
  1750. l = 6,
  1751. unit = "pt"),
  1752. legend.margin = margin(t= -6,0,0,0,unit = "pt"),
  1753. legend.position="bottom",
  1754. legend.key.size = unit(0.25, 'cm'),
  1755. plot.title = element_text(hjust = 0.5, face = "bold", size = 10),
  1756. axis.text.y = element_markdown(size = 8),
  1757. legend.title = element_blank(),
  1758. legend.text = element_text(size = 8)) +
  1759. scale_y_continuous(
  1760. breaks = c(3,2,1), # Set the y-axis positions
  1761. labels = label_new # Apply the custom labels
  1762. ) +
  1763. labs(title = "AGO1 - t00 vs t30") +
  1764. guides(fill = guide_legend(nrow = 1))
  1765. test
  1766. #
  1767. expressionPlots2$gene_expression$data$Analyis <- "DGE"
  1768. expressionPlots3$isoform_usage$data$Analyis <- "DTU"
  1769. expressionPlots2$isoform_expression$data$Analyis <- "DTE"
  1770. AGO1 <- ggdraw() +
  1771. draw_plot(test + theme(panel.grid.major = element_blank(),
  1772. panel.grid.minor = element_blank(),
  1773. plot.title = element_text(hjust = 0.5, size = 8, face = "bold")), x = 0, y = 0.6, width = 1, height = 0.4) +
  1774. draw_plot(expressionPlots2$gene_expression +
  1775. theme(axis.text.x=element_text(angle=-45, hjust = 0, vjust=1, size = 6.4, colour = "black"),
  1776. axis.text.y=element_text(size = 6.4, colour = "black"),
  1777. axis.title = element_text(size = 8),
  1778. strip.text = element_text(size = 8) ),
  1779. x = 0, y = 0, width = 0.3, height = 0.6) +
  1780. draw_plot(expressionPlots3$isoform_usage +
  1781. theme(plot.margin = margin(t = 6, r = 6, b = 6, l = 6, unit = "pt"),
  1782. axis.text.x=element_text(angle=-45, hjust = 0, vjust=1, size = 6.4, colour = "black"),
  1783. axis.text.y=element_text(size = 6.4, colour = "black"),
  1784. axis.title = element_text(size = 8),
  1785. strip.text = element_text(size = 8)) +
  1786. facet_wrap(~ Analyis, labeller = label_wrap_gen(width = 10)) , x = 0.65, y = 0, width = 0.35, height = 0.6) +
  1787. draw_plot(expressionPlots2$isoform_expression +
  1788. theme(axis.text.x=element_text(angle=-45, hjust = 0, vjust=1, size = 6.4, colour = "black"),
  1789. axis.text.y=element_text(size = 6.4, colour = "black"),
  1790. axis.title = element_text(size = 8),
  1791. strip.text = element_text(size = 8)) +
  1792. facet_wrap(~ Analyis, labeller = label_wrap_gen(width = 10)), x = 0.3, y = 0, width = 0.35, height = 0.6)
  1793. AGO1
  1794. AGO1 <- AGO1 + theme(plot.margin = margin(t = 0, r = 16, b = 0, l = 6, unit = "pt"))
  1795. # IR + NMD ----------------------------------------------------------------
  1796. #IR transcripts:
  1797. AS <- aSwitchList_part2$AlternativeSplicingAnalysis
  1798. AS_IR <- AS %>% filter(IR > 0) #12224 transcripts with 1 or more retained introns
  1799. AS_IR <- merge(AS_IR, classification[, c("isoform", "associated_gene")],
  1800. by.x = "isoform_id", by.y = "isoform", all.x = T)
  1801. CPM <- read.csv("./code/expression/output/transcript_CPM.csv")
  1802. CPM$Avgt00 <- rowMeans(subset(CPM, select = c(1:3)))
  1803. CPM$Avgt04 <- rowMeans(subset(CPM, select = c(4:9)))
  1804. CPM$Avgt30 <- rowMeans(subset(CPM, select = c(10:15)))
  1805. CPM$IR <- ifelse(CPM$pb_id %in% AS_IR$isoform_id, "IR", "no_IR")
  1806. #Only keep isoforms in the AS from isoswitch object:
  1807. CPM_AS <- CPM %>% filter(pb_id %in% aSwitchList_part2$AlternativeSplicingAnalysis$isoform_id)
  1808. #PTC transcripts:
  1809. PTC_tr <- aSwitchList_part2$isoformFeatures %>% filter(PTC == TRUE) %>% pull(isoform_id) %>% unique()
  1810. CPM$PTC <- ifelse(CPM$pb_id %in% PTC_tr, "PTC", "no_PTC")
  1811. CPM_PTC <- CPM %>% filter(pb_id %in% aSwitchList_part2$AlternativeSplicingAnalysis$isoform_id)
  1812. #IR =
  1813. IR_tr <- CPM %>% filter(IR == "IR") %>% pull(pb_id) %>% unique()
  1814. #IR only:
  1815. IR_only <- setdiff(IR_tr, PTC_tr) #9606
  1816. #NMD only:
  1817. PTC_only <- setdiff(PTC_tr, IR_tr)
  1818. #Overlap:
  1819. overlap <- intersect(IR_tr, PTC_tr)
  1820. #Remaining:
  1821. all <- unique(union(IR_tr, PTC_tr))
  1822. remaining <- setdiff(CPM_AS$pb_id, all)
  1823. transcript_groups <- list(
  1824. IR_only = IR_only,
  1825. PTC_only = PTC_only,
  1826. overlap = overlap,
  1827. remaining = remaining)
  1828. # Convert the list into a long data.frame for joining
  1829. group_df <- bind_rows(lapply(names(transcript_groups), function(name) {
  1830. data.frame(pb_id = transcript_groups[[name]], group = name)
  1831. }))
  1832. # Join and label the group
  1833. CPM_AS <- CPM_AS %>%
  1834. left_join(group_df, by = "pb_id")
  1835. cpm_long_AS <- CPM_AS %>%
  1836. pivot_longer(c("Avgt00", "Avgt04", "Avgt30"),
  1837. names_to = "Timepoint",
  1838. values_to = "CPM")
  1839. library(rstatix)
  1840. library(scales)
  1841. cpm_long_AS$log_cpm <- log2(cpm_long_AS$CPM + 1)
  1842. stat.test.ir <- cpm_long_AS %>% group_by(Timepoint) %>% wilcox_test(log_cpm ~ group)
  1843. stat.test.ir <- stat.test.ir %>% mutate(p.adj.signif = p.adjust(p, method='bonferroni')) #need to do sep, b/c of group_by
  1844. stat.test.ir <- stat.test.ir %>% add_xy_position(x = "Timepoint")
  1845. stat.test.ir$p.adj.signif <- sprintf("%.2e", stat.test.ir$p.adj.signif)
  1846. stat.test.ir <- stat.test.ir %>% add_significance(p.col = "p.adj")
  1847. stat.test.ir$y.position <- log2(stat.test.ir$y.position + 1)
  1848. stat.test.ir <- stat.test.ir %>%
  1849. mutate(group1 = recode(group1, "IR_only" = "IR only"),
  1850. group2 = recode(group2, "IR_only" = "IR only"),
  1851. group1 = recode(group1, "overlap" = "IR & PTC"),
  1852. group2 = recode(group2, "overlap" = "IR & PTC"),
  1853. group1 = recode(group1, "PTC_only" = "PTC only"),
  1854. group2 = recode(group2, "PTC_only" = "PTC only"),
  1855. group1 = recode(group1, "remaining" = "Others"),
  1856. group2 = recode(group2, "remaining" = "Others"))
  1857. cpm_long_AS <- cpm_long_AS %>%
  1858. mutate(group = recode(group, "IR_only" = "IR only"),
  1859. group = recode(group, "IR_only" = "IR only"),
  1860. group = recode(group, "overlap" = "IR & PTC"),
  1861. group = recode(group, "overlap" = "IR & PTC"),
  1862. group = recode(group, "PTC_only" = "PTC only"),
  1863. group = recode(group, "PTC_only" = "PTC only"),
  1864. group = recode(group, "remaining" = "Others"),
  1865. group = recode(group, "remaining" = "Others"))
  1866. cpm_long_AS$group <- factor(cpm_long_AS$group, levels = c("IR only", "IR & PTC", "PTC only", "Others"))
  1867. bp <- cpm_long_AS %>%
  1868. ggplot(aes(x=factor(Timepoint), y=log_cpm)) +
  1869. geom_boxplot(aes(fill = group, colour = group),
  1870. # outlier.size = 0.0001,
  1871. outlier.shape = NA,
  1872. size = 0.2,
  1873. alpha = 0.35,
  1874. # size = 0.5,
  1875. linewidth = 0.45,
  1876. width = 0.7
  1877. ) +
  1878. ylim(0, 6.4) +
  1879. labs(y = "log2(CPM + 1)") +
  1880. stat_pvalue_manual(stat.test.ir,
  1881. label = "p.adj.signif",
  1882. size = 2.5 ,
  1883. bracket.nudge.y = 1.2,
  1884. step.group.by = "Timepoint",
  1885. step.increase = 0.02,
  1886. tip.length = 0.01,
  1887. bracket.size = 0.2) +
  1888. theme_classic(base_size = 8) +
  1889. theme(legend.title = element_blank(),
  1890. legend.text = element_text(size = 8),
  1891. axis.title.x = element_blank(),
  1892. legend.position = "right",
  1893. axis.text = element_text(size = 8)) +
  1894. scale_x_discrete(labels = c("Avgt00" = "t00", "Avgt04" = "t04", "Avgt30" = "t30"))
  1895. bp
  1896. #
  1897. pdf(paste0("./figures/SUPP_IR_NMD_transcript.pdf"), height = 3.5, width = 4)
  1898. print(bp)
  1899. dev.off()
  1900. svg(paste0("./figures/SUPP_IR_NMD_transcript.svg"), height = 3.5, width = 4)
  1901. print(bp)
  1902. dev.off()
  1903. # APA ---------------------------------------------------------------------
  1904. #K APA
  1905. K_PPAU_t00_v_t30 <- read.csv("./code/APA/output/APA/PPAU_t00_v_t30.csv")
  1906. cluster_t30_vs_t00_df <- read.csv("./code/APA/output/APA/Deseq2_cluster_lrmethod_t00_v_t30.csv")
  1907. K_PPAU_t00_v_t30 <- merge(K_PPAU_t00_v_t30, cluster_t30_vs_t00_df[, c("X", "log2FoldChange", "padj")],
  1908. by.x = "sequence_cluster", by.y = "X", all.x = T)
  1909. K_PPAU_t00_v_t30 <- K_PPAU_t00_v_t30 %>% mutate(Analysis = "Long-read method",
  1910. Comparison = "t00 vs t30")
  1911. K_PPAU_t00_v_t30 <- K_PPAU_t00_v_t30[,c(1, 21, 22, 24:27)]
  1912. colnames(K_PPAU_t00_v_t30)[1] <- "GeneName"
  1913. K_PPAU_t00_v_t04 <- read.csv("./code/APA/output/APA/PPAU_t00_v_t04.csv")
  1914. cluster_t04_vs_t00_df <- read.csv("./code/APA/output/APA/Deseq2_cluster_lrmethod_t00_v_t04.csv")
  1915. K_PPAU_t00_v_t04 <- merge(K_PPAU_t00_v_t04, cluster_t04_vs_t00_df[, c("X", "log2FoldChange", "padj")],
  1916. by.x = "sequence_cluster", by.y = "X", all.x = T)
  1917. K_PPAU_t00_v_t04 <- K_PPAU_t00_v_t04 %>% mutate(Analysis = "Long-read method",
  1918. Comparison = "t00 vs t04")
  1919. K_PPAU_t00_v_t04 <- K_PPAU_t00_v_t04[,c(1, 21, 22, 24:27)]
  1920. colnames(K_PPAU_t00_v_t04)[1] <- "GeneName"
  1921. K_PPAU_t04_v_t30 <- read.csv("./code/APA/output/APA/PPAU_t04_v_t30.csv")
  1922. cluster_t30_vs_t04_df <- read.csv("./code/APA/output/APA/Deseq2_cluster_lrmethod_t04_v_t30.csv")
  1923. K_PPAU_t04_v_t30 <- merge(K_PPAU_t04_v_t30, cluster_t30_vs_t04_df[, c("X", "log2FoldChange", "padj")],
  1924. by.x = "sequence_cluster", by.y = "X", all.x = T)
  1925. K_PPAU_t04_v_t30 <- K_PPAU_t04_v_t30 %>% mutate(Analysis = "Long-read method",
  1926. Comparison = "t04 vs t30")
  1927. K_PPAU_t04_v_t30 <- K_PPAU_t04_v_t30[,c(1, 21, 22, 24:27)]
  1928. colnames(K_PPAU_t04_v_t30)[1] <- "GeneName"
  1929. #QAPA
  1930. QAPA_PPAU_t00_v_30 <- read.csv("./code/APA/output/QAPA/QAPA_PPAU_t00_v_t30.csv")
  1931. cluster_t00_vs_t30_df <- read.csv("./code/APA/output/QAPA/Deseq2_cluster_t00_v_t30.csv")
  1932. QAPA_PPAU_t00_v_30 <- merge(QAPA_PPAU_t00_v_30, cluster_t00_vs_t30_df[, c("X", "log2FoldChange", "padj")],
  1933. by.x = "GeneName", by.y = "X", all.x = T)
  1934. QAPA_PPAU_t00_v_30 <- QAPA_PPAU_t00_v_30 %>% mutate(Analysis = "QAPA",
  1935. Comparison = "t00 vs t30")
  1936. QAPA_PPAU_t00_v_30 <- QAPA_PPAU_t00_v_30[,c(1, 22:27)]
  1937. QAPA_PPAU_t00_v_04 <- read.csv("./code/APA/output/QAPA/QAPA_PPAU_t00_v_t04.csv")
  1938. cluster_t00_vs_t04_df <- read.csv("./code/APA/output/QAPA/Deseq2_cluster_t00_v_t04.csv")
  1939. QAPA_PPAU_t00_v_04 <- merge(QAPA_PPAU_t00_v_04, cluster_t00_vs_t04_df[, c("X", "log2FoldChange", "padj")],
  1940. by.x = "GeneName", by.y = "X", all.x = T)
  1941. QAPA_PPAU_t00_v_04 <- QAPA_PPAU_t00_v_04 %>% mutate(Analysis = "QAPA",
  1942. Comparison = "t00 vs t04")
  1943. QAPA_PPAU_t00_v_04 <- QAPA_PPAU_t00_v_04[,c(1, 22:27)]
  1944. QAPA_PPAU_t04_v_30 <- read.csv("./code/APA/output/QAPA/QAPA_PPAU_t04_v_t30.csv")
  1945. cluster_t04_vs_t30_df <- read.csv("./code/APA/output/QAPA/Deseq2_cluster_t04_v_t30.csv")
  1946. QAPA_PPAU_t04_v_30 <- merge(QAPA_PPAU_t04_v_30, cluster_t04_vs_t30_df[, c("X", "log2FoldChange", "padj")],
  1947. by.x = "GeneName", by.y = "X", all.x = T)
  1948. QAPA_PPAU_t04_v_30 <- QAPA_PPAU_t04_v_30 %>% mutate(Analysis = "QAPA",
  1949. Comparison = "t04 vs t30")
  1950. QAPA_PPAU_t04_v_30 <- QAPA_PPAU_t04_v_30[,c(1, 22:27)]
  1951. df_list <- list(K_PPAU_t00_v_t04, K_PPAU_t00_v_t30, K_PPAU_t04_v_t30,
  1952. QAPA_PPAU_t00_v_04, QAPA_PPAU_t00_v_30, QAPA_PPAU_t04_v_30)
  1953. df_all <- do.call(rbind, df_list)
  1954. df_all <- df_all %>% tidyr::replace_na(list(padj = 1))
  1955. library(ggrepel)
  1956. library(tidyr)
  1957. cluster_plot <- ggplot(df_all, aes(x=dPPAU, y=log2FoldChange)) +
  1958. geom_point(alpha = 0.5, size = 1, color = ifelse((df_all$log2FoldChange > 1 & df_all$padj <0.05),
  1959. "#FF958C",
  1960. ifelse((df_all$log2FoldChange < -1 & df_all$padj <0.05), "#883677", "grey"))) +
  1961. # geom_smooth(method = lm, se = FALSE) +
  1962. stat_cor(method = "pearson", p.accuracy = 0.001, r.accuracy = 0.001, size = 3.2) +
  1963. geom_vline(xintercept = c(-20, 20), linetype = "dashed") +
  1964. geom_hline(yintercept = c(-1, 1), linetype = "dashed") +
  1965. annotate("text", x = 28, y = -6, label = "Lengthening", hjust = 0, size = 2.8) +
  1966. annotate("segment",
  1967. x = 30, xend = 85,
  1968. y = -7, yend = -7,
  1969. arrow = arrow(length = unit(0.2, "cm")),
  1970. colour = "red") +
  1971. # Arrow + label for "shorter"
  1972. annotate("text", x = -87, y = -6, label = "Shortening", hjust = 0, size = 2.8) +
  1973. annotate("segment",
  1974. x = -30, xend = -85,
  1975. y = -7, yend = -7,
  1976. arrow = arrow(length = unit(0.2, "cm")),
  1977. colour = "blue") +
  1978. theme_bw(base_size = 9) +
  1979. theme(panel.spacing.x = unit(0.56, "cm")) +
  1980. labs(y = "log2FC") +
  1981. facet_grid(factor(Analysis) ~ factor(Comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")) )
  1982. cluster_plot
  1983. pdf(paste0("./figures/SUPP_APA.pdf"), height = 5, width = 6.5)
  1984. print(cluster_plot)
  1985. dev.off()
  1986. svg(paste0("./figures/SUPP_APA.svg"), height = 5, width = 6.5)
  1987. print(cluster_plot)
  1988. dev.off()
  1989. # SFARI GENE ENRICHMENT ---------------------------------------------------
  1990. # Function to compute Fisher's exact test for pairwise comparisons
  1991. #AS term enrichment:
  1992. #Run AS code above (at gene-level):
  1993. localConseq4$condition <- paste0(localConseq4$condition_1, "vs", localConseq4$condition_2)
  1994. localConseq4_summ <- localConseq4 %>% group_by(condition, AStype, gene_id) %>%
  1995. summarise(Sum = sum(nrDiff)) %>%
  1996. ungroup()
  1997. AS <- localConseq4_summ
  1998. #All genes (up or down)
  1999. #To get all genes:
  2000. gene_lists_t00_t04_AS <- AS %>%
  2001. filter(condition == "t00vst04") %>%
  2002. group_by(AStype) %>%
  2003. filter(Sum != 0) %>%
  2004. summarise(gene_ids = list(unique(gene_id)), .groups = "drop") %>%
  2005. dplyr::select(AStype, gene_ids) %>%
  2006. tibble::deframe()
  2007. gene_lists_t00_t30_AS <- AS %>%
  2008. filter(condition == "t00vst30") %>%
  2009. group_by(AStype) %>%
  2010. filter(Sum != 0) %>%
  2011. summarise(gene_ids = list(unique(gene_id)), .groups = "drop") %>%
  2012. dplyr::select(AStype, gene_ids) %>%
  2013. tibble::deframe()
  2014. gene_lists_t04_t30_AS <- AS %>%
  2015. filter(condition == "t04vst30") %>%
  2016. group_by(AStype) %>%
  2017. filter(Sum != 0) %>%
  2018. summarise(gene_ids = list(unique(gene_id)), .groups = "drop") %>%
  2019. dplyr::select(AStype, gene_ids) %>%
  2020. tibble::deframe()
  2021. #Bg genes:
  2022. bg.AS <- unique(aSwitchList_part2$isoformFeatures$gene_id) #10,529
  2023. SFARI <- read.csv("./data/SFARI-Gene_genes_04-03-2025release_04-15-2025export.csv")
  2024. #Testing for enrichment in the each functional consequence:
  2025. SFARI.AS <- SFARI %>% filter(gene.symbol %in% bg.AS) %>% pull(gene.symbol) %>% unique()
  2026. #Run tests for t00 vs t04:
  2027. results_list_t00_t04 <- list()
  2028. i = 1
  2029. for (i in 1:9) {
  2030. setA <- SFARI.AS
  2031. setB <- gene_lists_t00_t04_AS[[i]]
  2032. result <- compute_fisher_enrich(setA, setB, bg.AS)
  2033. # Store the results in the list, and create the pair name
  2034. pair_name <- paste0("SFARI vs ", names(gene_lists_t00_t04_AS[i]))
  2035. results_list_t00_t04[[pair_name]] <- result
  2036. }
  2037. results_df_t00_t04 <- do.call(rbind, results_list_t00_t04)
  2038. results_df_t00_t04 <- data.frame(pair = names(results_list_t00_t04), results_df_t00_t04)
  2039. results_df_t00_t04$p_adjusted <- p.adjust(results_df_t00_t04$p_value, method = "bonferroni")
  2040. #Run tests for t00 vs t30:
  2041. results_list_t00_t30 <- list()
  2042. i = 1
  2043. for (i in 1:9) {
  2044. setA <- SFARI.AS
  2045. setB <- gene_lists_t00_t30_AS[[i]]
  2046. result <- compute_fisher_enrich(setA, setB, bg.AS)
  2047. # Store the results in the list, and create the pair name
  2048. pair_name <- paste0("SFARI vs ", names(gene_lists_t00_t30_AS[i]))
  2049. results_list_t00_t30[[pair_name]] <- result
  2050. }
  2051. results_df_t00_t30 <- do.call(rbind, results_list_t00_t30)
  2052. results_df_t00_t30 <- data.frame(pair = names(results_list_t00_t30), results_df_t00_t30)
  2053. results_df_t00_t30$p_adjusted <- p.adjust(results_df_t00_t30$p_value, method = "bonferroni")
  2054. #Run tests for t00 vs t04:
  2055. results_list_t04_t30 <- list()
  2056. i = 1
  2057. for (i in 1:9) {
  2058. setA <- SFARI.AS
  2059. setB <- gene_lists_t04_t30_AS[[i]]
  2060. result <- compute_fisher_enrich(setA, setB, bg.AS)
  2061. # Store the results in the list, and create the pair name
  2062. pair_name <- paste0("SFARI vs ", names(gene_lists_t04_t30_AS[i]))
  2063. results_list_t04_t30[[pair_name]] <- result
  2064. }
  2065. results_df_t04_t30 <- do.call(rbind, results_list_t04_t30)
  2066. results_df_t04_t30 <- data.frame(pair = names(results_list_t04_t30), results_df_t04_t30)
  2067. results_df_t04_t30$p_adjusted <- p.adjust(results_df_t04_t30$p_value, method = "bonferroni")
  2068. #Combined data:
  2069. results_df_t00_t04$comparison <- "t00 vs t04"
  2070. results_df_t00_t30$comparison <- "t00 vs t30"
  2071. results_df_t04_t30$comparison <- "t04 vs t30"
  2072. results_AS <- rbind(rbind(results_df_t00_t04, results_df_t00_t30), results_df_t04_t30)
  2073. results_AS <- results_AS %>%
  2074. mutate(
  2075. consequence = str_remove(pair, "^SFARI vs\\s+")
  2076. )
  2077. results_AS
  2078. ######Func conseq term enrichment:
  2079. bg.func <- bg.AS
  2080. #SFARI <- read.csv("./data/SFARI-Gene_genes_04-03-2025release_04-15-2025export.csv")
  2081. #Testing for enrichment in the each functional consequence:
  2082. SFARI.func <- SFARI.AS
  2083. #Genes in each conseq:
  2084. Conseq_genes_count <- extractConsequenceEnrichment(
  2085. aSwitchList_part2,
  2086. alpha=0.05,
  2087. dIFcutoff = 0.05,
  2088. countGenes = T,
  2089. analysisOppositeConsequence=F,
  2090. plot=F,
  2091. returnResult=TRUE,
  2092. returnSummary=F)
  2093. #Conseq_genes_count <- Conseq_genes_count %>% filter((condition_1 == "t00" & condition_2 == "t30"))
  2094. Conseq_genes_count$comparison <- paste0(Conseq_genes_count$condition_1, " vs ", Conseq_genes_count$condition_2)
  2095. Conseq_genes_count <- Conseq_genes_count %>% filter(featureCompared == "3_utr_length" |
  2096. featureCompared == "5_utr_length" |
  2097. featureCompared == "domain_length" |
  2098. featureCompared == "domains_identified" |
  2099. featureCompared == "IDR_identified" |
  2100. featureCompared == "IDR_length" |
  2101. featureCompared == "isoform_length" |
  2102. featureCompared == "NMD_status" |
  2103. featureCompared == "ORF_length"
  2104. # featureCompared == "tss" |
  2105. # featureCompared == "tts"
  2106. )
  2107. Conseq_genes_count <- Conseq_genes_count %>% group_by(comparison, gene_id) %>%
  2108. mutate(nrDiff = ifelse((switchConsequence == "3UTR is longer"|
  2109. switchConsequence == "5UTR is longer"|
  2110. switchConsequence == "Domain gain"|
  2111. switchConsequence == "Domain length gain"|
  2112. switchConsequence == "IDR gain"|
  2113. switchConsequence == "IDR length gain"|
  2114. switchConsequence == "Length gain"|
  2115. switchConsequence == "NMD sensitive"| ##This is the opposite.
  2116. switchConsequence == "ORF is longer"
  2117. # switchConsequence == "Tss more upstream"|
  2118. # switchConsequence == "Tts more downstream"
  2119. ), 1, -1)) %>% ungroup()
  2120. info <- Conseq_genes_count %>% dplyr::select(switchConsequence, featureCompared) %>% unique()
  2121. Conseq_genes_summ <- Conseq_genes_count %>% group_by(comparison, switchConsequence, gene_id) %>%
  2122. dplyr::summarize(sum = sum(nrDiff)) %>%
  2123. ungroup()
  2124. Conseq_genes_summ <- merge(Conseq_genes_summ, info[,c('switchConsequence', 'featureCompared')])
  2125. #To get all genes:
  2126. gene_lists_t00_t04 <- Conseq_genes_summ %>%
  2127. filter(comparison == "t00 vs t04") %>%
  2128. group_by(featureCompared) %>%
  2129. filter(sum != 0) %>%
  2130. summarise(gene_ids = list(unique(gene_id)), .groups = "drop") %>%
  2131. dplyr::select(featureCompared, gene_ids) %>%
  2132. tibble::deframe()
  2133. gene_lists_t00_t30 <- Conseq_genes_summ %>%
  2134. filter(comparison == "t00 vs t30") %>%
  2135. group_by(featureCompared) %>%
  2136. filter(sum != 0) %>%
  2137. summarise(gene_ids = list(unique(gene_id)), .groups = "drop") %>%
  2138. dplyr::select(featureCompared, gene_ids) %>%
  2139. tibble::deframe()
  2140. gene_lists_t04_t30 <- Conseq_genes_summ %>%
  2141. filter(comparison == "t04 vs t30") %>%
  2142. group_by(featureCompared) %>%
  2143. filter(sum != 0) %>%
  2144. summarise(gene_ids = list(unique(gene_id)), .groups = "drop") %>%
  2145. dplyr::select(featureCompared, gene_ids) %>%
  2146. tibble::deframe()
  2147. #Run tests for t00 vs t04:
  2148. results_list_t00_t04 <- list()
  2149. i = 1
  2150. for (i in 1:9) {
  2151. setA <- SFARI.func
  2152. setB <- gene_lists_t00_t04[[i]]
  2153. result <- compute_fisher_enrich(setA, setB, bg.func)
  2154. # Store the results in the list, and create the pair name
  2155. pair_name <- paste0("SFARI vs ", names(gene_lists_t00_t04[i]))
  2156. results_list_t00_t04[[pair_name]] <- result
  2157. }
  2158. results_df_t00_t04 <- do.call(rbind, results_list_t00_t04)
  2159. results_df_t00_t04 <- data.frame(pair = names(results_list_t00_t04), results_df_t00_t04)
  2160. results_df_t00_t04$p_adjusted <- p.adjust(results_df_t00_t04$p_value, method = "bonferroni")
  2161. #Run tests for t00 vs t30:
  2162. results_list_t00_t30 <- list()
  2163. i = 1
  2164. for (i in 1:9) {
  2165. setA <- SFARI.func
  2166. setB <- gene_lists_t00_t30[[i]]
  2167. result <- compute_fisher_enrich(setA, setB, bg.func)
  2168. # Store the results in the list, and create the pair name
  2169. pair_name <- paste0("SFARI vs ", names(gene_lists_t00_t30[i]))
  2170. results_list_t00_t30[[pair_name]] <- result
  2171. }
  2172. results_df_t00_t30 <- do.call(rbind, results_list_t00_t30)
  2173. results_df_t00_t30 <- data.frame(pair = names(results_list_t00_t30), results_df_t00_t30)
  2174. results_df_t00_t30$p_adjusted <- p.adjust(results_df_t00_t30$p_value, method = "bonferroni")
  2175. #Run tests for t00 vs t04:
  2176. results_list_t04_t30 <- list()
  2177. i = 1
  2178. for (i in 1:9) {
  2179. setA <- SFARI.func
  2180. setB <- gene_lists_t04_t30[[i]]
  2181. result <- compute_fisher_enrich(setA, setB, bg.func)
  2182. # Store the results in the list, and create the pair name
  2183. pair_name <- paste0("SFARI vs ", names(gene_lists_t04_t30[i]))
  2184. results_list_t04_t30[[pair_name]] <- result
  2185. }
  2186. results_df_t04_t30 <- do.call(rbind, results_list_t04_t30)
  2187. results_df_t04_t30 <- data.frame(pair = names(results_list_t04_t30), results_df_t04_t30)
  2188. results_df_t04_t30$p_adjusted <- p.adjust(results_df_t04_t30$p_value, method = "bonferroni")
  2189. #Combined data:
  2190. results_df_t00_t04$comparison <- "t00 vs t04"
  2191. results_df_t00_t30$comparison <- "t00 vs t30"
  2192. results_df_t04_t30$comparison <- "t04 vs t30"
  2193. results_func_conseq <- rbind(rbind(results_df_t00_t04, results_df_t00_t30), results_df_t04_t30)
  2194. results_func_conseq <- results_func_conseq %>%
  2195. mutate(
  2196. consequence = str_remove(pair, "^SFARI vs\\s+")
  2197. )
  2198. results_AS$conseq_type <- "Alternative Splicing"
  2199. results_func_conseq$conseq_type <- "Functional Consequence"
  2200. ###Combined results + prep:
  2201. combined_enrich <- rbind(results_AS, results_func_conseq)
  2202. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "MES",
  2203. "Multiple exon splicing")
  2204. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "3_utr_length",
  2205. "3' UTR length")
  2206. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "5_utr_length",
  2207. "5' UTR length")
  2208. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "domain_length",
  2209. "Domain length")
  2210. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "domains_identified",
  2211. "Domain gain/loss")
  2212. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "IDR_identified",
  2213. "IDR gain/loss")
  2214. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "IDR_length",
  2215. "IDR length")
  2216. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "isoform_length",
  2217. "Isoform length")
  2218. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "NMD_status",
  2219. "NMD status")
  2220. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "ORF_length",
  2221. "ORF length")
  2222. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "A3",
  2223. "Alternative 3' splice site")
  2224. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "A5",
  2225. "Alternative 5' splice site")
  2226. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "ES",
  2227. "Exon splicing")
  2228. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "IR",
  2229. "Intron splicing")
  2230. combined_enrich$consequence <- str_replace(combined_enrich$consequence, "MIC",
  2231. "Microexon splicing")
  2232. combined_enrich <- combined_enrich %>%
  2233. mutate(consequence = fct_relevel(consequence,
  2234. "Alternative 3' splice site",
  2235. "Alternative 5' splice site",
  2236. "Exon splicing",
  2237. "Microexon splicing",
  2238. "Intron splicing",
  2239. "Multiple exon splicing",
  2240. "IDR length",
  2241. "IDR gain/loss",
  2242. "Domain length",
  2243. "Domain gain/loss",
  2244. "NMD status",
  2245. "ORF length",
  2246. "Isoform length",
  2247. "3' UTR length",
  2248. "5' UTR length"))
  2249. combined_enrich$sig <- ifelse(combined_enrich$p_adjusted <= 0.05, TRUE, FALSE)
  2250. combined_enrich$comparison <- factor(combined_enrich$comparison, levels = c("t00 vs t04", "t04 vs t30", "t00 vs t30"))
  2251. ##FIg:
  2252. combined_enrich_filter <- combined_enrich %>% filter(consequence != "ATTS" &
  2253. consequence != "ATSS" &
  2254. consequence != "MEE" &
  2255. consequence != "Isoform length" &
  2256. consequence != "Domain length" &
  2257. consequence != "IDR length" &
  2258. consequence != "Alternative 3' splice site" &
  2259. consequence != "Alternative 5' splice site" &
  2260. consequence != "Multiple exon splicing" &
  2261. consequence != "ORF length")
  2262. desired_order <- c("Exon splicing",
  2263. "Microexon splicing",
  2264. "Intron splicing",
  2265. "NMD status",
  2266. "Domain gain/loss",
  2267. "IDR gain/loss",
  2268. "5' UTR length",
  2269. "3' UTR length")
  2270. combined_enrich_filter <- combined_enrich_filter %>%
  2271. mutate(consequence = factor(consequence, levels = rev(desired_order)))
  2272. #
  2273. ##Plot:
  2274. ASD_bar <- combined_enrich_filter %>%
  2275. ggplot(aes(x = odds_ratio.odds.ratio,
  2276. y = consequence,
  2277. fill = overlap)) +
  2278. geom_col(width = 0.6) +
  2279. facet_wrap(~ factor(comparison, c("t00 vs t04", "t04 vs t30", "t00 vs t30")),
  2280. scales = "free_x") +
  2281. scale_fill_gradient(name = "Gene Count", low = "lightblue", high = "darkblue") +
  2282. scale_x_continuous(limits = c(0, 2.85),
  2283. expand = expansion(mult = c(0, .1))) +
  2284. labs(title = "SFARI Gene Enrichment",
  2285. x = "Odds Ratio",
  2286. y = NULL) +
  2287. geom_vline(xintercept = 1, linetype = "dashed", colour = "black") +
  2288. geom_text(data = subset(combined_enrich_filter, sig == TRUE),
  2289. aes(x = odds_ratio.odds.ratio,
  2290. y = consequence,
  2291. label = "*"),
  2292. hjust = -0.4,
  2293. vjust = 0.75,
  2294. colour = "black",
  2295. size = 3.5) +
  2296. theme_bw(base_size = 8) +
  2297. theme(
  2298. plot.title = element_text(hjust = 0.5,
  2299. size = 8, face = "bold"),
  2300. strip.text = element_text(size = 8),
  2301. axis.text = element_text(colour = "black", size = 6.4),
  2302. axis.title.y = element_blank(),
  2303. legend.position = "none"
  2304. )
  2305. ASD_bar
  2306. legend_ASD_bar <- ggpubr::get_legend(ASD_bar +
  2307. theme( legend.position = "top",
  2308. legend.box = "horizontal",
  2309. legend.text = element_text(size = 7),
  2310. legend.key.size = unit(0.25, 'cm'),
  2311. legend.margin = margin(
  2312. t = 0,
  2313. r = 0,
  2314. b = 0,
  2315. l = 0,
  2316. unit = "cm"
  2317. ) )+
  2318. guides(fill = guide_colourbar(title.vjust = 0.8,
  2319. barwidth = 3.5))
  2320. )
  2321. combined_ASD_bar <- ggdraw() +
  2322. draw_plot(ASD_bar + theme(plot.title = element_text(vjust = 16),
  2323. axis.title.x = element_text(vjust = -6))
  2324. , x = 0, y = 0, width = 1, height = 0.934) +
  2325. draw_plot(legend_ASD_bar, x = 0, y = 0.447, width = 1, height = 1)
  2326. combined_ASD_bar
  2327. #
  2328. # GO TERMS - SWITCHING GENES ----------------------------------------------
  2329. library(gprofiler2)
  2330. run_GO_enrichment <- function(gene_list, bg, searches) {
  2331. go_result <- gost(gene_list,
  2332. organism = "hsapiens",
  2333. significant = T,
  2334. exclude_iea = F,
  2335. user_threshold = 0.05,
  2336. correction_method = "fdr",
  2337. custom_bg = bg,
  2338. sources = searches)
  2339. return(go_result)
  2340. }
  2341. #Run AS code above (at gene-level):
  2342. localConseq4$condition <- paste0(localConseq4$condition_1, "vs", localConseq4$condition_2)
  2343. localConseq4_summ <- localConseq4 %>% group_by(condition, AStype, gene_id) %>%
  2344. summarise(Sum = sum(nrDiff)) %>%
  2345. ungroup()
  2346. ###T00 vs T30
  2347. AS_t00_t30 <- localConseq4_summ %>% filter(condition == "t00vst30")
  2348. #All genes (up or down)
  2349. genes_ATTS <- AS_t00_t30 %>% filter(AStype == "ATTS" & Sum != 0) %>% pull(gene_id)
  2350. genes_MIC <- AS_t00_t30 %>% filter(AStype == "MIC" & Sum != 0) %>% pull(gene_id)
  2351. genes_A3 <- AS_t00_t30 %>% filter(AStype == "A3" & Sum != 0) %>% pull(gene_id)
  2352. genes_A5 <- AS_t00_t30 %>% filter(AStype == "A5" & Sum != 0) %>% pull(gene_id)
  2353. genes_ATSS <- AS_t00_t30 %>% filter(AStype == "ATSS" & Sum != 0) %>% pull(gene_id)
  2354. genes_ES <- AS_t00_t30 %>% filter(AStype == "ES" & Sum != 0) %>% pull(gene_id)
  2355. genes_MES <- AS_t00_t30 %>% filter(AStype == "MES" & Sum != 0) %>% pull(gene_id)
  2356. genes_IR <- AS_t00_t30 %>% filter(AStype == "IR" & Sum != 0) %>% pull(gene_id)
  2357. #Bg genes:
  2358. all_AS_genes <- unique(aSwitchList_part2$isoformFeatures$gene_id) #10529
  2359. #GO terms for all AS results
  2360. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  2361. gene_lists <- list(genes_ATTS = genes_ATTS,
  2362. genes_MIC = genes_MIC,
  2363. genes_A3 = genes_A3,
  2364. genes_A5 = genes_A5,
  2365. genes_ATSS = genes_ATSS,
  2366. genes_ES = genes_ES,
  2367. genes_MES = genes_MES,
  2368. genes_IR = genes_IR)
  2369. # Initialize an empty list to store results
  2370. enrichment_results <- list()
  2371. i = 1
  2372. # Loop through each gene list and perform GO enrichment
  2373. for (i in seq_along(gene_lists)) {
  2374. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  2375. bg = all_AS_genes,
  2376. searches = searches)
  2377. }
  2378. #
  2379. go_results_IR <- enrichment_results$genes_IR$result
  2380. go_results_IR$query <- "IR GO Terms - t00 vs t30"
  2381. # RP_IR <- gene_lists[["genes_IR"]][grepl("^RP", gene_lists[["genes_IR"]])]
  2382. go_results_IR <- go_results_IR %>%
  2383. group_by(source) %>%
  2384. arrange(p_value) %>%
  2385. dplyr::slice(1:5) %>%
  2386. ungroup()
  2387. go_results_IR$term_name_wrapped <- str_wrap(go_results_IR$term_name, width = 20)
  2388. # Create a dot plot for each gene list and GO term
  2389. IR_go <- ggplot(go_results_IR, aes(x = reorder(term_name_wrapped, -p_value), y = -log10(p_value), fill = intersection_size)) +
  2390. geom_col(width = c(0.6*1, 0.6*1.1, 0.6*1.1, 0.6*1.1, 0.6*1.1, 0.6*1.1, 0.6*1)) +
  2391. scale_y_continuous(expand = expansion(mult = c(0, .1))) +
  2392. labs(title = "IR GO Terms - t00 vs t30",
  2393. y = expression(paste(-log[10], "(adjusted ", italic("P"), ")")) ) +
  2394. theme_bw(base_size = 8) +
  2395. coord_flip() +
  2396. scale_fill_gradient(name = "Gene Count", low = "lightblue", high = "darkblue") +
  2397. theme(plot.title = element_text(hjust = 0.5, size = 8, colour = "black", face = "bold"),
  2398. axis.title.y = element_blank(),
  2399. axis.text = element_text(size = 6.4, colour = "black"),
  2400. axis.title = element_text(size = 8, colour = "black"),
  2401. legend.position = "bottom",
  2402. strip.text = element_text(size = 6.4, colour = "black"),
  2403. # plot.margin = margin(t = 6, b = 0, l = 16, r = 6, unit = "pt"),
  2404. legend.margin = margin(t = -5, b = 0, l = -25, r = 0, unit = "pt"),
  2405. legend.key.size = unit(0.25, 'cm')
  2406. ) +
  2407. facet_wrap(~source,
  2408. scales = "free_y",
  2409. dir = "v",
  2410. strip.position = "right",
  2411. ncol = 1) + # Facet by source if applicable
  2412. force_panelsizes(row = c(1.25, 4.5, 1.25))
  2413. IR_go
  2414. # EXPORT FIG 4 ------------------------------------------------------------
  2415. library(Cairo)
  2416. Figure_4 <- ggdraw() +
  2417. draw_plot(bars_by_tr, x = 0, y = 0.78, width = 0.5, height = 0.22) +
  2418. draw_plot(final_plot, x = 0.5, y = 0.78, width = 0.5, height = 0.22) +
  2419. draw_plot(testp, x = 0, y = 0.35, width = 0.5, height = 0.43) +
  2420. draw_plot(combined_ASD_bar, x = 0.5, y = 0.38, width = 0.5, height = 0.3815) +
  2421. draw_plot(IR_go, x = 0.01, y = 0, width = 0.35, height = 0.35) +
  2422. draw_plot(AGO1, x = 0.35, y = 0, width = 0.65, height = 0.35) +
  2423. draw_plot_label(label = c("A", "B", "C", "D", "E", "F"),
  2424. size = 12,
  2425. x = c(0, 0.5, 0, 0.5, 0, 0.355),
  2426. y = c(1, 1, 0.78, 0.78, 0.35, 0.35))
  2427. Figure_4
  2428. #
  2429. CairoPDF(paste0("./figures/Fig_4.pdf"), height = 8, width = 6.5)
  2430. print(Figure_4)
  2431. dev.off()
  2432. svg(paste0("./figures/Fig_4.svg"), height = 8, width = 6.5)
  2433. print(Figure_4)
  2434. dev.off()
  2435. # SUPP. FIGS & TABLES ------------------------------------------------------
  2436. # GO TERMS - SWITCHING GENES ----------------------------------------------
  2437. library(gprofiler2)
  2438. run_GO_enrichment <- function(gene_list, bg, searches) {
  2439. # Convert gene symbols to Entrez IDs (if necessary)
  2440. # gene_ids <- bitr(gene_list, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = OrgDb)
  2441. go_result <- gost(gene_list,
  2442. organism = "hsapiens",
  2443. significant = T,
  2444. exclude_iea = F,
  2445. user_threshold = 0.05,
  2446. correction_method = "fdr",
  2447. custom_bg = bg,
  2448. sources = searches)
  2449. return(go_result)
  2450. }
  2451. #Run AS code above (at gene-level):
  2452. localConseq4$condition <- paste0(localConseq4$condition_1, "vs", localConseq4$condition_2)
  2453. localConseq4_summ <- localConseq4 %>% group_by(condition, AStype, gene_id) %>%
  2454. summarise(Sum = sum(nrDiff)) %>%
  2455. ungroup()
  2456. ###T00 vs T30
  2457. AS_t00_t30 <- localConseq4_summ %>% filter(condition == "t00vst30")
  2458. #All genes (up or down)
  2459. genes_ATTS <- AS_t00_t30 %>% filter(AStype == "ATTS" & Sum != 0) %>% pull(gene_id)
  2460. genes_MIC <- AS_t00_t30 %>% filter(AStype == "MIC" & Sum != 0) %>% pull(gene_id)
  2461. genes_A3 <- AS_t00_t30 %>% filter(AStype == "A3" & Sum != 0) %>% pull(gene_id)
  2462. genes_A5 <- AS_t00_t30 %>% filter(AStype == "A5" & Sum != 0) %>% pull(gene_id)
  2463. genes_ATSS <- AS_t00_t30 %>% filter(AStype == "ATSS" & Sum != 0) %>% pull(gene_id)
  2464. genes_ES <- AS_t00_t30 %>% filter(AStype == "ES" & Sum != 0) %>% pull(gene_id)
  2465. genes_MES <- AS_t00_t30 %>% filter(AStype == "MES" & Sum != 0) %>% pull(gene_id)
  2466. genes_IR <- AS_t00_t30 %>% filter(AStype == "IR" & Sum != 0) %>% pull(gene_id)
  2467. #Bg genes:
  2468. all_AS_genes <- unique(aSwitchList_part2$isoformFeatures$gene_id) #10529
  2469. #GO terms for all AS results
  2470. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  2471. gene_lists <- list(genes_ATTS = genes_ATTS,
  2472. genes_MIC = genes_MIC,
  2473. genes_A3 = genes_A3,
  2474. genes_A5 = genes_A5,
  2475. genes_ATSS = genes_ATSS,
  2476. genes_ES = genes_ES,
  2477. genes_MES = genes_MES,
  2478. genes_IR = genes_IR)
  2479. # Initialize an empty list to store results
  2480. enrichment_results <- list()
  2481. i = 1
  2482. # Loop through each gene list and perform GO enrichment
  2483. for (i in seq_along(gene_lists)) {
  2484. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  2485. bg = all_AS_genes,
  2486. searches = searches)
  2487. }
  2488. #
  2489. ###T00 vs T04
  2490. AS_t00_t04 <- localConseq4_summ %>% filter(condition == "t00vst04")
  2491. #All genes (up or down)
  2492. genes_ATTS <- AS_t00_t04 %>% filter(AStype == "ATTS" & Sum != 0) %>% pull(gene_id)
  2493. genes_MIC <- AS_t00_t04 %>% filter(AStype == "MIC" & Sum != 0) %>% pull(gene_id)
  2494. genes_A3 <- AS_t00_t04 %>% filter(AStype == "A3" & Sum != 0) %>% pull(gene_id)
  2495. genes_A5 <- AS_t00_t04 %>% filter(AStype == "A5" & Sum != 0) %>% pull(gene_id)
  2496. genes_ATSS <- AS_t00_t04 %>% filter(AStype == "ATSS" & Sum != 0) %>% pull(gene_id)
  2497. genes_ES <- AS_t00_t04 %>% filter(AStype == "ES" & Sum != 0) %>% pull(gene_id)
  2498. genes_MES <- AS_t00_t04 %>% filter(AStype == "MES" & Sum != 0) %>% pull(gene_id)
  2499. genes_IR <- AS_t00_t04 %>% filter(AStype == "IR" & Sum != 0) %>% pull(gene_id)
  2500. #Bg genes:
  2501. all_AS_genes
  2502. #GO terms for all AS results
  2503. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  2504. gene_lists <- list(genes_ATTS = genes_ATTS,
  2505. genes_MIC = genes_MIC,
  2506. genes_A3 = genes_A3,
  2507. genes_A5 = genes_A5,
  2508. genes_ATSS = genes_ATSS,
  2509. genes_ES = genes_ES,
  2510. genes_MES = genes_MES,
  2511. genes_IR = genes_IR)
  2512. # Initialize an empty list to store results
  2513. enrichment_results <- list()
  2514. i = 1
  2515. # Loop through each gene list and perform GO enrichment
  2516. for (i in seq_along(gene_lists)) {
  2517. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  2518. bg = all_AS_genes,
  2519. searches = searches)
  2520. }
  2521. ###T04 vs T30
  2522. AS_t04_t30 <- localConseq4_summ %>% filter(condition == "t04vst30")
  2523. #All genes (up or down)
  2524. genes_ATTS <- AS_t04_t30 %>% filter(AStype == "ATTS" & Sum != 0) %>% pull(gene_id)
  2525. genes_MIC <- AS_t04_t30 %>% filter(AStype == "MIC" & Sum != 0) %>% pull(gene_id)
  2526. genes_A3 <- AS_t04_t30 %>% filter(AStype == "A3" & Sum != 0) %>% pull(gene_id)
  2527. genes_A5 <- AS_t04_t30 %>% filter(AStype == "A5" & Sum != 0) %>% pull(gene_id)
  2528. genes_ATSS <- AS_t04_t30 %>% filter(AStype == "ATSS" & Sum != 0) %>% pull(gene_id)
  2529. genes_ES <- AS_t04_t30 %>% filter(AStype == "ES" & Sum != 0) %>% pull(gene_id)
  2530. genes_MES <- AS_t04_t30 %>% filter(AStype == "MES" & Sum != 0) %>% pull(gene_id)
  2531. genes_IR <- AS_t04_t30 %>% filter(AStype == "IR" & Sum != 0) %>% pull(gene_id)
  2532. #Bg genes:
  2533. all_AS_genes
  2534. #GO terms for all AS results
  2535. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  2536. gene_lists <- list(genes_ATTS = genes_ATTS,
  2537. genes_MIC = genes_MIC,
  2538. genes_A3 = genes_A3,
  2539. genes_A5 = genes_A5,
  2540. genes_ATSS = genes_ATSS,
  2541. genes_ES = genes_ES,
  2542. genes_MES = genes_MES,
  2543. genes_IR = genes_IR)
  2544. # Initialize an empty list to store results
  2545. enrichment_results <- list()
  2546. i = 1
  2547. # Loop through each gene list and perform GO enrichment
  2548. for (i in seq_along(gene_lists)) {
  2549. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  2550. bg = all_AS_genes,
  2551. searches = searches)
  2552. }
  2553. # GO TERMS - FUNC CONSEQ --------------------------------------------------
  2554. ###Do for func. conseq:
  2555. Conseq_genes <- extractConsequenceEnrichment(
  2556. aSwitchList_part2,
  2557. alpha=0.05,
  2558. dIFcutoff = 0.05,
  2559. countGenes = T,
  2560. analysisOppositeConsequence=F,
  2561. plot=F,
  2562. returnResult=TRUE,
  2563. returnSummary=T)
  2564. ##T00 vs T30:
  2565. Conseq_genes_count <- extractConsequenceEnrichment(
  2566. aSwitchList_part2,
  2567. alpha=0.05,
  2568. dIFcutoff = 0.05,
  2569. countGenes = T,
  2570. analysisOppositeConsequence=F,
  2571. plot=F,
  2572. returnResult=TRUE,
  2573. returnSummary=F)
  2574. Conseq_genes_count <- Conseq_genes_count %>% filter((condition_1 == "t00" & condition_2 == "t30"))
  2575. Conseq_genes_count$nrDiff <- ifelse((Conseq_genes_count$switchConsequence == "3UTR is longer"|
  2576. Conseq_genes_count$switchConsequence == "5UTR is longer"|
  2577. Conseq_genes_count$switchConsequence == "Domain gain"|
  2578. Conseq_genes_count$switchConsequence == "Domain length gain"|
  2579. Conseq_genes_count$switchConsequence == "IDR gain"|
  2580. Conseq_genes_count$switchConsequence == "IDR length gain"|
  2581. Conseq_genes_count$switchConsequence == "Length gain"|
  2582. Conseq_genes_count$switchConsequence == "NMD sensitive"| ##This is the opposite.
  2583. Conseq_genes_count$switchConsequence == "ORF is longer"|
  2584. Conseq_genes_count$switchConsequence == "Tss more upstream"|
  2585. Conseq_genes_count$switchConsequence == "Tts more downstream"), 1, -1)
  2586. Conseq_genes_summ <- Conseq_genes_count %>%
  2587. group_by(switchConsequence, gene_id) %>%
  2588. summarize(sum = sum(nrDiff)) %>%
  2589. ungroup()
  2590. summary_genes <- Conseq_genes_summ %>%
  2591. group_by(switchConsequence) %>%
  2592. filter(sum != 0)
  2593. #
  2594. #I can just take the genes that match the ones above (b/c all others are 0)
  2595. genes_3UTR <- Conseq_genes_summ %>% filter(switchConsequence == "3UTR is longer" |
  2596. switchConsequence == "3UTR is shorter") %>% pull(gene_id)
  2597. genes_5UTR <- Conseq_genes_summ %>% filter(switchConsequence == "5UTR is longer" |
  2598. switchConsequence == "5UTR is shorter") %>% pull(gene_id)
  2599. genes_domain_number <- Conseq_genes_summ %>% filter(switchConsequence == "Domain gain" |
  2600. switchConsequence == "Domain loss") %>% pull(gene_id)
  2601. genes_domain_length <- Conseq_genes_summ %>% filter(switchConsequence == "Domain length gain" |
  2602. switchConsequence == "Domain length loss") %>% pull(gene_id)
  2603. genes_IDR_number <- Conseq_genes_summ %>% filter(switchConsequence == "IDR gain" |
  2604. switchConsequence == "IDR loss") %>% pull(gene_id)
  2605. genes_IDR_length <- Conseq_genes_summ %>% filter(switchConsequence == "IDR length gain" |
  2606. switchConsequence == "IDR length loss") %>% pull(gene_id)
  2607. genes_length <- Conseq_genes_summ %>% filter(switchConsequence == "Length gain" |
  2608. switchConsequence == "Length loss") %>% pull(gene_id)
  2609. genes_NMD <- Conseq_genes_summ %>% filter(switchConsequence == "NMD sensitive" |
  2610. switchConsequence == "NMD insensitive") %>% pull(gene_id)
  2611. genes_ORF_length <- Conseq_genes_summ %>% filter(switchConsequence == "ORF is longer" |
  2612. switchConsequence == "ORF is shorter") %>% pull(gene_id)
  2613. genes_TSS_change <- Conseq_genes_summ %>% filter(switchConsequence == "Tss more upstream" |
  2614. switchConsequence == "Tss more downstream") %>% pull(gene_id)
  2615. genes_TTS_change <- Conseq_genes_summ %>% filter(switchConsequence == "Tts more downstream" |
  2616. switchConsequence == "Tts more upstream") %>% pull(gene_id)
  2617. # Your gene lists in a named list
  2618. gene_lists <- list(
  2619. genes_3UTR = genes_3UTR,
  2620. genes_5UTR = genes_5UTR,
  2621. genes_domain_number = genes_domain_number,
  2622. genes_domain_length = genes_domain_length,
  2623. genes_IDR_number = genes_IDR_number,
  2624. genes_IDR_length = genes_IDR_length,
  2625. genes_length = genes_length,
  2626. genes_NMD = genes_NMD,
  2627. genes_ORF_length = genes_ORF_length,
  2628. genes_TSS_change = genes_TSS_change,
  2629. genes_TTS_change = genes_TTS_change)
  2630. #GO terms for all AS results
  2631. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  2632. bg_genes <- unique(aSwitchList_part2$isoformFeatures$gene_id)
  2633. # Initialize an empty list to store results
  2634. enrichment_results <- list()
  2635. i = 1
  2636. # Loop through each gene list and perform GO enrichment
  2637. for (i in seq_along(gene_lists)) {
  2638. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  2639. bg = bg_genes,
  2640. searches = searches)
  2641. }
  2642. #go_results_IDR_number <- enrichment_results$genes_IDR_number$result
  2643. t00_t30 <- enrichment_results
  2644. ##T00 vs T04:
  2645. Conseq_genes_count <- extractConsequenceEnrichment(
  2646. aSwitchList_part2,
  2647. alpha=0.05,
  2648. dIFcutoff = 0.05,
  2649. countGenes = T,
  2650. analysisOppositeConsequence=F,
  2651. plot=F,
  2652. returnResult=TRUE,
  2653. returnSummary=F)
  2654. Conseq_genes_count <- Conseq_genes_count %>% filter((condition_1 == "t00" & condition_2 == "t04"))
  2655. Conseq_genes_count$nrDiff <- ifelse((Conseq_genes_count$switchConsequence == "3UTR is longer"|
  2656. Conseq_genes_count$switchConsequence == "5UTR is longer"|
  2657. Conseq_genes_count$switchConsequence == "Domain gain"|
  2658. Conseq_genes_count$switchConsequence == "Domain length gain"|
  2659. Conseq_genes_count$switchConsequence == "IDR gain"|
  2660. Conseq_genes_count$switchConsequence == "IDR length gain"|
  2661. Conseq_genes_count$switchConsequence == "Length gain"|
  2662. Conseq_genes_count$switchConsequence == "NMD sensitive"| ##This is the opposite.
  2663. Conseq_genes_count$switchConsequence == "ORF is longer"|
  2664. Conseq_genes_count$switchConsequence == "Tss more upstream"|
  2665. Conseq_genes_count$switchConsequence == "Tts more downstream"), 1, -1)
  2666. Conseq_genes_summ <- Conseq_genes_count %>%
  2667. group_by(switchConsequence, gene_id) %>%
  2668. summarize(sum = sum(nrDiff)) %>%
  2669. ungroup()
  2670. summary_genes <- Conseq_genes_summ %>%
  2671. group_by(switchConsequence) %>%
  2672. filter(sum != 0)
  2673. #I can just take the genes that match the ones above (b/c all others are 0)
  2674. genes_3UTR <- Conseq_genes_summ %>% filter(switchConsequence == "3UTR is longer" |
  2675. switchConsequence == "3UTR is shorter") %>% pull(gene_id)
  2676. genes_5UTR <- Conseq_genes_summ %>% filter(switchConsequence == "5UTR is longer" |
  2677. switchConsequence == "5UTR is shorter") %>% pull(gene_id)
  2678. genes_domain_number <- Conseq_genes_summ %>% filter(switchConsequence == "Domain gain" |
  2679. switchConsequence == "Domain loss") %>% pull(gene_id)
  2680. genes_domain_length <- Conseq_genes_summ %>% filter(switchConsequence == "Domain length gain" |
  2681. switchConsequence == "Domain length loss") %>% pull(gene_id)
  2682. genes_IDR_number <- Conseq_genes_summ %>% filter(switchConsequence == "IDR gain" |
  2683. switchConsequence == "IDR loss") %>% pull(gene_id)
  2684. genes_IDR_length <- Conseq_genes_summ %>% filter(switchConsequence == "IDR length gain" |
  2685. switchConsequence == "IDR length loss") %>% pull(gene_id)
  2686. genes_length <- Conseq_genes_summ %>% filter(switchConsequence == "Length gain" |
  2687. switchConsequence == "Length loss") %>% pull(gene_id)
  2688. genes_NMD <- Conseq_genes_summ %>% filter(switchConsequence == "NMD sensitive" |
  2689. switchConsequence == "NMD insensitive") %>% pull(gene_id)
  2690. genes_ORF_length <- Conseq_genes_summ %>% filter(switchConsequence == "ORF is longer" |
  2691. switchConsequence == "ORF is shorter") %>% pull(gene_id)
  2692. genes_TSS_change <- Conseq_genes_summ %>% filter(switchConsequence == "Tss more upstream" |
  2693. switchConsequence == "Tss more downstream") %>% pull(gene_id)
  2694. genes_TTS_change <- Conseq_genes_summ %>% filter(switchConsequence == "Tts more downstream" |
  2695. switchConsequence == "Tts more upstream") %>% pull(gene_id)
  2696. # Your gene lists in a named list
  2697. gene_lists <- list(
  2698. genes_3UTR = genes_3UTR,
  2699. genes_5UTR = genes_5UTR,
  2700. genes_domain_number = genes_domain_number,
  2701. genes_domain_length = genes_domain_length,
  2702. genes_IDR_number = genes_IDR_number,
  2703. genes_IDR_length = genes_IDR_length,
  2704. genes_length = genes_length,
  2705. genes_NMD = genes_NMD,
  2706. genes_ORF_length = genes_ORF_length,
  2707. genes_TSS_change = genes_TSS_change,
  2708. genes_TTS_change = genes_TTS_change)
  2709. #GO terms for all AS results
  2710. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  2711. bg_genes
  2712. # Initialize an empty list to store results
  2713. enrichment_results <- list()
  2714. i = 1
  2715. # Loop through each gene list and perform GO enrichment
  2716. for (i in seq_along(gene_lists)) {
  2717. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  2718. bg = bg_genes,
  2719. searches = searches)
  2720. }
  2721. t00_t04 <- enrichment_results
  2722. ##T04 vs T30:
  2723. Conseq_genes_count <- extractConsequenceEnrichment(
  2724. aSwitchList_part2,
  2725. alpha=0.05,
  2726. dIFcutoff = 0.05,
  2727. countGenes = T,
  2728. analysisOppositeConsequence=F,
  2729. plot=F,
  2730. returnResult=TRUE,
  2731. returnSummary=F)
  2732. Conseq_genes_count <- Conseq_genes_count %>% filter((condition_1 == "t04" & condition_2 == "t30"))
  2733. Conseq_genes_count$nrDiff <- ifelse((Conseq_genes_count$switchConsequence == "3UTR is longer"|
  2734. Conseq_genes_count$switchConsequence == "5UTR is longer"|
  2735. Conseq_genes_count$switchConsequence == "Domain gain"|
  2736. Conseq_genes_count$switchConsequence == "Domain length gain"|
  2737. Conseq_genes_count$switchConsequence == "IDR gain"|
  2738. Conseq_genes_count$switchConsequence == "IDR length gain"|
  2739. Conseq_genes_count$switchConsequence == "Length gain"|
  2740. Conseq_genes_count$switchConsequence == "NMD sensitive"| ##This is the opposite.
  2741. Conseq_genes_count$switchConsequence == "ORF is longer"|
  2742. Conseq_genes_count$switchConsequence == "Tss more upstream"|
  2743. Conseq_genes_count$switchConsequence == "Tts more downstream"), 1, -1)
  2744. Conseq_genes_summ <- Conseq_genes_count %>%
  2745. group_by(switchConsequence, gene_id) %>%
  2746. summarize(sum = sum(nrDiff)) %>%
  2747. ungroup()
  2748. summary_genes <- Conseq_genes_summ %>%
  2749. group_by(switchConsequence) %>%
  2750. filter(sum != 0)
  2751. #I can just take the genes that match the ones above (b/c all others are 0)
  2752. genes_3UTR <- Conseq_genes_summ %>% filter(switchConsequence == "3UTR is longer" |
  2753. switchConsequence == "3UTR is shorter") %>% pull(gene_id)
  2754. genes_5UTR <- Conseq_genes_summ %>% filter(switchConsequence == "5UTR is longer" |
  2755. switchConsequence == "5UTR is shorter") %>% pull(gene_id)
  2756. genes_domain_number <- Conseq_genes_summ %>% filter(switchConsequence == "Domain gain" |
  2757. switchConsequence == "Domain loss") %>% pull(gene_id)
  2758. genes_domain_length <- Conseq_genes_summ %>% filter(switchConsequence == "Domain length gain" |
  2759. switchConsequence == "Domain length loss") %>% pull(gene_id)
  2760. genes_IDR_number <- Conseq_genes_summ %>% filter(switchConsequence == "IDR gain" |
  2761. switchConsequence == "IDR loss") %>% pull(gene_id)
  2762. genes_IDR_length <- Conseq_genes_summ %>% filter(switchConsequence == "IDR length gain" |
  2763. switchConsequence == "IDR length loss") %>% pull(gene_id)
  2764. genes_length <- Conseq_genes_summ %>% filter(switchConsequence == "Length gain" |
  2765. switchConsequence == "Length loss") %>% pull(gene_id)
  2766. genes_NMD <- Conseq_genes_summ %>% filter(switchConsequence == "NMD sensitive" |
  2767. switchConsequence == "NMD insensitive") %>% pull(gene_id)
  2768. genes_ORF_length <- Conseq_genes_summ %>% filter(switchConsequence == "ORF is longer" |
  2769. switchConsequence == "ORF is shorter") %>% pull(gene_id)
  2770. genes_TSS_change <- Conseq_genes_summ %>% filter(switchConsequence == "Tss more upstream" |
  2771. switchConsequence == "Tss more downstream") %>% pull(gene_id)
  2772. genes_TTS_change <- Conseq_genes_summ %>% filter(switchConsequence == "Tts more downstream" |
  2773. switchConsequence == "Tts more upstream") %>% pull(gene_id)
  2774. # Your gene lists in a named list
  2775. gene_lists <- list(
  2776. genes_3UTR = genes_3UTR,
  2777. genes_5UTR = genes_5UTR,
  2778. genes_domain_number = genes_domain_number,
  2779. genes_domain_length = genes_domain_length,
  2780. genes_IDR_number = genes_IDR_number,
  2781. genes_IDR_length = genes_IDR_length,
  2782. genes_length = genes_length,
  2783. genes_NMD = genes_NMD,
  2784. genes_ORF_length = genes_ORF_length,
  2785. genes_TSS_change = genes_TSS_change,
  2786. genes_TTS_change = genes_TTS_change)
  2787. #GO terms for all AS results
  2788. searches <- c("GO:BP", "GO:MF", "GO:CC", "MIRNA")
  2789. bg_genes
  2790. # Initialize an empty list to store results
  2791. enrichment_results <- list()
  2792. i = 1
  2793. # Loop through each gene list and perform GO enrichment
  2794. for (i in seq_along(gene_lists)) {
  2795. enrichment_results[[names(gene_lists)[i]]] <- run_GO_enrichment(gene_lists[[i]],
  2796. bg = bg_genes,
  2797. searches = searches)
  2798. }
  2799. t04_t30 <- enrichment_results

Figures.R at commit 080e8a9, under MIT · at the source

Overview

Authors: Nuo Xu1,2, Katherine M Rynard3, Elizabeth Radley4, Ai Tian5, Maahil Arshad3,6, Chaoying Long3,5, Jimmy Ly7,8, Hua Luo3, Ellie Hogan1, Maria Eleni Fafouti1,2, Melanie Davie3, Fatima Naimi5, Yun Li3,9, John A Calarco10, Brett Trost3,6,11, Julien Muffat3,5, Hyun O Lee4, Howard D Lipshitz3, Craig A Smibert3,4, Shreejoy J Tripathy1,2,12,13
13 affiliations
  1. Krembil Centre for Neuroinformatics, Centre for Addiction and Mental Health, Toronto, ON Canada
  2. Department of Physiology, University of Toronto, Toronto, ON Canada
  3. Department of Molecular Genetics, University of Toronto, Toronto, ON Canada
  4. Department of Biochemistry, University of Toronto, Toronto, ON Canada
  5. Program in Neurosciences and Mental Health, The Hospital for Sick Children, Toronto, ON Canada
  6. Program in Molecular Medicine, The Hospital for Sick Children, Toronto, ON Canada
  7. Whitehead Institute for Biomedical Research, Cambridge, MA USA
  8. Department of Biology, Massachusetts Institute of Technology, Cambridge, MA USA
  9. Program in Developmental, Stem Cell & Cancer Biology, The Hospital for Sick Children, Toronto, ON Canada
  10. Department of Cell and Systems Biology, University of Toronto, Toronto, ON Canada
  11. Program in Genetics & Genome Biology, The Hospital for Sick Children, Toronto, ON Canada
  12. Department of Psychiatry, University of Toronto, Toronto, ON Canada
  13. Institute of Medical Sciences, University of Toronto, Toronto, ON Canada
Journal: Nature communications, volume 17, issue 1, article 9363
Dates: received 12 February 2026; accepted 4 August 2026; published online 19 August 2026
Type: Research article · Language: English
License: CC BY-NC-ND
Identifiers: DOI 10.1038/s41467-026-76675-1 · PMID 42680762 · PMCID PMC13534637 · OpenAlex W4417497197
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: genetics / omics (modality), human (organism), autism (population), developmental (subfield)
Methods: Spectral & time-frequency, Statistics, Evoked potentials, Connectivity, fMRI & imaging
Keywords: Development of the nervous system, Computational biology and bioinformatics, Gene expression analysis, Proteomic analysis, Autism spectrum disorders
MeSH: Cell Differentiation*, Neurons*, Proteogenomics*, Alternative Splicing, Autistic Disorder, Exons, Humans, Induced Pluripotent Stem Cells, Neurodevelopment, Neurogenesis, Protein Isoforms, RNA, Messenger (* major topic)
Topic: RNA Research and Splicing (Molecular Biology, Biochemistry, Genetics and Molecular Biology), according to OpenAlex
Funding: Gouvernement du Canada | Natural Sciences and Engineering Research Council of Canada; Krembil Foundation; Gouvernement du Canada | Canadian Institutes of Health Research
Citations: not cited yet (Europe PMC); 87 references in the paper

Abstract

The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repositories

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

gandallab/Dev_Brain_IsoSeq

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 934d23cf3ecd0a412359d02578a668a3d439ba2f, 30 May 2024
Languages: Quarto (26), JavaScript (9), Jupyter (7), R (4), Python (1), Shell (1)
Size: 793 files, 48 scripts
Software Heritage: not archived
Found in: “Data availability”
Holds: README, documentation, 33 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration
Tools: tidyverse (28 files), data.table (7 files), cowplot (5 files), edgeR (5 files), WGCNA (5 files), BEDTools (4 files), ggplot2 (4 files), Seurat (4 files), NumPy (3 files), pandas (3 files), patchwork (3 files), DESeq2 (2 files), limma (2 files), Matplotlib (2 files), scikit-learn (2 files), igraph (1 file), Monocle 3 (1 file), pheatmap (1 file), reshape2 (1 file), SAMtools (1 file), UMAP (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
49 files

nuoxuxu/SFARI

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 080e8a9cac3a1a16d9a6aa7e0b90028c46b81b3a, 29 May 2026
Languages: R (95), Python (86), Shell (47), Jupyter (8), Quarto (6)
Size: 322 files, 242 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file, environment (environment.yml, pyproject.toml, setup.py, uv.lock, bin/src/setup.py, subworkflows/local/classify_and_count/environment.yml, subworkflows/local/merge_and_collapse/environment.yml, subworkflows/local/ORFanage/environment.yml, subworkflows/local/proteoform_classification/environment.yml, subworkflows/local/proteomic/environment.yml, modules/nf-core/salmon/index/environment.yml, modules/nf-core/salmon/quant/environment.yml), 16 notebooks
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: tidyverse (92 files), ggplot2 (43 files), NumPy (21 files), patchwork (18 files), Salmon (18 files), Matplotlib (16 files), pandas (16 files), edgeR (7 files), ggpubr (7 files), SciPy (6 files), seaborn (6 files), Biopython (5 files), cowplot (5 files), pheatmap (5 files), DESeq2 (4 files), emmeans (3 files), reshape2 (3 files), reticulate (3 files), BEDTools (2 files), data.table (2 files), h5py (2 files), anndata (1 file), glmmTMB (1 file), NetworkX (1 file), pysam (1 file), rstatix (1 file), SAMtools (1 file), scikit-learn (1 file), STAR (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
244 files

Zenodo 16897532

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: the references
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
At the source:

Code availability statement

The paper has a code availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41467-026-76675-1.

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:

  • 3 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 290 scripts, each with its path and the digest of its content;
  • 40 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

Datasets cited

Code and data availability statement

The paper has a code and data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41467-026-76675-1.

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, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 20 authors, 5 keywords, 12 MeSH terms, 3 funders, 86 references.

Cite

This paper

Xu, N., Rynard, K. M., Radley, E., Tian, A., Arshad, M., Long, C., Ly, J., Luo, H., Hogan, E., Fafouti, M. E., Davie, M., Naimi, F., Li, Y., Calarco, J. A., Trost, B., Muffat, J., Lee, H. O., Lipshitz, H. D., Smibert, C. A., & Tripathy, S. J. (2026). Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms. Nature communications, 17(1), 9363. https://doi.org/10.1038/s41467-026-76675-1

BibTeX

@article{xu2026long,
author = {Xu, Nuo and Rynard, Katherine M and Radley, Elizabeth and Tian, Ai and Arshad, Maahil and Long, Chaoying and Ly, Jimmy and Luo, Hua and Hogan, Ellie and Fafouti, Maria Eleni and Davie, Melanie and Naimi, Fatima and Li, Yun and Calarco, John A and Trost, Brett and Muffat, Julien and Lee, Hyun O and Lipshitz, Howard D and Smibert, Craig A and Tripathy, Shreejoy J},
title = {{Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms}},
journal = {Nature communications},
year = {2026},
month = aug,
volume = {17},
number = {1},
pages = {9363},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/s41467-026-76675-1},
url = {https://doi.org/10.1038/s41467-026-76675-1},
pmid = {42680762},
pmcid = {PMC13534637}
}

RIS

TY - JOUR
AU - Xu, Nuo
AU - Rynard, Katherine M
AU - Radley, Elizabeth
AU - Tian, Ai
AU - Arshad, Maahil
AU - Long, Chaoying
AU - Ly, Jimmy
AU - Luo, Hua
AU - Hogan, Ellie
AU - Fafouti, Maria Eleni
AU - Davie, Melanie
AU - Naimi, Fatima
AU - Li, Yun
AU - Calarco, John A
AU - Trost, Brett
AU - Muffat, Julien
AU - Lee, Hyun O
AU - Lipshitz, Howard D
AU - Smibert, Craig A
AU - Tripathy, Shreejoy J
TI - Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/08/19
VL - 17
IS - 1
SP - 9363
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/s41467-026-76675-1
UR - https://doi.org/10.1038/s41467-026-76675-1
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41467-026-76675-1",
"type": "article-journal",
"title": "Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms",
"container-title": "Nature communications",
"author": [
{
"family": "Xu",
"given": "Nuo"
},
{
"family": "Rynard",
"given": "Katherine M"
},
{
"family": "Radley",
"given": "Elizabeth"
},
{
"family": "Tian",
"given": "Ai"
},
{
"family": "Arshad",
"given": "Maahil"
},
{
"family": "Long",
"given": "Chaoying"
},
{
"family": "Ly",
"given": "Jimmy"
},
{
"family": "Luo",
"given": "Hua"
},
{
"family": "Hogan",
"given": "Ellie"
},
{
"family": "Fafouti",
"given": "Maria Eleni"
},
{
"family": "Davie",
"given": "Melanie"
},
{
"family": "Naimi",
"given": "Fatima"
},
{
"family": "Li",
"given": "Yun"
},
{
"family": "Calarco",
"given": "John A"
},
{
"family": "Trost",
"given": "Brett"
},
{
"family": "Muffat",
"given": "Julien"
},
{
"family": "Lee",
"given": "Hyun O"
},
{
"family": "Lipshitz",
"given": "Howard D"
},
{
"family": "Smibert",
"given": "Craig A"
},
{
"family": "Tripathy",
"given": "Shreejoy J"
}
],
"container-title-short": "Nat Commun",
"volume": "17",
"issue": "1",
"page": "9363",
"DOI": "10.1038/s41467-026-76675-1",
"PMID": "42680762",
"PMCID": "PMC13534637",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41467-026-76675-1",
"language": "en",
"issued": {
"date-parts": [
[
2026,
8,
19
]
]
}
}

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.1093/bioinformatics/btag592 [code]
Network-based stratification of allele-specific expression reveals patient subgroups in Huntington's disease.
Journal: Bioinformatics (Oxford, England)
In common: STAR, WGCNA, SAMtools, 23 other tools, genetics / omics, 2 references
[2] doi:10.1016/j.xcrm.2026.102766 [code]
A longitudinal single-cell and spatial multiomic atlas of pediatric high-grade glioma.
Journal: Cell reports. Medicine
In common: pysam, Monocle 3, WGCNA, 23 other tools, genetics / omics, 1 reference
[3] doi:10.1038/s42003-026-10957-8 [code]
Brain defence by the extracellular matrix protein Cochlin.
Journal: Communications biology
In common: Monocle 3, Biopython, WGCNA, 22 other tools
[4] doi:10.1038/s44318-026-00818-9 [code]
FAM134B-mediated ER-phagy degrades APP and suppresses Alzheimer's disease pathology.
Journal: The EMBO journal
In common: Monocle 3, Biopython, BEDTools, 20 other tools, 1 reference
[5] doi:10.1126/sciadv.aed2952 [code]
Activation of transposable elements is linked to a region- and cell type-specific interferon response in Parkinson's disease.
Journal: Science advances
In common: STAR, pysam, Biopython, 19 other tools, 2 references
[6] doi:10.1016/j.celrep.2026.117073 [code]
Single-cell epigenomics uncovers heterochromatin instability and transcription factor dysfunction during mouse brain aging.
Journal: Cell reports
In common: pysam, BEDTools, SAMtools, 19 other tools, genetics / omics, 1 reference
[7] doi:10.1186/s13059-026-04177-w [code]
Genomic sequence evolution underlying human neocortical interareal diversification.
Journal: Genome biology
In common: pysam, Monocle 3, BEDTools, 19 other tools, genetics / omics
[8] doi:10.1038/s41586-026-10629-x [code]
Whole-genome duplication shaped cell-type evolution in the vertebrate brain.
Journal: Nature
In common: BEDTools, reticulate, rstatix, 19 other tools, genetics / omics, 2 references
[9] doi:10.1038/s41467-026-74753-y [code]
A human-specific microRNA controls the timing of excitatory synaptogenesis.
Journal: Nature communications
In common: STAR, SAMtools, edgeR, 13 other tools, 4 references
[10] doi:10.1016/j.cpblue.2026.100007 [code]
An integrated single-cell and spatial proteotranscriptomics atlas of fibroblast-driven immunoregulation within the human adult oral cavity.
Journal: Cell press blue
In common: STAR, SAMtools, edgeR, 19 other tools

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.

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: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

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