OSCR

KOLF2.1J iTF-Microglia: A standardized platform to study microglial transcriptional regulatory networks in CNS disease.

Code ↔ Paper

27 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 27 matches · 1 of them tie a paragraph to a whole file, not to given lines: a weak match, whose lines are not tinted
  1. [1] § Results › Inference of cCRE-gene associations across microglial states ↔ Scripts/cCRE-TargetGene_analysis.R, lines 1098–1184 · score 0.83 · GTPase, neutrophil degranulation, neuronal system, RHO, phase, cycle
  2. [2] § Results › Cis-regulatory landscapes of iTF-microglia across differentiation and activation ↔ Scripts/cCRE_analysis.R, lines 227–315 · score 0.83 · CA CTCF, CA H3K4me3, CA TF, dELS, pELS, cCRE
  3. [3] § Results › Cis-regulatory landscapes of iTF-microglia across differentiation and activation ↔ Scripts/TF_monaLisa_analysis.R, lines 199–242 · score 0.82 · CA CTCF, CA H3K4me3, CA TF, dELS, pELS, cCRE
  4. [4] § Results › Cis-regulatory landscapes of iTF-microglia across differentiation and activation ↔ Scripts/cCRE_analysis.R, lines 419–462 · score 0.79 · cell cycle, dELS, pELS, cytokine signaling, chemokine, translation
  5. [5] § STAR★Methods › Quantification and statistical analysis › Nomination of transcriptional regulatory networks (TRNs) › Identification of candidate cis-regulatory elements (cCREs) ↔ Scripts/TF_monaLisa_analysis.R, lines 41–81 · score 0.78 · regionCounts, windowCounts, background bins, H3K27ac, TMM, windows
  6. [6] § STAR★Methods › Quantification and statistical analysis › Nomination of transcriptional regulatory networks (TRNs) › Identification of target genes ↔ Scripts/cCRE-TargetGene_analysis.R, lines 1098–1184 · score 0.77 · Reactome pathway, Brain microglia links, target genes, DegCre, Closest, iPSCs
  7. [7] § Results › KOLF2.1J iTF-microglia transcriptome resembles other in vitro microglia models and brain microglia ↔ Scripts/RNAseq_analysis.R, lines 640–679 · score 0.76 · iHPCs, iMGLs, fetal microglia, CD16, WTC11, CD14
  8. [8] § Results › Inflammatory activation of iTF-microglia by LPS + IFNγ ↔ Scripts/cCRE_analysis.R, lines 419–462 · score 0.66 · innate immune, neutrophil degranulation, interleukin, phagocytosis, iPSCs, Pathway
  9. [9] § STAR★Methods › Quantification and statistical analysis › Nomination of transcriptional regulatory networks (TRNs) › Identification of candidate cis-regulatory elements (cCREs) ↔ Scripts/LDSC_bed_files_20250429.R, lines 84–162 · score 0.64 · GenomicRanges, findOverlaps, H3K27ac, cCREs, consensus, filtered
  10. [10] § Results › Cis-regulatory landscapes of iTF-microglia across differentiation and activation ↔ Scripts/TF_monaLisa_analysis.R, lines 244–284 · score 0.64 · dELS, pELS, ChIP, cCREs, PLS, promoters
  11. [11] § Results › Inflammatory activation of iTF-microglia by LPS + IFNγ ↔ Scripts/RNAseq_analysis.R, lines 170–233 · score 0.63 · HLA DRB1, CD40, CXCL9, GBP2, IDO1, CXCL10
  12. [12] § Results › Inflammatory activation of iTF-microglia by LPS + IFNγ ↔ Scripts/TF_monaLisa_analysis.R, lines 1061–1087 · score 0.63 · HLA DRB1, CD40, CXCL9, GBP2, IDO1, CXCL10
  13. [13] § STAR★Methods › Quantification and statistical analysis › Association of TRNs with candidate disease-risk variants ↔ Scripts/monalisa_b.R, lines 40–82 · score 0.62 · AD GWAS, risk variants, LD, H3K27ac, monaLisa, ATAC
  14. [14] § Results › KOLF2.1J iTF-microglia transcriptome resembles other in vitro microglia models and brain microglia ↔ Scripts/RNAseq_analysis.R, lines 640–679 · score 0.61 · iHPCs, fetal microglia, DESeq2, adult, KOLF2.1J, Monocytes
  15. [15] § STAR★Methods › Quantification and statistical analysis › Association of TRNs with candidate disease-risk variants ↔ Scripts/motifbreakR_script.R, lines 41–112 · score 0.61 · motifbreakR, ic, JASPAR, PWMs, candidate, motifs
  16. [16] § Results › Inference of cCRE-gene associations across microglial states ↔ Scripts/cCRE-TargetGene_analysis.R, lines 1200–1263 · score 0.60 · vivo microglial, Brain microglia links, DegCre, closest, distance, enhancer
  17. [17] § STAR★Methods › Quantification and statistical analysis › Nomination of transcriptional regulatory networks (TRNs) › Identification of candidate cis-regulatory elements (cCREs) ↔ Scripts/cCRE_disease_variant_annotation.R, lines 581–625 · score 0.60 · GenomicRanges, findOverlaps, cCRE, filtered, overlapping, cell
  18. [18] § STAR★Methods › Quantification and statistical analysis › Nomination of transcriptional regulatory networks (TRNs) › Identification of TFs in TRNs ↔ Scripts/monalisa_b.R, lines 211–253 · score 0.59 · findMotifHits, scanning, PWMs, monaLisa, JASPAR2024, csaw
  19. [19] § Results › Inference of cCRE-gene associations across microglial states ↔ Scripts/cCRE-TargetGene_analysis.R, lines 1524–1594 · score 0.57 · brain microglia links, cCRE, DegCre, promoter, TSS, enhancers
  20. [20] § STAR★Methods › Quantification and statistical analysis › ATAC- and ChIP-seq processing and peak calling ↔ src/encode_task_overlap.py, lines 132–174 · score 0.56 · naive overlap, ATAC seq, shift, blacklist, ChIP, filtered
  21. [21] § STAR★Methods › Quantification and statistical analysis › Nomination of transcriptional regulatory networks (TRNs) › Identification of TFs in TRNs ↔ Scripts/TF_monaLisa_analysis.R, lines 453–495 · score 0.56 · findMotifHits, scanning, PWMs, JASPAR2024, csaw, matrices
  22. [22] § Results › Inference of cCRE-gene associations across microglial states ↔ Scripts/cCRE-TargetGene_analysis.R, lines 1524–1594 · score 0.56 · cCRE, target genes, DegCre, brain microglia, ratio, TSS
  23. [23] § STAR★Methods › Quantification and statistical analysis › RNA-seq meta-analysis ↔ Scripts/motifbreakR_script.R, lines 464–533 · score 0.55 · Variance stabilizing transformation, VST, iPSCs, clustering, Gene, microglia
  24. [24] § STAR★Methods › Quantification and statistical analysis › Association of TRNs with candidate disease-risk variants ↔ Scripts/MAGMA_expression_matrix_format.R, the whole file · a weak match · score 0.54 · GWAS summary, MAGMA, winsorized, log2, TPM, subsets
  25. [25] § Results › iTF-microglia TRNs are enriched for neurodegenerative and autoimmune risk variants ↔ Scripts/LDSC_heatmap.R, lines 136–195 · score 0.54 · REL, H3K27ac, IBD, SCZ, SLE, cCREs
  26. [26] § STAR★Methods › Quantification and statistical analysis › RNA-seq meta-analysis ↔ Scripts/RNAseq_analysis.R, lines 681–720 · score 0.52 · Variance stabilizing transformation, VST, clustering
  27. [27] § STAR★Methods › Quantification and statistical analysis › ATAC- and ChIP-seq processing and peak calling ↔ src/encode_task_qc_report.py, lines 458–526 · score 0.50 · seq pipeline, mitochondrial, Picard, quality, QC, ENCODE

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 · 1,594 lines · 62 KB · MIT · 5 matches

  1. # Script to compare target genes in iTF cells
  2. # open R
  3. srun -n 10 -p interactive --pty /bin/bash
  4. module load cluster/gsl/1.15
  5. module load cluster/htslib/1.9-devel
  6. module load cluster/build_tools/llvm/8.0
  7. module load cluster/util/gcc/8.2
  8. module load hdf5_18/1.8.21
  9. conda activate r_env
  10. #conda deactivate
  11. R
  12. library(GenomicRanges)
  13. library(AnnotationHub)
  14. library(data.table)
  15. library(dplyr)
  16. library(tidyr)
  17. library(rtracklayer)
  18. library(tibble)
  19. library(stringr)
  20. library(DESeq2)
  21. library(org.Hs.eg.db)
  22. library(ggplot2)
  23. # Set work directory
  24. setwd("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/")
  25. # Load data
  26. iTF_CREs_ENCODE <- readRDS("batch2/Tables/cCREs_overlap_iTF_ATAC_H3K27ac_overlap.rds")
  27. consensus_CREs <- readRDS("batch2/Tables/cCREs_overlap_consensus_peaks.rds")
  28. gse <- readRDS("batch2/Tables/gse.rds")
  29. load("/cluster/home/broberts/ref_genomes/STAR_Gencode_v46/gencodeV46TSSGR.rda")
  30. Gencode.V46 <- finalTSsGR
  31. # Load and filter gene expression data
  32. coldata <- read.csv("/cluster/home/irodriguez/Myers_Lab/20240416_Novogene_RNAseq_Library_iTF_iMGLs_Nick_paper/R_analysis/iTF-Microglia_BulkRNA_SampleSheet_phenotype.csv")
  33. tpm <- assay(gse, "abundance")
  34. coldata_subset <- coldata[c(13:15, 19:24),]
  35. tpm_subset <- tpm[, c(13:15, 19:24)]
  36. colnames(tpm_subset) <- coldata_subset$Sample
  37. rownames(tpm_subset) <- sapply(strsplit(rownames(tpm_subset), "[.]"), `[[`, 1)
  38. # Compute row-wise means
  39. expr_means <- data.frame(
  40. iPSC = rowMeans(tpm_subset[, 1:3]),
  41. Microglia = rowMeans(tpm_subset[, 4:6]),
  42. Microglia_LPS_IFNG = rowMeans(tpm_subset[, 7:9])
  43. )
  44. # Filter genes based on expression
  45. filtered_genes <- rownames(expr_means)[rowSums(expr_means > 1) > 0]
  46. # Filter and process GENCODE annotations
  47. gtf_df_filtered <- as.data.frame(Gencode.V46) %>%
  48. filter(GeneID %in% filtered_genes) %>%
  49. mutate(
  50. promoter_start = ifelse(strand == "+", pmax(start - 2000, 1), end - 200),
  51. promoter_end = ifelse(strand == "+", start + 200, pmax(end + 2000, 1))
  52. )
  53. Gencode.V46_tss <- GRanges(gtf_df_filtered)
  54. # Promoters
  55. promoter_df <- unique(gtf_df_filtered[,c(1,10:11,7)])
  56. Gencode.V46_promoter <- GRanges(promoter_df)
  57. # Find closest TSS and distances
  58. closest_tss_indices <- nearest(consensus_CREs, Gencode.V46_tss)
  59. dists <- distanceToNearest(consensus_CREs, Gencode.V46_tss)
  60. consensus_CREs$closest_tss <- mcols(Gencode.V46_tss[closest_tss_indices])$GeneSymb
  61. consensus_CREs$distance_tss <- mcols(dists)$distance
  62. # Overlap with cell-type specific peaks
  63. overlap_gr_list <- GRangesList(
  64. lapply(names(iTF_CREs_ENCODE), function(name) {
  65. gr_current <- iTF_CREs_ENCODE[[name]]
  66. overlaps <- findOverlaps(consensus_CREs, gr_current)
  67. overlapping_ranges <- consensus_CREs[queryHits(overlaps)]
  68. mcols(overlapping_ranges)$cell.type <- mcols(gr_current)$cell.type[subjectHits(overlaps)]
  69. unique(overlapping_ranges)
  70. })
  71. )
  72. # Convert results to data frames
  73. iTF_cCREs_df <- as.data.frame(consensus_CREs)
  74. overlap_dfs <- lapply(overlap_gr_list, as.data.frame)
  75. names(overlap_dfs) <- names(iTF_CREs_ENCODE)
  76. iTF_iPSCs_cCREs_df <- overlap_dfs$iTF_iPSCs
  77. iTF_Microglia_cCREs_df <- overlap_dfs$iTF_Microglia
  78. iTF_Microglia.LPS.IFNG_cCREs_df <- overlap_dfs$iTF_Microglia.LPS.IFNG
  79. # Merge keeping all rows in df1
  80. merged_iTF_cCREs_df <- merge(iTF_cCREs_df, iTF_iPSCs_cCREs_df, by = intersect(names(iTF_cCREs_df), names(iTF_iPSCs_cCREs_df)), all.x = TRUE)
  81. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_Microglia_cCREs_df, by = intersect(names(iTF_cCREs_df), names(iTF_Microglia_cCREs_df)), all.x = TRUE)
  82. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_Microglia.LPS.IFNG_cCREs_df, by = intersect(names(iTF_cCREs_df), names(iTF_Microglia.LPS.IFNG_cCREs_df)), all.x = TRUE)
  83. # Rename columns
  84. merged_iTF_cCREs_df <- merged_iTF_cCREs_df %>% rename(
  85. iPSC_cCRE = cell.type.x,
  86. Microglia_cCRE = cell.type.y,
  87. Microglia_LPS_IFNG_cCRE = cell.type
  88. ) %>% unique()
  89. ########################
  90. # HiC loops Processing
  91. ########################
  92. library(mariner)
  93. library(InteractionSet)
  94. # Define file path
  95. dir_loop_data <- "/cluster/projects/ADFTD/HiC/Ivan_10-21-24/encode_pipeline_outputs"
  96. loopFiles <- list.files(path = dir_loop_data, pattern = "loops_30.bedpe.gz", recursive = TRUE, full.names = TRUE)
  97. # Read and sort loops file
  98. loops_sorted <- fread(loopFiles[7], header = FALSE) %>%
  99. as.data.frame() %>%
  100. arrange(V1, V2) %>%
  101. mutate(name = paste0("loop", row_number()))
  102. # Convert to GInteractions and clear metadata
  103. loops_GI <- as_ginteractions(loops_sorted)
  104. mcols(loops_GI) <- NULL
  105. # Find overlaps
  106. overlap_anchor1 <- findOverlaps(anchors(loops_GI, type = "first"), Gencode.V46_promoter)
  107. overlap_anchor2 <- findOverlaps(anchors(loops_GI, type = "second"), Gencode.V46_promoter)
  108. # Create data.frames of overlaps
  109. df_olap1 <- data.frame(
  110. anchor_id = queryHits(overlap_anchor1),
  111. gene = Gencode.V46_promoter$GeneSymb[subjectHits(overlap_anchor1)]
  112. )
  113. df_olap2 <- data.frame(
  114. anchor_id = queryHits(overlap_anchor2),
  115. gene = Gencode.V46_promoter$GeneSymb[subjectHits(overlap_anchor2)]
  116. )
  117. # Collapse overlapping gene names
  118. collapsed_genes1 <- aggregate(gene ~ anchor_id, df_olap1, function(x) paste(unique(x), collapse = ","))
  119. collapsed_genes2 <- aggregate(gene ~ anchor_id, df_olap2, function(x) paste(unique(x), collapse = ","))
  120. # Initialize columns
  121. mcols(loops_GI)$hic_anchor1_gene <- NA_character_
  122. mcols(loops_GI)$hic_anchor2_gene <- NA_character_
  123. # Assign collapsed gene names
  124. mcols(loops_GI)$hic_anchor1_gene[collapsed_genes1$anchor_id] <-
  125. collapsed_genes1$gene[match(collapsed_genes1$anchor_id, collapsed_genes1$anchor_id)]
  126. mcols(loops_GI)$hic_anchor2_gene[collapsed_genes2$anchor_id] <-
  127. collapsed_genes2$gene[match(collapsed_genes2$anchor_id, collapsed_genes2$anchor_id)]
  128. # Overlap with cCREs
  129. consensus_CREs_ranges <- consensus_CREs
  130. mcols(consensus_CREs_ranges) <- NULL
  131. # Overlap cCREs with anchor1
  132. overlap_cCRE_anchor1 <- findOverlaps(consensus_CREs_ranges,anchors(loops_GI, type = "first"))
  133. # Overlap cCREs with anchor2
  134. overlap_cCRE_anchor2 <- findOverlaps(consensus_CREs_ranges,anchors(loops_GI, type = "second"))
  135. # Add gene_name to anchor1 overlaps
  136. consensus_CREs_anchor1 <- consensus_CREs_ranges
  137. mcols(consensus_CREs_anchor1)$hic_anchor_gene <- NA
  138. mcols(consensus_CREs_anchor1)$hic_anchor_gene[queryHits(overlap_cCRE_anchor1)] <- loops_GI$hic_anchor2_gene[subjectHits(overlap_cCRE_anchor1)]
  139. # Add gene_name to anchor2 overlaps
  140. consensus_CREs_anchor2 <- consensus_CREs_ranges
  141. mcols(consensus_CREs_anchor2)$hic_anchor_gene <- NA
  142. mcols(consensus_CREs_anchor2)$hic_anchor_gene[queryHits(overlap_cCRE_anchor2)] <- loops_GI$hic_anchor1_gene[subjectHits(overlap_cCRE_anchor2)]
  143. # Create datafr
  144. consensus_CREs_anchor1_df <- as.data.frame(consensus_CREs_anchor1)
  145. consensus_CREs_anchor2_df <- as.data.frame(consensus_CREs_anchor2)
  146. # Assuming df1 and df2 are the dataframes you want to rbind
  147. df_combined <- bind_rows(consensus_CREs_anchor1_df, consensus_CREs_anchor1_df)
  148. # Remove NA from 'hic_anchor_gene' and collapse by ',' (comma separator)
  149. cCRE_hic_genes <- df_combined %>%
  150. filter(!is.na(hic_anchor_gene)) %>%
  151. group_by(across(-hic_anchor_gene)) %>% # Group by all columns except 'hic_anchor_gene'
  152. summarise(hic_anchor_gene = paste(unique(na.omit(hic_anchor_gene)), collapse = ","), .groups = 'drop')
  153. # Result
  154. cCRE_hic_genes <- as.data.frame(cCRE_hic_genes)
  155. # Merge dataframe
  156. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, cCRE_hic_genes, by = intersect(names(iTF_cCREs_df), names(cCRE_hic_genes)), all.x = TRUE)
  157. ########################
  158. #DegCre results
  159. ########################
  160. # Define the directory
  161. folder_path <- "/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables"
  162. # List all files with the "_degCreGInter.rd" suffix
  163. #rd_files <- list.files(folder_path, pattern = "_H3K27ac_overlapping_peaks_degCreGInter.rd$", full.names = TRUE)
  164. #rd_files <- list.files(folder_path, pattern = "_ATAC_overlapping_peaks_degCreGInter.rd$", full.names = TRUE)
  165. rd_files <- list.files(folder_path, pattern = "_ATAC_overlapping_peaks_diff_degCreGInter.rd$", full.names = TRUE)
  166. rd_files <- list.files(folder_path, pattern = "_H3K27ac_overlapping_peaks_stim_degCreGInter.rd$", full.names = TRUE)
  167. # Loop through the list of files and load each one
  168. for (file in rd_files) {
  169. # Extract the file name without extension to use as a variable name
  170. file_name <- gsub("_H3K27ac_overlapping_peaks_stim_degCreGInter.rd$", "", basename(file))
  171. # Load the file
  172. temp_object_name <- load(file)
  173. # Retrieve the object using `get`
  174. assign(file_name, get(temp_object_name))
  175. # Optionally remove the temporary object
  176. rm(list = temp_object_name)
  177. }
  178. # After the loop, the variables corresponding to the files will be available in the environment
  179. # Extract the second anchor (the second column of the anchor matrix)
  180. iTF_Microglia_vs_iPSCs_CRE <- anchors(csaw_iTF_Microglia_vs_iTF_iPSCs, type = "second")
  181. iTF_Microglia_vs_iPSCs_CRE_df <- as.data.frame(iTF_Microglia_vs_iPSCs_CRE)
  182. iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_CRE <- anchors(csaw_iTF_Microglia.LPS.IFNG_vs_iTF_Microglia, type = "second")
  183. iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_CRE_df <- as.data.frame(iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_CRE)
  184. # Extract the metadata columns: Deg_GeneSymb and Cre_direction
  185. iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_CRE_meta_data <- mcols(csaw_iTF_Microglia.LPS.IFNG_vs_iTF_Microglia)[, c("Deg_GeneSymb", "Cre_direction", "assocDist")]
  186. iTF_Microglia_vs_iPSCs_CRE_meta_data <- mcols(csaw_iTF_Microglia_vs_iTF_iPSCs)[, c("Deg_GeneSymb", "Cre_direction", "assocDist")]
  187. # Combine the second anchor and the selected metadata columns into a data frame
  188. iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_DegCre <- unique(cbind(iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_CRE_df, iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_CRE_meta_data))
  189. iTF_Microglia_vs_iPSCs_DegCre <- unique(cbind(iTF_Microglia_vs_iPSCs_CRE_df, iTF_Microglia_vs_iPSCs_CRE_meta_data))
  190. # Separate by cell type
  191. iTF_Microglia.LPS.IFNG_DegCre <- iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_DegCre[iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_DegCre$Cre_direction == "up",]
  192. iTF_Microglia.untreated_DegCre <- iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_DegCre[iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_DegCre$Cre_direction == "down",]
  193. iTF_Microglia.diff_DegCre <- iTF_Microglia_vs_iPSCs_DegCre[iTF_Microglia_vs_iPSCs_DegCre$Cre_direction == "up",]
  194. iTF_iPSCs_DegCre <- iTF_Microglia_vs_iPSCs_DegCre[iTF_Microglia_vs_iPSCs_DegCre$Cre_direction == "down",]
  195. # Bind cell types
  196. iTF_Microglia.LPS.IFNG_DegCre <- unique(iTF_Microglia.LPS.IFNG_DegCre[,c(1:6,8)])
  197. iTF_Microglia.untreated_DegCre <- unique(iTF_Microglia.untreated_DegCre[,c(1:6,8)])
  198. iTF_Microglia.diff_DegCre <- unique(iTF_Microglia.diff_DegCre[,c(1:6,8)])
  199. iTF_iPSCs_DegCre <- unique(iTF_iPSCs_DegCre[,c(1:6,8)])
  200. # Assuming df is your dataframe
  201. iTF_Microglia.LPS.IFNG_DegCre <- iTF_Microglia.LPS.IFNG_DegCre %>%
  202. group_by(seqnames, start, end) %>% # Group by seqnames and start
  203. summarise(
  204. DegCre_iTF_Microglia.LPS.IFNG = paste(sort(unique(na.omit(Deg_GeneSymb))), collapse = ","), # Sort and collapse unique Deg_GeneSymb
  205. .groups = 'drop' # Drop grouping structure in the result
  206. ) %>%
  207. arrange(seqnames, start, end) %>%
  208. as.data.frame()
  209. iTF_Microglia.untreated_DegCre <- iTF_Microglia.untreated_DegCre %>%
  210. group_by(seqnames, start, end) %>% # Group by seqnames and start
  211. summarise(
  212. DegCre_iTF_Microglia.untreated = paste(sort(unique(na.omit(Deg_GeneSymb))), collapse = ","), # Collapse unique Deg_GeneSymb
  213. .groups = 'drop' # Drop grouping structure in the result
  214. ) %>%
  215. arrange(seqnames, start, end) %>% as.data.frame()
  216. iTF_Microglia.diff_DegCre <- iTF_Microglia.diff_DegCre %>%
  217. group_by(seqnames, start, end) %>% # Group by seqnames and start
  218. summarise(
  219. DegCre_iTF_Microglia.diff = paste(sort(unique(na.omit(Deg_GeneSymb))), collapse = ","), # Collapse unique Deg_GeneSymb
  220. .groups = 'drop' # Drop grouping structure in the result
  221. ) %>%
  222. arrange(seqnames, start, end) %>% as.data.frame()
  223. iTF_iPSCs_DegCre <- iTF_iPSCs_DegCre %>%
  224. group_by(seqnames, start, end) %>% # Group by seqnames and start
  225. summarise(
  226. DegCre_iTF_iPSCs = paste(sort(unique(na.omit(Deg_GeneSymb))), collapse = ","), # Collapse unique Deg_GeneSymb
  227. .groups = 'drop' # Drop grouping structure in the result
  228. ) %>%
  229. arrange(seqnames, start, end) %>% as.data.frame()
  230. # Make Granges
  231. iTF_iPSCs_DegCre_gr <- GRanges(iTF_iPSCs_DegCre)
  232. iTF_Microglia.diff_DegCre_gr <- GRanges(iTF_Microglia.diff_DegCre)
  233. iTF_Microglia.untreated_DegCre_gr <- GRanges(iTF_Microglia.untreated_DegCre)
  234. iTF_Microglia.LPS.IFNG_DegCre_gr <- GRanges(iTF_Microglia.LPS.IFNG_DegCre)
  235. # Make GrangesList
  236. DegCre_iTF_list <- list(iTF_iPSCs_DegCre_gr,iTF_Microglia.diff_DegCre_gr,
  237. iTF_Microglia.untreated_DegCre_gr,iTF_Microglia.LPS.IFNG_DegCre_gr)
  238. #DegCre_iTF_list_grl <- GRangesList(DegCre_iTF_list)
  239. # overlap
  240. overlap_with_metadata <- function(query, subject) {
  241. # Find overlaps between query and subject
  242. hits <- findOverlaps(query, subject)
  243. # Extract overlapping ranges
  244. query_overlaps <- query[queryHits(hits)]
  245. subject_overlaps <- subject[subjectHits(hits)]
  246. # Combine metadata columns
  247. combined_mcols <- cbind(mcols(query_overlaps), mcols(subject_overlaps))
  248. # Create a new GRanges object with combined metadata
  249. result <- query_overlaps
  250. mcols(result) <- combined_mcols
  251. return(result)
  252. }
  253. # Assuming ABC_Mac_list is a named list of GRanges objects
  254. overlapped_list <- lapply(DegCre_iTF_list, function(gr) overlap_with_metadata(consensus_CREs_ranges, gr))
  255. iTF_iPSCs_DegCre <- as.data.frame(overlapped_list[[1]])
  256. iTF_Microglia.diff_DegCre <- as.data.frame(overlapped_list[[2]])
  257. iTF_Microglia.untreated_DegCre <- as.data.frame(overlapped_list[[3]])
  258. iTF_Microglia.LPS.IFNG_DegCre <- as.data.frame(overlapped_list[[4]])
  259. iTF_iPSCs_DegCre <- unique(iTF_iPSCs_DegCre[,c(1:3,6)])
  260. iTF_Microglia.diff_DegCre <- unique(iTF_Microglia.diff_DegCre[,c(1:3,6)])
  261. iTF_Microglia.untreated_DegCre <- unique(iTF_Microglia.untreated_DegCre[,c(1:3,6)])
  262. iTF_Microglia.LPS.IFNG_DegCre <- unique(iTF_Microglia.LPS.IFNG_DegCre[,c(1:3,6)])
  263. # Collapse CREs
  264. # Group by seqnames, start, and end, then collapse
  265. iTF_iPSCs_DegCre_collapsed <- iTF_iPSCs_DegCre %>%
  266. group_by(seqnames, start, end) %>%
  267. summarise(DegCre_iTF_iPSCs = paste(
  268. unique(sort(unlist(strsplit(DegCre_iTF_iPSCs, ",")))),
  269. collapse = ","
  270. ), .groups = "drop") %>% as.data.frame()
  271. iTF_Microglia_DegCre.diff_collapsed <- iTF_Microglia.diff_DegCre %>%
  272. group_by(seqnames, start, end) %>%
  273. summarise(DegCre_iTF_Microglia.diff = paste(
  274. unique(sort(unlist(strsplit(DegCre_iTF_Microglia.diff, ",")))),
  275. collapse = ","
  276. ), .groups = "drop") %>% as.data.frame()
  277. iTF_Microglia_DegCre.untreated_collapsed <- iTF_Microglia.untreated_DegCre %>%
  278. group_by(seqnames, start, end) %>%
  279. summarise(DegCre_iTF_Microglia.untreated = paste(
  280. unique(sort(unlist(strsplit(DegCre_iTF_Microglia.untreated, ",")))),
  281. collapse = ","
  282. ), .groups = "drop") %>% as.data.frame()
  283. iTF_Microglia_DegCre.LPS.IFNG_collapsed <- iTF_Microglia.LPS.IFNG_DegCre %>%
  284. group_by(seqnames, start, end) %>%
  285. summarise(DegCre_iTF_Microglia.LPS.IFNG = paste(
  286. unique(sort(unlist(strsplit(DegCre_iTF_Microglia.LPS.IFNG, ",")))),
  287. collapse = ","
  288. ), .groups = "drop") %>% as.data.frame()
  289. # Merge dataframe
  290. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_iPSCs_DegCre_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_iPSCs_DegCre_collapsed)), all.x = TRUE)
  291. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_Microglia_DegCre.diff_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_Microglia_DegCre.diff_collapsed)), all.x = TRUE)
  292. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_Microglia_DegCre.untreated_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_Microglia_DegCre.untreated_collapsed)), all.x = TRUE)
  293. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_Microglia_DegCre.LPS.IFNG_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_Microglia_DegCre.LPS.IFNG_collapsed)), all.x = TRUE)
  294. ########################
  295. #ABC results
  296. ########################
  297. # Define the list of file paths
  298. file_paths <- c(
  299. "/cluster/home/irodriguez/software/ABC-Enhancer-Gene-Prediction/results_KOLF2.1J-iTF_HiC_20250423/iTF_iPSCs_hic_all/Predictions/EnhancerPredictionsAllPutative.tsv.gz",
  300. "/cluster/home/irodriguez/software/ABC-Enhancer-Gene-Prediction/results_KOLF2.1J-iTF_HiC_20250423/iTF_Microglia_hic_all/Predictions/EnhancerPredictionsAllPutative.tsv.gz",
  301. "/cluster/home/irodriguez/software/ABC-Enhancer-Gene-Prediction/results_KOLF2.1J-iTF_HiC_20250423/iTF_Microglia.LPS.IFNG_hic_all/Predictions/EnhancerPredictionsAllPutative.tsv.gz"
  302. )
  303. # Apply the function to each file path
  304. cell_types <- sapply(strsplit(unlist(file_paths),"[/]"),"[[",8)
  305. # Read all files into a list
  306. ABC_list <- lapply(file_paths, function(fp) fread(fp, sep = "\t", header = TRUE))
  307. names(ABC_list) <- cell_types
  308. # ABC score threshold based on doi:10.1038/s41586-021-03446-x
  309. ABC_filtered <- lapply(ABC_list, function(df) {
  310. df[df$class == "promoter" & df$ABC.Score >= 0.1 |
  311. df$class != "promoter" & df$ABC.Score >= 0.015, ]
  312. })
  313. ABC_filtered_subset <- lapply(ABC_filtered, function(x) {
  314. unique(x[,c(1:3,11,31)])
  315. })
  316. iTF_iPSCs_ABC <- as.data.frame(ABC_filtered_subset$iTF_iPSCs_hic_all)
  317. iTF_Microglia_ABC <- as.data.frame(ABC_filtered_subset$iTF_Microglia_hic_all)
  318. iTF_Microglia.LPS.IFNG_ABC <- as.data.frame(ABC_filtered_subset$iTF_Microglia.LPS.IFNG_hic_all)
  319. # Assuming df is your dataframe
  320. iTF_Microglia.LPS.IFNG_ABC <- iTF_Microglia.LPS.IFNG_ABC %>%
  321. group_by(chr, start, end) %>% # Group by chr and start
  322. summarise(
  323. ABC_iTF_Microglia.LPS.IFNG = paste(sort(unique(na.omit(TargetGene))), collapse = ","), # Sort and collapse unique TargetGene
  324. .groups = 'drop' # Drop grouping structure in the result
  325. ) %>%
  326. arrange(chr, start, end) %>%
  327. as.data.frame()
  328. iTF_Microglia_ABC <- iTF_Microglia_ABC %>%
  329. group_by(chr, start, end) %>% # Group by chr and start
  330. summarise(
  331. ABC_iTF_Microglia = paste(sort(unique(na.omit(TargetGene))), collapse = ","), # Collapse unique TargetGene
  332. .groups = 'drop' # Drop grouping structure in the result
  333. ) %>%
  334. arrange(chr, start, end) %>% as.data.frame()
  335. iTF_iPSCs_ABC <- iTF_iPSCs_ABC %>%
  336. group_by(chr, start, end) %>% # Group by chr and start
  337. summarise(
  338. ABC_iTF_iPSCs = paste(sort(unique(na.omit(TargetGene))), collapse = ","), # Collapse unique TargetGene
  339. .groups = 'drop' # Drop grouping structure in the result
  340. ) %>%
  341. arrange(chr, start, end) %>% as.data.frame()
  342. # Make Granges
  343. iTF_iPSCs_ABC_gr <- GRanges(iTF_iPSCs_ABC)
  344. iTF_Microglia_ABC_gr <- GRanges(iTF_Microglia_ABC)
  345. iTF_Microglia.LPS.IFNG_ABC_gr <- GRanges(iTF_Microglia.LPS.IFNG_ABC)
  346. # Make GrangesList
  347. ABC_iTF_list <- list(iTF_iPSCs_ABC_gr,iTF_Microglia_ABC_gr,iTF_Microglia.LPS.IFNG_ABC_gr)
  348. # overlap
  349. overlap_with_metadata <- function(query, subject) {
  350. # Find overlaps between query and subject
  351. hits <- findOverlaps(query, subject)
  352. # Extract overlapping ranges
  353. query_overlaps <- query[queryHits(hits)]
  354. subject_overlaps <- subject[subjectHits(hits)]
  355. # Combine metadata columns
  356. combined_mcols <- cbind(mcols(query_overlaps), mcols(subject_overlaps))
  357. # Create a new GRanges object with combined metadata
  358. result <- query_overlaps
  359. mcols(result) <- combined_mcols
  360. return(result)
  361. }
  362. # Assuming ABC_iTF_list is a named list of GRanges objects
  363. overlapped_list <- lapply(ABC_iTF_list, function(gr) overlap_with_metadata(consensus_CREs_ranges, gr))
  364. iTF_iPSCs_ABC <- as.data.frame(overlapped_list[[1]])
  365. iTF_Microglia_ABC <- as.data.frame(overlapped_list[[2]])
  366. iTF_Microglia.LPS.IFNG_ABC <- as.data.frame(overlapped_list[[3]])
  367. iTF_iPSCs_ABC <- unique(iTF_iPSCs_ABC[,c(1:3,6)])
  368. iTF_Microglia_ABC <- unique(iTF_Microglia_ABC[,c(1:3,6)])
  369. iTF_Microglia.LPS.IFNG_ABC <- unique(iTF_Microglia.LPS.IFNG_ABC[,c(1:3,6)])
  370. # Collapse CREs
  371. # Group by seqnames, start, and end, then collapse ABC_THP1_Mac_0h
  372. iTF_iPSCs_ABC_collapsed <- iTF_iPSCs_ABC %>%
  373. group_by(seqnames, start, end) %>%
  374. summarise(ABC_iTF_iPSCs = paste(
  375. unique(sort(unlist(strsplit(ABC_iTF_iPSCs, ",")))),
  376. collapse = ","
  377. ), .groups = "drop") %>% as.data.frame()
  378. iTF_Microglia_ABC_collapsed <- iTF_Microglia_ABC %>%
  379. group_by(seqnames, start, end) %>%
  380. summarise(ABC_iTF_Microglia = paste(
  381. unique(sort(unlist(strsplit(ABC_iTF_Microglia, ",")))),
  382. collapse = ","
  383. ), .groups = "drop") %>% as.data.frame()
  384. iTF_Microglia.LPS.IFNG_ABC_collapsed <- iTF_Microglia.LPS.IFNG_ABC %>%
  385. group_by(seqnames, start, end) %>%
  386. summarise(ABC_iTF_Microglia.LPS.IFNG = paste(
  387. unique(sort(unlist(strsplit(ABC_iTF_Microglia.LPS.IFNG, ",")))),
  388. collapse = ","
  389. ), .groups = "drop") %>% as.data.frame()
  390. # Merge dataframe
  391. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_iPSCs_ABC_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_iPSCs_ABC_collapsed)), all.x = TRUE)
  392. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_Microglia_ABC_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_Microglia_ABC_collapsed)), all.x = TRUE)
  393. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_Microglia.LPS.IFNG_ABC_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_Microglia.LPS.IFNG_ABC_collapsed)), all.x = TRUE)
  394. #Save files
  395. saveRDS(merged_iTF_cCREs_df,file="/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/iTF_CREs_target_genes.rds")
  396. #merged_iTF_cCREs_df <- readRDS("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/Tables/iTF_CREs_target_genes.rds")
  397. #consensus_CREs <- readRDS("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/candidate_CREs/iTF_CREs_all_ENCODE_ABC_peaks.rds")
  398. #iTF_cCREs_df <- as.data.frame(consensus_CREs)
  399. #######################
  400. #snMULTIomics AD Myers lab
  401. #######################
  402. # Load links
  403. links <- read.csv("/cluster/home/irodriguez/Myers_Lab/20230327_AD_variants_TF_trios_snMultiomics/mmc6_feature_links.csv")
  404. # Subset trios
  405. links_subset <- unique(links[,c(1:3,5,9,8)])
  406. links_subset_MG <- links_subset[grep("Microglia",links_subset$CT),]
  407. links_subset_MG_genes <- unique(links_subset_MG$gene)
  408. # Summarize by unique seqnames, start, and end
  409. links_subset_MG_summary <- links_subset_MG %>%
  410. group_by(seqnames, start, end) %>%
  411. summarise(
  412. gene = paste(gene, collapse = ","),
  413. group = paste(group, collapse = ","),
  414. .groups = "drop"
  415. )
  416. links_subset_MG_summary <- unique(links_subset_MG_summary)
  417. #colnames(links_subset_MG_summary) <- c("seqnames","start","end","Peak2gene.Anderson2023")
  418. colnames(links_subset_MG_summary) <- c("seqnames","start","end","Peak2gene.Anderson2023","Phenotype.Anderson2023")
  419. # Create GRanges objects
  420. links_GR <- GRanges(links_subset_MG_summary)
  421. #overlap with SNPs
  422. olap_links <- findOverlaps(consensus_CREs_ranges,links_GR)
  423. # add the metacolumns to the GR object
  424. consensus_CREs_links <- consensus_CREs_ranges[queryHits(olap_links)]
  425. mcols(consensus_CREs_links) <- cbind(mcols(consensus_CREs_links), mcols(links_GR[subjectHits(olap_links)]))
  426. # Create df from the GR overlap
  427. iTF_cCREs_links <- data.frame(consensus_CREs_links)
  428. iTF_cCREs_links <- unique(iTF_cCREs_links[,c(1:3,6:7)])
  429. # Collapse CREs
  430. # Group by seqnames, start, and end
  431. iTF_cCREs_links_collapsed <- iTF_cCREs_links %>%
  432. group_by(seqnames, start, end) %>%
  433. summarise(Peak2gene.Anderson2023 = paste(
  434. unlist(strsplit(Peak2gene.Anderson2023, ",")), collapse = ","),
  435. Phenotype.Anderson2023 = paste(
  436. unlist(strsplit(Phenotype.Anderson2023, ",")), collapse = ","),
  437. .groups = "drop") %>% as.data.frame()
  438. iTF_cCREs_links_collapsed <- unique(iTF_cCREs_links_collapsed)
  439. # Merge dataframe
  440. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_cCREs_links_collapsed, by = intersect(names(iTF_cCREs_df), names(iTF_cCREs_links_collapsed)), all.x = TRUE)
  441. #Save files
  442. saveRDS(merged_iTF_cCREs_df,file="/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/iTF_CREs_target_genes.rds")
  443. #merged_iTF_cCREs_df <- readRDS("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/iTF_CREs_target_genes.rds")
  444. #########################################
  445. # Nott PLACseq brain
  446. #########################################
  447. library(readxl)
  448. read_excel_allsheets <- function(filename, tibble = FALSE) {
  449. # I prefer straight data.frames
  450. # but if you like tidyverse tibbles (the default with read_excel)
  451. # then just pass tibble = TRUE
  452. sheets <- readxl::excel_sheets(filename)
  453. x <- lapply(sheets, function(X) readxl::read_excel(filename, sheet = X))
  454. if(!tibble) x <- lapply(x, as.data.frame)
  455. names(x) <- sheets
  456. x
  457. }
  458. # Load PLACseq files
  459. Nott_PLAC <- read_excel_allsheets("/cluster/home/irodriguez/Myers_Lab/GWAS_AD_summary_statistics/variant_annotation/Nott_files/aay0793-nott-table-s5.xlsx")
  460. names(Nott_PLAC)
  461. PLAC_mic <- as.data.frame(Nott_PLAC[[2]])
  462. colnames(PLAC_mic) <- PLAC_mic[2,]
  463. PLAC_mic <- PLAC_mic[-c(1:2),1:6]
  464. PLACseq <- unique(PLAC_mic)
  465. PLACseq$start1 <- as.numeric(PLACseq$start1)
  466. PLACseq$start2 <- as.numeric(PLACseq$start2)
  467. # Convert to GInteractions and clear metadata
  468. loops_GI <- as_ginteractions(PLACseq)
  469. mcols(loops_GI) <- NULL
  470. # Liftover loops
  471. # transformation to hg38 coordinates
  472. ch = import.chain("/cluster/home/irodriguez/software/hg19ToHg38.over.chain")
  473. str(ch[[1]])
  474. # Perform liftOver without flattening
  475. lifted1_list <- liftOver(anchors(loops_GI, type = "first"), ch)
  476. lifted2_list <- liftOver(anchors(loops_GI, type = "second"), ch)
  477. # Get indices where exactly one mapping was returned
  478. valid_idx <- elementNROWS(lifted1_list) == 1 & elementNROWS(lifted2_list) == 1
  479. # Subset to valid interactions
  480. loops_valid <- loops_GI[valid_idx]
  481. # Extract the lifted anchors
  482. lifted1 <- unlist(lifted1_list[valid_idx])
  483. lifted2 <- unlist(lifted2_list[valid_idx])
  484. lifted_loops_GI <- GInteractions(anchor1 = lifted1,
  485. anchor2 = lifted2,
  486. metadata = mcols(loops_valid),
  487. mode = "strict") # optional
  488. # Find overlaps
  489. overlap_anchor1 <- findOverlaps(anchors(lifted_loops_GI, type = "first"), Gencode.V46_promoter)
  490. overlap_anchor2 <- findOverlaps(anchors(lifted_loops_GI, type = "second"), Gencode.V46_promoter)
  491. # Create data.frames of overlaps
  492. df_olap1 <- data.frame(
  493. anchor_id = queryHits(overlap_anchor1),
  494. gene = Gencode.V46_promoter$GeneSymb[subjectHits(overlap_anchor1)]
  495. )
  496. df_olap2 <- data.frame(
  497. anchor_id = queryHits(overlap_anchor2),
  498. gene = Gencode.V46_promoter$GeneSymb[subjectHits(overlap_anchor2)]
  499. )
  500. # Collapse overlapping gene names
  501. collapsed_genes1 <- aggregate(gene ~ anchor_id, df_olap1, function(x) paste(unique(x), collapse = ","))
  502. collapsed_genes2 <- aggregate(gene ~ anchor_id, df_olap2, function(x) paste(unique(x), collapse = ","))
  503. # Initialize columns
  504. mcols(lifted_loops_GI)$PLAC_anchor1_gene <- NA_character_
  505. mcols(lifted_loops_GI)$PLAC_anchor2_gene <- NA_character_
  506. # Assign collapsed gene names
  507. mcols(lifted_loops_GI)$PLAC_anchor1_gene[collapsed_genes1$anchor_id] <-
  508. collapsed_genes1$gene[match(collapsed_genes1$anchor_id, collapsed_genes1$anchor_id)]
  509. mcols(lifted_loops_GI)$PLAC_anchor2_gene[collapsed_genes2$anchor_id] <-
  510. collapsed_genes2$gene[match(collapsed_genes2$anchor_id, collapsed_genes2$anchor_id)]
  511. # Overlap cCREs with anchor1
  512. overlap_cCRE_anchor1 <- findOverlaps(consensus_CREs_ranges,anchors(lifted_loops_GI, type = "first"))
  513. # Overlap cCREs with anchor2
  514. overlap_cCRE_anchor2 <- findOverlaps(consensus_CREs_ranges,anchors(lifted_loops_GI, type = "second"))
  515. # Add gene_name to anchor1 overlaps
  516. consensus_CREs_anchor1 <- consensus_CREs_ranges
  517. mcols(consensus_CREs_anchor1)$Nott_PLAC_anchor_gene <- NA
  518. mcols(consensus_CREs_anchor1)$Nott_PLAC_anchor_gene[queryHits(overlap_cCRE_anchor1)] <- lifted_loops_GI$PLAC_anchor2_gene[subjectHits(overlap_cCRE_anchor1)]
  519. # Add gene_name to anchor2 overlaps
  520. consensus_CREs_anchor2 <- consensus_CREs_ranges
  521. mcols(consensus_CREs_anchor2)$Nott_PLAC_anchor_gene <- NA
  522. mcols(consensus_CREs_anchor2)$Nott_PLAC_anchor_gene[queryHits(overlap_cCRE_anchor2)] <- lifted_loops_GI$PLAC_anchor1_gene[subjectHits(overlap_cCRE_anchor2)]
  523. # Create datafr
  524. consensus_CREs_anchor1_df <- as.data.frame(consensus_CREs_anchor1)
  525. consensus_CREs_anchor2_df <- as.data.frame(consensus_CREs_anchor2)
  526. # Assuming df1 and df2 are the dataframes you want to rbind
  527. df_combined <- bind_rows(consensus_CREs_anchor1_df, consensus_CREs_anchor1_df)
  528. # Remove NA from 'hic_anchor_gene' and collapse by ',' (comma separator)
  529. cCRE_hic_genes <- df_combined %>%
  530. filter(!is.na(Nott_PLAC_anchor_gene)) %>%
  531. group_by(across(-Nott_PLAC_anchor_gene)) %>% # Group by all columns except 'hic_anchor_gene'
  532. summarise(Nott_PLAC_anchor_gene = paste(unique(na.omit(Nott_PLAC_anchor_gene)), collapse = ","), .groups = 'drop')
  533. # Result
  534. cCRE_hic_genes <- as.data.frame(cCRE_hic_genes)
  535. # Merge dataframe
  536. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, cCRE_hic_genes, by = intersect(names(iTF_cCREs_df), names(cCRE_hic_genes)), all.x = TRUE)
  537. #Save files
  538. saveRDS(merged_iTF_cCREs_df,file="/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/iTF_CREs_target_genes.rds")
  539. #############
  540. # monaLisa TF
  541. #############
  542. # monaLisa
  543. monaLisa_iTF_Microglia.LPS.IFNG_vs_iTF_Microglia <- readRDS("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/cCRE_specific_monaLisa_9050_iTF_Microglia.LPS.IFNG_vs_iTF_Microglia_H3K27ac_overlapping_peaks.rds")
  544. monaLisa_iTF_Microglia_vs_iTF_iPSC <- readRDS("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/cCRE_specific_monaLisa_9054_iTF_Microglia_vs_iTF_iPSCs_ATAC_overlapping_peaks.rds")
  545. grl <- c(monaLisa_iTF_Microglia.LPS.IFNG_vs_iTF_Microglia,monaLisa_iTF_Microglia_vs_iTF_iPSC)
  546. grl <- GRangesList(lapply(names(grl), function(nm) {
  547. gr <- grl[[nm]]
  548. mcols(gr)$TF <- nm
  549. gr
  550. }))
  551. unlisted_gr <- unlist(grl)
  552. # Remove row names
  553. names(unlisted_gr) <- NULL
  554. # Convert to data.frame without row names
  555. df <- as.data.frame(unlisted_gr, row.names = NULL)
  556. df <- unique(df[,c(1:5,15)])
  557. # Arrange the data frame by seqnames, start, end, and TF
  558. df_sorted <- df %>%
  559. arrange(seqnames, start, end, TF)
  560. df_summarized <- df_sorted %>%
  561. group_by(seqnames, start, end, width, strand) %>%
  562. summarise(
  563. monaLisa.TF = paste(unique(TF), collapse = ","),
  564. .groups = 'drop'
  565. )
  566. monalisa_gr <- GRanges(df_summarized)
  567. mcols(monalisa_gr)$monaLisa.TF <- toupper(mcols(monalisa_gr)$monaLisa.TF)
  568. # Find overlaps
  569. overlaps <- findOverlaps(consensus_CREs_ranges, monalisa_gr)
  570. # Create a new column with overlapping names
  571. iTF_cCREs_TF <- consensus_CREs_ranges[queryHits(overlaps)]
  572. mcols(iTF_cCREs_TF) <- cbind(mcols(iTF_cCREs_TF), mcols(monalisa_gr[subjectHits(overlaps)]))
  573. iTF_cCREs_TF_df <- as.data.frame(iTF_cCREs_TF)
  574. iTF_cCREs_TF_df <- unique(iTF_cCREs_TF_df)
  575. iTF_cCREs_TF_df_collapsed <- iTF_cCREs_TF_df %>%
  576. group_by(seqnames, start, end) %>%
  577. summarise(monaLisa.TF = paste(
  578. unique(sort(unlist(strsplit(monaLisa.TF, ",")))),
  579. collapse = ","
  580. ), .groups = "drop") %>% as.data.frame()
  581. # Merge dataframe
  582. merged_iTF_cCREs_df <- merge(merged_iTF_cCREs_df, iTF_cCREs_TF_df_collapsed,
  583. by = intersect(names(iTF_cCREs_df), names(iTF_cCREs_TF_df_collapsed)),
  584. all.x = TRUE)
  585. ########################
  586. # Filter target genes based on their expression
  587. ########################
  588. # Load and filter gene expression data
  589. coldata <- read.csv("/cluster/home/irodriguez/Myers_Lab/20240416_Novogene_RNAseq_Library_iTF_iMGLs_Nick_paper/R_analysis/iTF-Microglia_BulkRNA_SampleSheet_phenotype.csv")
  590. gse <- readRDS("batch2/Tables/gse.rds")
  591. tpm <- assay(gse, "abundance")
  592. coldata_subset <- coldata[c(13:15, 19:24),]
  593. tpm_subset <- tpm[, c(13:15, 19:24)]
  594. colnames(tpm_subset) <- coldata_subset$Sample
  595. #rownames(tpm_subset) <- sapply(strsplit(rownames(tpm_subset), "[.]"), `[[`, 1)
  596. # Replace ensgid to gene symbol
  597. gene_map <- readRDS("Tables/Gencode_v46_gene_map.rds")
  598. # Create a lookup table
  599. gene_lookup <- setNames(gene_map$gene_name, gene_map$gene_id)
  600. # Replace ENSG IDs with gene symbols where possible
  601. new_rownames <- gene_lookup[rownames(tpm_subset)]
  602. # Keep ENSG IDs for missing symbols
  603. new_rownames[is.na(new_rownames)] <- rownames(tpm_subset)[is.na(new_rownames)]
  604. # Assign new row names
  605. rownames(tpm_subset) <- new_rownames
  606. # Split columns into groups
  607. iPSC_cols <- tpm_subset[,1:3]
  608. Microglia_cols <- tpm_subset[,4:6]
  609. Microglia_LPS_IFNG_cols <- tpm_subset[,7:9]
  610. # Compute row-wise means for each group
  611. iPSC_mean <- rowMeans(iPSC_cols)
  612. Microglia_mean <- rowMeans(Microglia_cols)
  613. Microglia_LPS_IFNG_mean <- rowMeans(Microglia_LPS_IFNG_cols)
  614. # Get rows where any group has an average expression > 1
  615. iPSC_filtered_rows <- (iPSC_mean > 1)
  616. Microglia_filtered_rows <- (Microglia_mean > 1)
  617. Microglia_LPS_IFNG_filtered_rows <- (Microglia_LPS_IFNG_mean > 1)
  618. # Extract gene names from row names
  619. iPSC_filtered_genes <- rownames(iPSC_cols)[iPSC_filtered_rows]
  620. Microglia_filtered_genes <- rownames(Microglia_cols)[Microglia_filtered_rows]
  621. Microglia_LPS_IFNG_filtered_genes <- rownames(Microglia_LPS_IFNG_cols)[Microglia_LPS_IFNG_filtered_rows]
  622. filtered_genes <- c(iPSC_filtered_genes,Microglia_filtered_genes,Microglia_LPS_IFNG_filtered_genes)
  623. filtered_genes <- unique(filtered_genes)
  624. # Define gene list
  625. gene_list <- iPSC_filtered_genes #iPSCs
  626. gene_list <- Microglia_filtered_genes #Microglia
  627. gene_list <- Microglia_LPS_IFNG_filtered_genes #Microglia_LPS_IFNG
  628. gene_list <- filtered_genes #all
  629. # Define columns that need filtering
  630. gene_cols <- c("DegCre_iTF_iPSCs", "ABC_iTF_iPSCs") # iPSCs
  631. gene_cols <- c("DegCre_iTF_Microglia.diff", "DegCre_iTF_Microglia.untreated", "ABC_iTF_Microglia") # Microglia
  632. gene_cols <- c("DegCre_iTF_Microglia.LPS.IFNG", "ABC_iTF_Microglia.LPS.IFNG") # MicrogliaLPS.IFNG
  633. gene_cols <- c("monaLisa.TF") # filtered_genes
  634. # Function to filter gene symbols, handling "::" cases
  635. filter_gene_symbols <- function(col) {
  636. ifelse(is.na(col), NA,
  637. sapply(strsplit(col, ","), function(genes) {
  638. # Process each gene entry
  639. filtered_genes <- sapply(genes, function(g) {
  640. # Split by "::" and check if any part is in gene_list
  641. parts <- unlist(strsplit(g, "::"))
  642. if (any(parts %in% gene_list)) g else NA
  643. })
  644. # Remove NA entries and collapse back
  645. paste(na.omit(filtered_genes), collapse = ",")
  646. })
  647. )
  648. }
  649. # Apply the filtering function to the specified columns
  650. #filtered_iTF_cCREs_df <- merged_iTF_cCREs_df
  651. filtered_iTF_cCREs_df <- filtered_iTF_cCREs_df %>%
  652. mutate(across(all_of(gene_cols), filter_gene_symbols))
  653. #Save files
  654. saveRDS(filtered_iTF_cCREs_df,file="/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/iTF_CREs_target_genes.rds")
  655. filtered_iTF_cCREs_df <- readRDS("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/iTF_CREs_target_genes.rds")
  656. filtered_iTF_cCREs_df %>%
  657. filter(if_any(everything(), ~ grepl("^GRN", .)))
  658. ########################
  659. # Count cCREs and target genes
  660. ########################
  661. # Format dataframe
  662. iTF_cCREs_split_df <- filtered_iTF_cCREs_df
  663. iTF_cCREs_split_df <- unique(iTF_cCREs_split_df[,c(1:3,6,12:19,21)])
  664. # Remove"Nott_PLAC_anchor_gene" column
  665. iTF_cCREs_split_df <- unique(iTF_cCREs_split_df[,-13])
  666. # List of columns to separate
  667. cols_to_separate <- c(
  668. "closest_tss",
  669. "DegCre_iTF_iPSCs",
  670. "DegCre_iTF_Microglia.diff",
  671. "DegCre_iTF_Microglia.untreated",
  672. "DegCre_iTF_Microglia.LPS.IFNG",
  673. "ABC_iTF_iPSCs",
  674. "ABC_iTF_Microglia",
  675. "ABC_iTF_Microglia.LPS.IFNG",
  676. "Peak2gene.Anderson2023")
  677. cols_to_separate <- c(
  678. "closest_tss",
  679. "DegCre_iTF_iPSCs",
  680. "DegCre_iTF_Microglia.diff",
  681. "DegCre_iTF_Microglia.untreated",
  682. "DegCre_iTF_Microglia.LPS.IFNG",
  683. "ABC_iTF_iPSCs",
  684. "ABC_iTF_Microglia",
  685. "ABC_iTF_Microglia.LPS.IFNG",
  686. "Peak2gene.Anderson2023",
  687. "Nott_PLAC_anchor_gene")
  688. # Apply separate_rows to each specified column
  689. iTF_cCREs_split_long <- iTF_cCREs_split_df
  690. # Convert to data.table
  691. iTF_cCREs_split_long_dt <- as.data.table(iTF_cCREs_split_long)
  692. # Function to split columns into long format
  693. split_columns_to_long <- function(dt, cols_to_separate) {
  694. # Initialize an empty list to store the long-format data
  695. long_dt_list <- list()
  696. # Iterate through each column you want to separate
  697. for (col in cols_to_separate) {
  698. # For each column, split the comma-separated values into separate rows
  699. temp_dt <- dt[!is.na(get(col)) & get(col) != "",
  700. .(seqnames, start, end,
  701. target_gene = unlist(tstrsplit(get(col), ",", fixed = TRUE)),
  702. Mapping = col)
  703. ]
  704. # Append the processed data.table chunk to the list
  705. long_dt_list[[col]] <- temp_dt
  706. }
  707. # Combine all the chunks into one final long-format data.table
  708. final_long_dt <- rbindlist(long_dt_list, fill = TRUE)
  709. # Order the final data.table by seqnames and start
  710. setorder(final_long_dt, seqnames, start)
  711. return(final_long_dt)
  712. }
  713. # Apply the function to your data.table
  714. iTF_cCREs_split_long_dt <- split_columns_to_long(iTF_cCREs_split_long_dt, cols_to_separate)
  715. iTF_cCREs_split_long_dt <-unique(iTF_cCREs_split_long_dt)
  716. # View the first few rows of the transformed data
  717. head(iTF_cCREs_split_long_dt)
  718. # Remove NA
  719. iTF_cCREs_clean <- iTF_cCREs_split_long_dt[complete.cases(iTF_cCREs_split_long_dt),]
  720. iTF_cCREs_clean <- iTF_cCREs_clean %>% distinct()
  721. iTF_cCREs_clean <- iTF_cCREs_clean %>%
  722. mutate(cell.type = case_when(
  723. grepl("iTF_iPSCs", Mapping) ~ "iTF-iPSCs",
  724. grepl("iTF_Microglia$", Mapping) ~ "iTF-Microglia",
  725. grepl("iTF_Microglia.diff", Mapping) ~ "iTF-Microglia",
  726. grepl("iTF_Microglia.untreated", Mapping) ~ "iTF-Microglia",
  727. grepl("LPS.IFNG", Mapping) ~ "iTF-Microglia LPS+IFNG",
  728. grepl("Anderson2023", Mapping) ~ "Brain microglia",
  729. TRUE ~ NA_character_ # For rows that don't match any condition
  730. ))
  731. iTF_cCREs_clean <- iTF_cCREs_clean %>%
  732. mutate(mapping = case_when(
  733. grepl("DegCre", Mapping) ~ "DegCre",
  734. grepl("ABC_iTF", Mapping) ~ "ABC",
  735. grepl("closest_tss", Mapping) ~ "closest tss",
  736. grepl("Peak2gene", Mapping) ~ "Brain microglia link",
  737. TRUE ~ NA_character_ # For rows that don't match any condition
  738. ))
  739. iTF_cCREs_clean <- iTF_cCREs_clean %>%
  740. mutate(mapping = case_when(
  741. grepl("DegCre", Mapping) ~ "DegCre",
  742. grepl("ABC_iTF", Mapping) ~ "ABC",
  743. grepl("closest_tss", Mapping) ~ "closest tss",
  744. grepl("Peak2gene", Mapping) ~ "Brain microglia link",
  745. grepl("Nott", Mapping) ~ "PLAC-seq (Nott)",
  746. TRUE ~ NA_character_ # For rows that don't match any condition
  747. ))
  748. iTF_cCREs_clean$cell.type <- as.factor(iTF_cCREs_clean$cell.type)
  749. iTF_cCREs_clean$mapping <- as.factor(iTF_cCREs_clean$mapping)
  750. #iTF_cCREs_clean <- unique(iTF_cCREs_clean[,-5])
  751. iTF_cCREs_class <- iTF_cCREs_clean
  752. # Split the data by cell.type
  753. cell_type_list <- split(iTF_cCREs_clean, iTF_cCREs_clean$cell.type)
  754. iTF_cCREs_class_gr <- GRanges(iTF_cCREs_class)
  755. # Overlap with specific cell peaks
  756. overlap_with_metadata <- function(query, subject) {
  757. # Find overlaps between query and subject
  758. hits <- findOverlaps(query, subject)
  759. # Extract overlapping ranges
  760. query_overlaps <- query[queryHits(hits)]
  761. subject_overlaps <- subject[subjectHits(hits)]
  762. # Combine metadata columns
  763. combined_mcols <- cbind(mcols(query_overlaps), mcols(subject_overlaps))
  764. # Create a new GRanges object with combined metadata
  765. result <- query_overlaps
  766. mcols(result) <- combined_mcols
  767. return(result)
  768. }
  769. # Assuming ABC_iTF_list is a named list of GRanges objects
  770. overlapped_list <- lapply(iTF_CREs_ENCODE, function(gr) overlap_with_metadata(iTF_cCREs_class_gr, gr))
  771. iTF_iPSCs_class <- as.data.frame(overlapped_list$iTF_iPSCs)
  772. iTF_Microglia_class <- as.data.frame(overlapped_list$iTF_Microglia)
  773. iTF_Microglia.LPS.IFNG_class <- as.data.frame(overlapped_list$iTF_Microglia.LPS.IFNG)
  774. iTF_iPSCs_closest.tss <- iTF_iPSCs_class[iTF_iPSCs_class$mapping == "closest tss",]
  775. iTF_iPSCs_DegCre <- iTF_iPSCs_class[iTF_iPSCs_class$cell.type == "iTF-iPSCs" & iTF_iPSCs_class$mapping == "DegCre",]
  776. iTF_iPSCs_ABC <- iTF_iPSCs_class[iTF_iPSCs_class$cell.type == "iTF-iPSCs" & iTF_iPSCs_class$mapping == "ABC",]
  777. iTF_iPSCs_Brain.MG.link <- iTF_iPSCs_class[iTF_iPSCs_class$mapping == "Brain microglia link",]
  778. #iTF_iPSCs_PLAC <- iTF_iPSCs_class[iTF_iPSCs_class$mapping == "PLAC-seq (Nott)",]
  779. iTF_Microglia_closest.tss <- iTF_Microglia_class[iTF_Microglia_class$mapping == "closest tss",]
  780. iTF_Microglia.diff_DegCre <- iTF_Microglia_class[iTF_Microglia_class$Mapping == "DegCre_iTF_Microglia.diff",]
  781. iTF_Microglia.unt_DegCre <- iTF_Microglia_class[iTF_Microglia_class$Mapping == "DegCre_iTF_Microglia.untreated",]
  782. iTF_Microglia_ABC <- iTF_Microglia_class[iTF_Microglia_class$Mapping == "ABC_iTF_Microglia",]
  783. iTF_Microglia_Brain.MG.link <- iTF_Microglia_class[iTF_Microglia_class$mapping == "Brain microglia link",]
  784. #iTF_Microglia_PLAC <- iTF_Microglia_class[iTF_Microglia_class$mapping == "PLAC-seq (Nott)",]
  785. iTF_Microglia.LPS.IFNG_closest.tss <- iTF_Microglia.LPS.IFNG_class[iTF_Microglia.LPS.IFNG_class$Mapping == "closest_tss",]
  786. iTF_Microglia.LPS.IFNG_DegCre <- iTF_Microglia.LPS.IFNG_class[iTF_Microglia.LPS.IFNG_class$Mapping == "DegCre_iTF_Microglia.LPS.IFNG",]
  787. iTF_Microglia.LPS.IFNG_ABC <- iTF_Microglia.LPS.IFNG_class[iTF_Microglia.LPS.IFNG_class$Mapping == "ABC_iTF_Microglia.LPS.IFNG",]
  788. iTF_Microglia.LPS.IFNG_Brain.MG.link <- iTF_Microglia.LPS.IFNG_class[iTF_Microglia.LPS.IFNG_class$mapping == "Brain microglia link",]
  789. #iTF_Microglia.LPS.IFNG_PLAC <- iTF_Microglia.LPS.IFNG_class[iTF_Microglia.LPS.IFNG_class$mapping == "PLAC-seq (Nott)",]
  790. dim(unique(iTF_iPSCs_closest.tss[,1:3]))
  791. length(unique(iTF_iPSCs_closest.tss[,6]))
  792. dim(unique(iTF_iPSCs_DegCre[,1:3])) #42753
  793. length(unique(iTF_iPSCs_DegCre[,6])) #6645
  794. dim(unique(iTF_iPSCs_ABC[,1:3])) #39486
  795. length(unique(iTF_iPSCs_ABC[,6])) #14453
  796. dim(unique(iTF_iPSCs_Brain.MG.link[,1:3])) #16175
  797. length(unique(iTF_iPSCs_Brain.MG.link[,6])) #11613
  798. dim(unique(iTF_iPSCs_PLAC[,1:3])) #16175
  799. length(unique(iTF_iPSCs_PLAC[,6])) #11613
  800. dim(unique(iTF_Microglia_closest.tss[,1:3])) #62011
  801. length(unique(iTF_Microglia_closest.tss[,6])) #26899
  802. dim(unique(iTF_Microglia.diff_DegCre[,1:3])) #22377
  803. length(unique(iTF_Microglia.diff_DegCre[,6])) #9885
  804. dim(unique(iTF_Microglia.unt_DegCre[,1:3])) #22377
  805. length(unique(iTF_Microglia.unt_DegCre[,6])) #9885
  806. dim(unique(iTF_Microglia_ABC[,1:3])) #43971
  807. length(unique(iTF_Microglia_ABC[,6])) #15724
  808. dim(unique(iTF_Microglia_Brain.MG.link[,1:3])) #23788
  809. length(unique(iTF_Microglia_Brain.MG.link[,6])) #12240
  810. dim(unique(iTF_Microglia_PLAC[,1:3])) #16175
  811. length(unique(iTF_Microglia_PLAC[,6])) #11613
  812. dim(unique(iTF_Microglia.LPS.IFNG_closest.tss[,1:3])) #62470
  813. length(unique(iTF_Microglia.LPS.IFNG_closest.tss[,6])) #26387
  814. dim(unique(iTF_Microglia.LPS.IFNG_DegCre[,1:3])) #26298
  815. length(unique(iTF_Microglia.LPS.IFNG_DegCre[,6])) #10020
  816. dim(unique(iTF_Microglia.LPS.IFNG_ABC[,1:3])) #39913
  817. length(unique(iTF_Microglia.LPS.IFNG_ABC[,6])) #15695
  818. dim(unique(iTF_Microglia.LPS.IFNG_Brain.MG.link[,1:3])) #23861
  819. length(unique(iTF_Microglia.LPS.IFNG_Brain.MG.link[,6])) #12191
  820. dim(unique(iTF_Microglia.LPS.IFNG_PLAC[,1:3])) #16175
  821. length(unique(iTF_Microglia.LPS.IFNG_PLAC[,6])) #11613
  822. ########################
  823. #Cluster profiler target genes
  824. ########################
  825. # Load required packages
  826. library(clusterProfiler)
  827. library(ReactomePA)
  828. library(ggplot2)
  829. library(dplyr)
  830. library(ComplexUpset)
  831. library(purrr)
  832. # Consolidate gene lists
  833. gene_lists <- list(
  834. iTF_iPSCs = list(
  835. `closest TSS` = unique(iTF_iPSCs_closest.tss[, 6]),
  836. DegCre = unique(iTF_iPSCs_DegCre[, 6]),
  837. ABC = unique(iTF_iPSCs_ABC[, 6]),
  838. `Brain microglia link` = unique(iTF_iPSCs_Brain.MG.link[, 6])#,
  839. #`PLAC-seq (Nott)` = unique(iTF_iPSCs_PLAC[, 6])
  840. ),
  841. iTF_Microglia = list(
  842. `closest TSS` = unique(iTF_Microglia_closest.tss[, 6]),
  843. DegCre.diff = unique(iTF_Microglia.diff_DegCre[, 6]),
  844. DegCre.unt = unique(iTF_Microglia.unt_DegCre[, 6]),
  845. ABC = unique(iTF_Microglia_ABC[, 6]),
  846. `Brain microglia link` = unique(iTF_Microglia_Brain.MG.link[, 6])#,
  847. #`PLAC-seq (Nott)` = unique(iTF_Microglia_PLAC[, 6])
  848. ),
  849. iTF_Microglia_LPS_IFNG = list(
  850. `closest TSS` = unique(iTF_Microglia.LPS.IFNG_closest.tss[, 6]),
  851. DegCre = unique(iTF_Microglia.LPS.IFNG_DegCre[, 6]),
  852. ABC = unique(iTF_Microglia.LPS.IFNG_ABC[, 6]),
  853. `Brain microglia link` = unique(iTF_Microglia.LPS.IFNG_Brain.MG.link[, 6])#,
  854. #`PLAC-seq (Nott)` = unique(iTF_Microglia.LPS.IFNG_PLAC[, 6])
  855. )
  856. )
  857. # Function to map gene names/IDs to Entrez IDs
  858. convert_to_entrez <- function(gene_vector, gene_map) {
  859. gene_df <- data.frame(gene_name = gene_vector, stringsAsFactors = FALSE)
  860. # Ensure gene_map has unique mappings
  861. gene_map_filtered <- gene_map %>%
  862. select(gene_name, entrez_id) %>%
  863. distinct() %>%
  864. filter(!is.na(entrez_id)) # Remove NA Entrez IDs
  865. # Perform the mapping
  866. mapped_genes <- left_join(gene_df, gene_map_filtered, by = "gene_name")
  867. # Return only Entrez IDs (removing NAs)
  868. return(na.omit(mapped_genes$entrez_id))
  869. }
  870. # Apply function to each list element
  871. gene_lists_entrez <- map_depth(gene_lists, 2, ~convert_to_entrez(.x, gene_map))
  872. # Check structure of converted lists
  873. str(gene_lists_entrez)
  874. # Perform Reactome enrichment analysis and save results separately
  875. csv_file_paths <- list()
  876. for (cell_type in names(gene_lists_entrez)) {
  877. reactome_results <- compareCluster(
  878. geneCluster = gene_lists_entrez[[cell_type]],
  879. fun = "enrichPathway",
  880. pvalueCutoff = 0.05,
  881. readable = TRUE
  882. )
  883. # Save results to CSV
  884. csv_file_path <- paste0("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/Reactome_Enrichment_target_gene_", cell_type, ".csv")
  885. write.csv(reactome_results@compareClusterResult, csv_file_path, row.names = FALSE)
  886. csv_file_paths[[cell_type]] <- csv_file_path
  887. }
  888. # Combine all results for dot plot
  889. all_reactome_results <- do.call(rbind, lapply(csv_file_paths, read.csv))
  890. all_reactome_results$mapped.cell <- ifelse(grepl("iTF_iPSCs", rownames(all_reactome_results)), "iTF-iPSCs",
  891. ifelse(grepl("iTF_Microglia_LPS_IFNG", rownames(all_reactome_results)), "iTF-Microglia\nLPS+IFNG",
  892. ifelse(grepl("iTF_Microglia.", rownames(all_reactome_results)), "iTF-Microglia", NA)))
  893. # Define pathways of interest
  894. pathways <- c(
  895. "RHO GTPase cycle","Translation","S Phase",
  896. "Transcriptional regulation of pluripotent stem cells","Neuronal System",
  897. "Neutrophil degranulation","Inflammasomes","Signaling by Interleukins",
  898. "Interferon gamma signaling")
  899. # Subset Reactome results
  900. reactome_results_subset <- all_reactome_results %>% filter(Description %in% pathways)
  901. # Ensure Cluster is a factor with the desired order
  902. reactome_results_subset$Cluster <- factor(reactome_results_subset$Cluster, levels = c("closest TSS", "DegCre",
  903. "DegCre.diff","DegCre.unt",
  904. "ABC", "Brain microglia link"#,
  905. #"PLAC-seq (Nott)"
  906. ))
  907. # Order pathways as a factor
  908. reactome_results_subset$Description <- factor(reactome_results_subset$Description, levels = rev(pathways))
  909. pdf("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Figures/Reactome_Pathway_target_genes_DotPlot.pdf", width = 11, height = 9)
  910. #pdf("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Figures/Reactome_Pathway_target_genes_DotPlot.pdf", width = 10, height = 12)
  911. #pdf("/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Figures/Reactome_Pathway_target_genes_DotPlot.pdf", width = 14, height = 12)
  912. ggplot(reactome_results_subset, aes(x = Cluster, y = Description, size = Count, fill = p.adjust)) +
  913. geom_point(shape = 21, color = "black", stroke = 0.5) + # Black outline for each dot
  914. scale_fill_gradient(low = "blue", high = "red") +
  915. facet_wrap(~ mapped.cell, scales = "free_x") +
  916. theme_minimal() +
  917. labs(title = NULL, x = NULL, y = NULL) +
  918. theme(
  919. text = element_text(size = 16),
  920. axis.text.x = element_text(size = 14, angle = 45, hjust = 1),
  921. axis.text.y = element_text(size = 16),
  922. plot.title = element_text(size = 18, face = "bold"),
  923. strip.background = element_rect(fill = "grey80", color = "black"), # Grey background with black border for facet title
  924. strip.text = element_text(size = 16, face = "bold"),
  925. panel.border = element_rect(color = "black", fill = NA, linewidth = 1) # Outline around each facet
  926. )
  927. dev.off()
  928. ########################
  929. #Overlap CRE-gene pair models
  930. ########################
  931. iTF_cCREs_split_df <- unique(filtered_iTF_cCREs_df[, c(1:3,6,12:19,21)])
  932. iTF_cCREs_split_df <- unique(filtered_iTF_cCREs_df[, c(1:3,6,12:19)])
  933. # List of columns to separate
  934. cols_to_separate <- c(
  935. "closest_tss", "DegCre_iTF_iPSCs", "DegCre_iTF_Microglia.diff",
  936. "DegCre_iTF_Microglia.untreated",
  937. "DegCre_iTF_Microglia.LPS.IFNG", "ABC_iTF_iPSCs", "ABC_iTF_Microglia",
  938. "ABC_iTF_Microglia.LPS.IFNG", "Peak2gene.Anderson2023"#, "Nott_PLAC_anchor_gene"
  939. )
  940. # Convert to data.table
  941. iTF_cCREs_split_long_dt <- as.data.table(iTF_cCREs_split_df)
  942. # Function to split columns into long format
  943. split_columns_to_long <- function(dt, cols_to_separate) {
  944. long_dt_list <- lapply(cols_to_separate, function(col) {
  945. dt[!is.na(get(col)) & get(col) != "", .(
  946. seqnames, start, end,
  947. target_gene = unlist(tstrsplit(get(col), ",", fixed = TRUE)),
  948. Mapping = col
  949. )]
  950. })
  951. final_long_dt <- rbindlist(long_dt_list, fill = TRUE)
  952. setorder(final_long_dt, seqnames, start)
  953. unique(final_long_dt)
  954. }
  955. # Apply function
  956. iTF_cCREs_clean <- split_columns_to_long(iTF_cCREs_split_long_dt, cols_to_separate)
  957. iTF_cCREs_clean <- iTF_cCREs_clean[complete.cases(iTF_cCREs_clean),] %>% distinct()
  958. # Process promoters
  959. gencode_promoters <- gtf_df_filtered %>%
  960. dplyr::select(seqnames, promoter_start, promoter_end, strand, GeneID, GeneSymb) %>%
  961. unique() %>%
  962. filter(seqnames != "chrM")
  963. promoters_V46 <- GRanges(gencode_promoters[, c("seqnames", "promoter_start", "promoter_end", "GeneSymb")])
  964. mcols(promoters_V46)$class <- "promoter"
  965. # Merge with promoters
  966. iTF_cCREs_clean_promoter <- merge(iTF_cCREs_clean, gencode_promoters,
  967. by.x = "target_gene", by.y = "GeneSymb",
  968. allow.cartesian = TRUE) %>%
  969. dplyr::select(seqnames = seqnames.x, start, end, target_gene, Mapping)
  970. # Convert to GRanges
  971. iTF_cCREs_clean_gr <- GRanges(iTF_cCREs_clean_promoter)
  972. # Find overlaps
  973. olap_2KB <- findOverlaps(iTF_cCREs_clean_gr, promoters_V46)
  974. cCREs_2KB <- iTF_cCREs_clean_gr[queryHits(olap_2KB)]
  975. mcols(cCREs_2KB) <- cbind(mcols(cCREs_2KB), mcols(promoters_V46[subjectHits(olap_2KB)]))
  976. # Convert to DataFrame
  977. cCREs_2KB_df <- as.data.frame(cCREs_2KB) %>%
  978. dplyr::select(seqnames, start, end, GeneSymb) %>%
  979. distinct() %>%
  980. mutate(class = "promoter") %>%
  981. arrange(seqnames, start)
  982. # Save results
  983. saveRDS(cCREs_2KB_df, "/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Tables/iTF_cCREs_promoter_2KB.rds")
  984. # Merge and classify for distance
  985. iTF_cCREs_clean_prom <- merge(as.data.frame(iTF_cCREs_clean_gr), cCREs_2KB_df,
  986. by = c("seqnames", "start", "end"), all.x = TRUE) %>%
  987. mutate(
  988. cCreType = case_when(
  989. class == "promoter" & target_gene == GeneSymb ~ "SelfPromoter",
  990. class == "promoter" & target_gene != GeneSymb ~ "OtherPromoter",
  991. TRUE ~ "enhancer"
  992. ),
  993. cell.type = case_when(
  994. grepl("iTF_iPSCs", Mapping) ~ "iTF-iPSCs",
  995. grepl("iTF_Microglia$", Mapping) ~ "iTF-Microglia",
  996. grepl("LPS.IFNG", Mapping) ~ "iTF-Microglia LPS+IFNG",
  997. grepl("Anderson2023", Mapping) ~ "Brain microglia",
  998. #grepl("Nott_PLAC", Mapping) ~ "Ex vivo microglia",
  999. TRUE ~ NA_character_
  1000. ),
  1001. mapping = case_when(
  1002. grepl("DegCre", Mapping) ~ "DegCre",
  1003. grepl("ABC_iTF", Mapping) ~ "ABC",
  1004. grepl("closest_tss", Mapping) ~ "closest TSS",
  1005. grepl("Peak2gene", Mapping) ~ "Brain microglia link",
  1006. #grepl("Nott", Mapping) ~ "PLAC-seq (Nott)",
  1007. TRUE ~ NA_character_
  1008. )
  1009. ) %>%
  1010. mutate(across(c(cCreType, cell.type, mapping), as.factor))
  1011. # Merge and classify for upset plot
  1012. iTF_cCREs_clean_prom <- merge(as.data.frame(iTF_cCREs_clean_gr), cCREs_2KB_df,
  1013. by = c("seqnames", "start", "end"), all.x = TRUE) %>%
  1014. mutate(
  1015. cCreType = case_when(
  1016. class == "promoter" & target_gene == GeneSymb ~ "SelfPromoter",
  1017. class == "promoter" & target_gene != GeneSymb ~ "OtherPromoter",
  1018. TRUE ~ "enhancer"
  1019. )
  1020. ) %>%
  1021. mutate(
  1022. cell.type = case_when(
  1023. grepl("iTF_iPSCs", Mapping) ~ "iTF-iPSCs",
  1024. grepl("iTF_Microglia$", Mapping) ~ "iTF-Microglia",
  1025. grepl("iTF_Microglia.diff", Mapping) ~ "iTF-Microglia",
  1026. grepl("iTF_Microglia.untreated", Mapping) ~ "iTF-Microglia",
  1027. grepl("LPS.IFNG", Mapping) ~ "iTF-Microglia LPS+IFNG",
  1028. grepl("Anderson2023", Mapping) ~ "Brain microglia",
  1029. #grepl("Nott_PLAC", Mapping) ~ "Ex vivo microglia",
  1030. TRUE ~ NA_character_
  1031. ),
  1032. mapping = case_when(
  1033. grepl("DegCre", Mapping) ~ "DegCre",
  1034. grepl("ABC_iTF", Mapping) ~ "ABC",
  1035. grepl("closest_tss", Mapping) ~ "closest TSS",
  1036. grepl("Peak2gene", Mapping) ~ "Brain microglia link",
  1037. #grepl("Nott", Mapping) ~ "PLAC-seq (Nott)",
  1038. TRUE ~ NA_character_
  1039. )
  1040. ) %>%
  1041. mutate(across(c(cCreType, cell.type, mapping), as.factor))
  1042. # Convert to GRanges
  1043. iTF_cCREs_class_gr <- GRanges(iTF_cCREs_clean_prom[, c(1:7, 10, 12)])
  1044. # Overlap function
  1045. overlap_with_metadata <- function(query, subject) {
  1046. hits <- findOverlaps(query, subject)
  1047. query_overlaps <- query[queryHits(hits)]
  1048. subject_overlaps <- subject[subjectHits(hits)]
  1049. result <- query_overlaps
  1050. mcols(result) <- cbind(mcols(query_overlaps), mcols(subject_overlaps))
  1051. result
  1052. }
  1053. # Process overlaps
  1054. overlapped_list <- lapply(iTF_CREs_ENCODE, function(gr) overlap_with_metadata(iTF_cCREs_class_gr, gr))
  1055. # Extract specific cell type classes
  1056. iTF_iPSCs_class <- as.data.frame(overlapped_list$iTF_iPSCs) %>%
  1057. filter(Mapping %in% c(#"Nott_PLAC_anchor_gene",
  1058. "DegCre_iTF_iPSCs", "ABC_iTF_iPSCs", "Peak2gene.Anderson2023", "closest_tss")) %>%
  1059. distinct()
  1060. iTF_Microglia_class <- as.data.frame(overlapped_list$iTF_Microglia) %>%
  1061. filter(Mapping %in% c(#"Nott_PLAC_anchor_gene",
  1062. "DegCre_iTF_Microglia.diff", "DegCre_iTF_Microglia.untreated", "ABC_iTF_Microglia", "Peak2gene.Anderson2023", "closest_tss")) %>%
  1063. distinct()
  1064. iTF_Microglia.LPS.IFNG_class <- as.data.frame(overlapped_list$iTF_Microglia.LPS.IFNG) %>%
  1065. filter(Mapping %in% c(#"Nott_PLAC_anchor_gene",
  1066. "DegCre_iTF_Microglia.LPS.IFNG", "ABC_iTF_Microglia.LPS.IFNG", "Peak2gene.Anderson2023", "closest_tss")) %>%
  1067. distinct()
  1068. # Function to process data
  1069. process_data <- function(df, dataset_name) {
  1070. df <- df %>%
  1071. group_by(across(-c(cCreType))) %>%
  1072. filter(!(cCreType == "OtherPromoter" & "SelfPromoter" %in% cCreType)) %>%
  1073. ungroup() %>%
  1074. mutate(CREtoGene = paste(seqnames, start, end, target_gene, sep = "_"),
  1075. Dataset = dataset_name) %>%
  1076. as.data.frame()
  1077. return(df)
  1078. }
  1079. # Process all datasets
  1080. iTF_cCRE_gene_pair_iPSCs <- process_data(iTF_iPSCs_class, "iTF-iPSCs")
  1081. iTF_cCRE_gene_pair_Microglia <- process_data(iTF_Microglia_class, "iTF-Microglia")
  1082. iTF_cCRE_gene_pair_Microglia_LPS_IFNG <- process_data(iTF_Microglia.LPS.IFNG_class, "iTF-Microglia LPS+IFNG")
  1083. # Combine datasets
  1084. combined_df <- bind_rows(iTF_cCRE_gene_pair_iPSCs,
  1085. iTF_cCRE_gene_pair_Microglia,
  1086. iTF_cCRE_gene_pair_Microglia_LPS_IFNG)
  1087. # Compute distances with correct sign
  1088. cCRE_gr <- GRanges(
  1089. seqnames = combined_df$seqnames,
  1090. ranges = IRanges(start = combined_df$start, end = combined_df$end),
  1091. strand = "*",
  1092. target_gene = combined_df$target_gene
  1093. )
  1094. # Match TSS positions based on the target gene
  1095. matched_tss <- Gencode.V46[match(cCRE_gr$target_gene, Gencode.V46$GeneSymb)]
  1096. # Compute raw distances
  1097. distances <- distance(cCRE_gr, matched_tss)
  1098. # Determine the direction based on gene strand
  1099. strand_info <- as.character(strand(matched_tss))
  1100. # Adjust distances: negative for upstream (on + strand), positive for downstream
  1101. signed_distances <- ifelse(
  1102. strand_info == "+",
  1103. start(cCRE_gr) - start(matched_tss),
  1104. start(matched_tss) - start(cCRE_gr)
  1105. )
  1106. # Assign distances back
  1107. combined_df$distance_to_TSS <- distances
  1108. combined_df$signed_distances <- signed_distances
  1109. # Change sign in distances based on strand
  1110. combined_df$distance_to_TSS <- ifelse(
  1111. combined_df$distance_to_TSS == 0,
  1112. 0,
  1113. ifelse(
  1114. combined_df$signed_distances < 0,
  1115. abs(combined_df$distance_to_TSS) * -1,
  1116. abs(combined_df$distance_to_TSS)
  1117. )
  1118. )
  1119. # Mapping column transformation
  1120. combined_df <- combined_df %>%
  1121. mutate(Mapping = case_when(
  1122. grepl("closest", Mapping) ~ "closest TSS",
  1123. grepl("DegCre", Mapping) ~ "DegCre",
  1124. grepl("ABC", Mapping) ~ "ABC",
  1125. grepl("Anderson2023", Mapping) ~ "Brain microglia link",
  1126. #grepl("Nott", Mapping) ~ "PLAC-seq (Nott)",
  1127. TRUE ~ NA_character_
  1128. ))
  1129. combined_df <- unique(combined_df[,-7])
  1130. # Order
  1131. orderMapping <- c(#"PLAC-seq (Nott)",
  1132. "DegCre","ABC","Brain microglia link", "closest TSS")
  1133. combined_df$mapping <- factor(combined_df$mapping, levels = rev(orderMapping))
  1134. # Define colors
  1135. custom_colors <- c(
  1136. #"PLAC-seq (Nott)" = "#000000",
  1137. "Brain microglia link" = "#009E73",
  1138. "DegCre" = "#F0E442",
  1139. "ABC" = "#0072B2",
  1140. "closest TSS" = "#D55E00"
  1141. )
  1142. # Define your custom linetypes per mapping
  1143. custom_linetypes <- c(
  1144. "DegCre" = "dotdash",
  1145. "ABC" = "dashed",
  1146. "closest TSS" = "solid",
  1147. "Brain microglia link" = "dotted"#,
  1148. #"PLAC-seq (Nott)" = "twodash"
  1149. )
  1150. # Create plot
  1151. library(scales) # For custom transformation
  1152. # Define output files
  1153. Distance_plot_file_log <- "/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Figures/Distance_CREs_target_genes_log.pdf"
  1154. # Define a signed log transformation
  1155. signed_log_trans <- trans_new(
  1156. name = "signed_log10",
  1157. transform = function(x) sign(x) * log10(abs(x) + 1),
  1158. inverse = function(x) sign(x) * (10^abs(x) - 1)
  1159. )
  1160. # Manually define tick positions (log scale, symmetric around zero)
  1161. log_ticks <- c(-1e5, -1e3, 0, 1e3, 1e5)
  1162. # Create plot
  1163. pdf(Distance_plot_file_log, width=12, height=5)
  1164. # Loop over each unique dataset to generate and plot individually
  1165. ggplot(combined_df, aes(x = distance_to_TSS, color = mapping, linetype = mapping)) +
  1166. geom_density(linewidth = 1.2) +
  1167. facet_wrap(~ Dataset) +
  1168. scale_x_continuous(trans = signed_log_trans, breaks = log_ticks) +
  1169. scale_color_manual(values = custom_colors) +
  1170. scale_linetype_manual(values = custom_linetypes) +
  1171. theme_minimal() +
  1172. theme(
  1173. text = element_text(size = 16),
  1174. axis.text.x = element_text(angle = 45, hjust = 1, size = 14),
  1175. axis.text.y = element_text(size = 14),
  1176. strip.text = element_text(size = 18, face = "bold"),
  1177. legend.text = element_text(size = 14)
  1178. ) +
  1179. labs(
  1180. x = "cCRE distance to target TSS",
  1181. y = "Density",
  1182. color = "Mapping",
  1183. linetype = "Mapping"
  1184. )
  1185. dev.off()
  1186. #######################
  1187. # Overlap target genes
  1188. #######################
  1189. library(ComplexUpset)
  1190. library(ggplot2)
  1191. # Convert to the appropriate format
  1192. upset_data <- iTF_cCRE_gene_pair_iPSCs %>%
  1193. mutate(CREtoGene = factor(CREtoGene))
  1194. upset_data <- iTF_cCRE_gene_pair_Microglia %>%
  1195. mutate(CREtoGene = factor(CREtoGene))
  1196. upset_data <- iTF_cCRE_gene_pair_Microglia_LPS_IFNG %>%
  1197. mutate(CREtoGene = factor(CREtoGene))
  1198. # Upset plot
  1199. upset_data_subset <- unique(upset_data[,c(1:5,8:11)])
  1200. upset_data_collapsed <- upset_data_subset %>%
  1201. group_by(seqnames, start, end, width, strand, cCreType, cell.type, CREtoGene) %>%
  1202. summarise(mapping = paste(mapping, collapse = ","), .groups = "drop")
  1203. upset_data_collapsed <- upset_data_collapsed %>%
  1204. mutate(
  1205. `closest TSS` = ifelse(grepl("closest", mapping), 1, 0),
  1206. ABC = ifelse(grepl("ABC", mapping), 1, 0),
  1207. DegCre = ifelse(grepl("DegCre", mapping), 1, 0),
  1208. `Brain microglia link` = ifelse(grepl("Brain", mapping), 1, 0)#,
  1209. #`PLAC-seq (Nott)` = ifelse(grepl("Nott", mapping), 1, 0),
  1210. ) %>% as.data.frame()
  1211. cats <- colnames(upset_data_collapsed)[10:13]
  1212. orderBind <- c("SelfPromoter","OtherPromoter","enhancer")
  1213. orderBind <- rev(orderBind)
  1214. upset_data_collapsed$cCreType <- factor(upset_data_collapsed$cCreType,levels = orderBind)
  1215. Upset_plot_file = "/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Figures/Upset_CREs_target_genes_iTF_iPSCs.pdf"
  1216. Upset_plot_file = "/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Figures/Upset_CREs_target_genes_iTF_Microglia.pdf"
  1217. Upset_plot_file = "/cluster/home/irodriguez/Myers_Lab/KOLF2.1J-iTF_iMGLs_Nick_paper/manuscript/batch2/Figures/Upset_CREs_target_genes_iTF_Microglia_LPS_IFNG.pdf"
  1218. library(grid)
  1219. pdf(Upset_plot_file, width = 10, height = 5)
  1220. p <- upset(
  1221. upset_data_collapsed,
  1222. cats,
  1223. n_intersections = 10,
  1224. # Custom themes
  1225. themes = upset_modify_themes(list(
  1226. 'intersections_matrix' = theme(text = element_text(size = 16))
  1227. )),
  1228. # Customize intersection size bar
  1229. base_annotations = list(
  1230. 'cCREs-TargetGene' = intersection_size(
  1231. counts = FALSE,
  1232. mapping = aes(fill = cCreType)
  1233. ) +
  1234. scale_fill_manual(values = c(
  1235. "SelfPromoter" = "red1",
  1236. "OtherPromoter" = "purple",
  1237. "enhancer" = "gold"
  1238. )) +
  1239. theme(
  1240. text = element_text(size = 18),
  1241. axis.text.y = element_text(size = 14),
  1242. legend.position = "top",
  1243. panel.grid = element_blank()
  1244. )
  1245. ),
  1246. # Customize set size bar
  1247. set_sizes = (
  1248. upset_set_size() +
  1249. theme(
  1250. axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, size = 16),
  1251. text = element_blank()
  1252. )
  1253. ),
  1254. width_ratio = 0.2,
  1255. # Highlight specific sets
  1256. queries = list(
  1257. #upset_query(set = 'PLAC-seq (Nott)', fill = '#000000'),
  1258. upset_query(set = 'Brain microglia link', fill = '#009E73'),
  1259. upset_query(set = 'ABC', fill = '#0072B2'),
  1260. upset_query(set = 'DegCre', fill = '#F0E442'),
  1261. upset_query(set = 'closest TSS', fill = '#D55E00')
  1262. )
  1263. )
  1264. # Ensure the plot is printed to the device and only one page is used
  1265. print(p)
  1266. dev.off()
  1267. # Calculate average number of genes per cCRE
  1268. genes_per_cCRE <- upset_data %>%
  1269. group_by(Mapping, seqnames, start, end) %>%
  1270. summarise(num_genes = n_distinct(target_gene), .groups = "drop") %>%
  1271. group_by(Mapping) %>%
  1272. summarise(avg_genes_per_cCRE = mean(num_genes))
  1273. # Calculate average number of cCREs per gene
  1274. cCREs_per_gene <- upset_data %>%
  1275. group_by(Mapping, target_gene) %>%
  1276. summarise(num_cCREs = n_distinct(paste(seqnames, start, end, sep = "_")), .groups = "drop") %>%
  1277. group_by(Mapping) %>%
  1278. summarise(avg_cCREs_per_gene = mean(num_cCREs))
  1279. # Combine both results
  1280. result_iPSC <- full_join(genes_per_cCRE, cCREs_per_gene, by = "Mapping")
  1281. result_Microglia <- full_join(genes_per_cCRE, cCREs_per_gene, by = "Mapping")
  1282. result_LPS_IFNG <- full_join(genes_per_cCRE, cCREs_per_gene, by = "Mapping")

cCRE-TargetGene_analysis.R at commit 83d4caa, under MIT · at the source

Overview

Authors: Brianne B. Rogers1, Ashlyn G. Anderson1,2, Ivan Rodriguez-Nunez1, Samuel C. Bartley1,2, S. Quinn Johnston1, Jared W. Taylor1, Sarah K. Meadows1, Kimberly M. Newberry1, Richard M. Myers1, J. Nicholas Cochran1
  1. HudsonAlpha Institute for Biotechnology, Huntsville, AL 35806, USA
  2. University of Alabama at Birmingham, Birmingham, AL 35294, USA
Journal: iScience, volume 29, issue 7, article 116412
Dates: received 24 September 2025; accepted 29 May 2026; published online 16 June 2026
Type: Research article · Language: English
License: CC BY-NC
Identifiers: DOI 10.1016/j.isci.2026.116412 · PMID 42338472 · PMCID PMC13285636 · OpenAlex W7164886869
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: genetics / omics (modality)
Methods: Statistics, Machine learning
Keywords: neuroscience, techniques in neuroscience, stem cells research
Topic: Neuroinflammation and Neurodegeneration Mechanisms (Neurology, Neuroscience), according to OpenAlex
Funding: NIH (5R00AG068271); National Institute on Aging (5R01AG085357); Alzheimer’s Association (AARG-24-1308947); American Parkinson Disease Association (1269685); NIGMS (5T32GM146611); HudsonAlpha Foundation
Citations: not cited yet (Europe PMC); 99 references in the paper
Research resources: Alexa 488 Goat-AntiMouse RRID:AB_2534069, Anti-H3K27ac RRID:AB_2561016, IBA1 Monoclonal Antibody (GT10312) RRID:AB_2735228, RRID:AB_469901

Abstract

Understanding transcriptional regulatory networks (TRNs) in microglia is essential for elucidating mechanisms underlying central nervous system (CNS) disorders. Human induced pluripotent stem cell (iPSC)-derived models enable mechanistic studies of microglia but often suffer from variability across lines. Here, we use the standardized KOLF2.1J iPSC line, engineered to inducibly express six transcription factors that allow rapid generation of microglia-like cells (iTF-microglia). We profile TRNs under homeostatic and inflammatory conditions and show that iTF-microglia resemble primary brain microglia at transcriptomic and epigenomic levels. Integrative analyses identify microglia-enriched candidate cis-regulatory elements (cCREs) and reveal dynamic enhancer remodeling during differentiation and stimulation with lipopolysaccharide (LPS) or interferon-gamma (IFNγ), involving NF-κB, IRF, and STAT transcription factors. TRNs active in iTF-microglia are enriched for genetic variants linked to Alzheimer’s disease and related CNS disorders. These findings establish KOLF2.1J iTF-microglia as a reproducible, genetically tractable system for dissecting microglial gene regulation and TRN remodeling in disease.

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

Repositories

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

HudsonAlpha/iTF-Microglia

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 83d4caaea2aab82e4da550cf5a5f377e5ed611d3, 11 September 2025
Languages: R (14)
Size: 23 files, 14 scripts
Software Heritage: not archived
Found in: “Data and code availability”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: tidyverse (12 files), ggplot2 (8 files), data.table (6 files), ComplexHeatmap (5 files), DESeq2 (5 files), ggpubr (4 files), circlize (3 files), clusterProfiler (2 files), edgeR (2 files), pheatmap (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
16 files

ENCODE-DCC/atac-seq-pipeline

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 47ba8dff9c332e24b48e767303e9fcac98589cf2, 15 February 2024
Languages: Python (45), Shell (9)
Size: 204 files, 54 scripts
Software Heritage: not archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (scripts/requirements.macs2.txt, scripts/requirements.python2.txt, scripts/requirements.spp.txt, scripts/requirements.txt, dev/docker_image/Dockerfile), tests, continuous integration, documentation
Not found: CITATION.cff
Tools: Matplotlib (6 files), NumPy (6 files), pandas (3 files), SAMtools (2 files), SciPy (2 files), BEDTools (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
56 files

The paper's code and data availability statement is in the Data section.

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:

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

Data and code availability

• RNA-sequencing, ATAC-sequencing, ChIP-sequencing and Hi-C data have been deposited at GEO database under GEO Superseries: GSE299850 and are publicly available. • The analysis scripts used to generate the images and statistical output in this study are available on GitHub (https://github.com/HudsonAlpha/iTF-Microglia) • Any additional information required to reanalyze the data reported in this study is available from the lead contact upon request.

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

Versions

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

Version 2, 28 September 2026

  • Authors: added J. Nicholas Cochran (0000-0002-9852-5504); removed J. Nicholas Cochran

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 10 authors, 3 keywords, 6 funders, 99 references, 4 RRIDs.

Cite

This paper

Rogers, B. B., Anderson, A. G., Rodriguez-Nunez, I., Bartley, S. C., Johnston, S. Q., Taylor, J. W., Meadows, S. K., Newberry, K. M., Myers, R. M., & Cochran, J. N. (2026). KOLF2.1J iTF-Microglia: A standardized platform to study microglial transcriptional regulatory networks in CNS disease. iScience, 29(7), 116412. https://doi.org/10.1016/j.isci.2026.116412

BibTeX

@article{rogers2026kolf2,
author = {Rogers, Brianne B. and Anderson, Ashlyn G. and Rodriguez-Nunez, Ivan and Bartley, Samuel C. and Johnston, S. Quinn and Taylor, Jared W. and Meadows, Sarah K. and Newberry, Kimberly M. and Myers, Richard M. and Cochran, J. Nicholas},
title = {{KOLF2.1J iTF-Microglia: A standardized platform to study microglial transcriptional regulatory networks in CNS disease}},
journal = {iScience},
year = {2026},
month = jun,
volume = {29},
number = {7},
pages = {116412},
publisher = {Elsevier},
issn = {2589-0042},
doi = {10.1016/j.isci.2026.116412},
url = {https://doi.org/10.1016/j.isci.2026.116412},
pmid = {42338472},
pmcid = {PMC13285636}
}

RIS

TY - JOUR
AU - Rogers, Brianne B.
AU - Anderson, Ashlyn G.
AU - Rodriguez-Nunez, Ivan
AU - Bartley, Samuel C.
AU - Johnston, S. Quinn
AU - Taylor, Jared W.
AU - Meadows, Sarah K.
AU - Newberry, Kimberly M.
AU - Myers, Richard M.
AU - Cochran, J. Nicholas
TI - KOLF2.1J iTF-Microglia: A standardized platform to study microglial transcriptional regulatory networks in CNS disease
T2 - iScience
J2 - iScience
PY - 2026
DA - 2026/06/16
VL - 29
IS - 7
SP - 116412
SN - 2589-0042
PB - Elsevier
DO - 10.1016/j.isci.2026.116412
UR - https://doi.org/10.1016/j.isci.2026.116412
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.isci.2026.116412",
"type": "article-journal",
"title": "KOLF2.1J iTF-Microglia: A standardized platform to study microglial transcriptional regulatory networks in CNS disease",
"container-title": "iScience",
"author": [
{
"family": "Rogers",
"given": "Brianne B."
},
{
"family": "Anderson",
"given": "Ashlyn G."
},
{
"family": "Rodriguez-Nunez",
"given": "Ivan"
},
{
"family": "Bartley",
"given": "Samuel C."
},
{
"family": "Johnston",
"given": "S. Quinn"
},
{
"family": "Taylor",
"given": "Jared W."
},
{
"family": "Meadows",
"given": "Sarah K."
},
{
"family": "Newberry",
"given": "Kimberly M."
},
{
"family": "Myers",
"given": "Richard M."
},
{
"family": "Cochran",
"given": "J. Nicholas"
}
],
"container-title-short": "iScience",
"volume": "29",
"issue": "7",
"page": "116412",
"DOI": "10.1016/j.isci.2026.116412",
"PMID": "42338472",
"PMCID": "PMC13285636",
"ISSN": "2589-0042",
"publisher": "Elsevier",
"URL": "https://doi.org/10.1016/j.isci.2026.116412",
"language": "en",
"issued": {
"date-parts": [
[
2026,
6,
16
]
]
}
}

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

Similar papers

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

[1] doi:10.1038/s41467-026-73007-1 [code]
Single-nucleus epigenomic dysregulation unmasks genetic risk-associated neurodegenerative glia states.
Journal: Nature communications
In common: SAMtools, circlize, ComplexHeatmap, 7 other tools, genetics / omics, 13 references
[2] doi:10.1038/s41593-026-02367-0 [code]
A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes.
Journal: Nature neuroscience
In common: edgeR, circlize, DESeq2, 7 other tools, 7 references
[3] doi:10.1038/s41386-026-02406-1 [code]
Functional genomic profiling of schizophrenia-associated genes reveals key microglial regulators.
Journal: Neuropsychopharmacology : official publication of the American College of Neuropsychopharmacology
In common: SAMtools, circlize, DESeq2, 7 other tools, genetics / omics, 6 references
[4] doi:10.1038/s41586-026-10512-9 [code]
Astrocyte glucocorticoid receptor signalling restricts neuronal plasticity.
Journal: Nature
In common: BEDTools, SAMtools, edgeR, 13 other tools, 1 reference
[5] 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: SAMtools, edgeR, circlize, 12 other tools, genetics / omics, 2 references
[6] doi:10.1101/gr.281113.125 [code]
Single-nucleus multiomic profiling of the aging mouse substantia nigra reveals conserved gene alterations linked to Parkinson's disease.
Journal: Genome research
In common: BEDTools, edgeR, circlize, 9 other tools, genetics / omics, 3 references
[7] 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: BEDTools, SAMtools, edgeR, 11 other tools, genetics / omics, 2 references
[8] doi:10.1038/s41467-026-69944-6 [code]
Multi-modal dissection of cell-type specific TDP-43 pathology in the motor cortex.
Journal: Nature communications
In common: BEDTools, SAMtools, circlize, 12 other tools, genetics / omics, 1 reference
[9] doi:10.1038/s41467-026-71790-5 [code]
Recurrent DNA break clusters drive replication-stress-induced copy number variants and genome diversification.
Journal: Nature communications
In common: BEDTools, SAMtools, edgeR, 12 other tools, genetics / omics
[10] doi:10.1038/s41467-026-72598-z [code]
Functional impact of genetic background on variable expressivity in neurodevelopmental disorders.
Journal: Nature communications
In common: BEDTools, SAMtools, DESeq2, 11 other tools, 2 references

Contribute

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

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

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.