OSCR

A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes.

Code ↔ Paper

18 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 18 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 › 3BTMs enable studying AD-relevant perturbations and drug responses in human brain cells ↔ analysis_3BTM_rhapsody/analysis_3BTM_downstream.Rmd, lines 6167–6187 · score 0.85 · apoptotic signaling pathways, MHC class, protein folding, negative regulation, neuron projection, stress
  2. [2] § Methods › scRNA-seq › Downstream analysis of the BD Rhapsody datasets ↔ install_bioc.R, the whole file · a weak match · score 0.76 · ComplexHeatmap, UCell, clusterProfiler, fgsea, MAST, seq
  3. [3] § Methods › scRNA-seq › Downstream analysis of the 10X dataset ↔ analysis_3BTM_10x/Figure5_scRNA_microglia_KI.Rmd, lines 787–822 · score 0.76 · downregulated DEGs, min.pct, FindMarkers, WT Resting, MAST, DEAs
  4. [4] § Methods › scRNA-seq › Downstream analysis of the BD Rhapsody datasets ↔ analysis_3BTM_10x/Figure5_scRNA_microglia_KI.Rmd, lines 82–219 · score 0.72 · FindMarkers, VlnPlot, ribosomal, Seurat, downstream, UMIs
  5. [5] § Methods › scRNA-seq › Downstream analysis of the BD Rhapsody datasets ↔ analysis_3BTM_rhapsody/analysis_3BTM_downstream.Rmd, lines 5642–5690 · score 0.72 · latent.vars, FindMarkers, Sample_univoque, MAST, Rhapsody, threshold
  6. [6] § Methods › scRNA-seq › Downstream analysis of the 10X dataset ↔ analysis_3BTM_10x/Figure3_scRNA_microglia_maturation_clean.Rmd, lines 246–299 · score 0.66 · k.weight, IntegrateData, CCA, transform, Seurat, Downstream
  7. [7] § Results › iMGs in AD-modeling 3BTMs recapitulate disease-related changes ↔ analysis_3BTM_10x/Figure5_scRNA_microglia_KI.Rmd, lines 1238–1261 · score 0.64 · AD risk genes, KI cluster, WT resting, BLNK, SORL1, TREM2
  8. [8] § Methods › scRNA-seq › Downstream analysis of the 10X dataset ↔ analysis_3BTM_10x/Figure5_scRNA_microglia_KI.Rmd, lines 82–219 · score 0.64 · standard Seurat, workflow, ribosomal, downstream, UMIs, mitochondrial
  9. [9] § Results › 3BTMs enable studying AD-relevant perturbations and drug responses in human brain cells ↔ analysis_3BTM_rhapsody/analysis_3BTM_downstream.Rmd, lines 6267–6333 · score 0.63 · MHC protein complex, innate immune response, GO term, phagocytosis, aducanumab, signal
  10. [10] § Results › iMGs, iNEs and iAS show reproducible, AD-related changes across cell lines ↔ analysis_3BTM_rhapsody/analysis_3BTM_downstream.Rmd, lines 6023–6049 · score 0.59 · unfolded protein response, endoplasmic reticulum, neurons, GO
  11. [11] § Results › iMGs mature in 3BTMs and adopt transcriptomic signatures similar to the human brain ↔ analysis_3BTM_10x/Figure3_scRNA_microglia_maturation_clean.Rmd, lines 2023–2060 · score 0.56 · adult human, signatures derived, scRNA, fetal, maturation, seq
  12. [12] § Results › Brain cells in 3BTMs show increased maturity, homeostasis and functionality compared to 2D co-cultures ↔ analysis_3BTM_3Dvs2D/analysis_3BTM_3Dvs2D_minimal.Rmd, lines 3259–3282 · score 0.56 · ATP1A2, SLC2A1, MT3
  13. [13] § Methods › scRNA-seq › Downstream analysis of the 10X dataset ↔ analysis_3BTM_10x/Figure3_scRNA_microglia_maturation_clean.Rmd, lines 595–616 · score 0.56 · ALDH1A1, SOX11, TYROBP, AQP4, canonical, downstream
  14. [14] § Results › CRISPR–Cas9-mediated insertion of synergistic APP mutations to model AD ↔ analysis_3BTM_10x/Figure5_scRNA_microglia_KI.Rmd, lines 241–274 · score 0.53 · causing mutations, stem cells, iPSC, APP, knocked, cultured
  15. [15] § Results › iMGs in AD-modeling 3BTMs recapitulate disease-related changes ↔ analysis_3BTM_10x/Figure5_scRNA_microglia_KI.Rmd, lines 1238–1261 · score 0.52 · AD risk genes, WT resting, Cell state, Violin, Figure 5, subset
  16. [16] § Results › Brain cells in 3BTMs show increased maturity, homeostasis and functionality compared to 2D co-cultures ↔ analysis_3BTM_rhapsody/analysis_3BTM_downstream.Rmd, lines 6167–6187 · score 0.52 · synaptic signaling, synapse organization, pathways, regulation, protein
  17. [17] § Results › iMGs, iNEs and iAS show reproducible, AD-related changes across cell lines ↔ analysis_3BTM_3Dvs2D/analysis_3BTM_3Dvs2D_minimal.Rmd, lines 2372–2397 · score 0.51 · BCL11B, mid, GABAergic, layer, SATB2, cortical
  18. [18] § Results › Brain cells in 3BTMs show increased maturity, homeostasis and functionality compared to 2D co-cultures ↔ analysis_3BTM_3Dvs2D/analysis_3BTM_3Dvs2D_minimal.Rmd, lines 2886–2912 · score 0.51 · synaptic signaling, synapse organization, regulation, protein

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 Markdown · 1,404 lines · 50 KB · no license · 6 matches

  1. ---
  2. title: "Characterization of the KI 3months model"
  3. author: ""
  4. date: "`r format(Sys.time(), '%d %B, %Y')`"
  5. output:
  6. html_document:
  7. code_download: yes
  8. df_print: kable
  9. theme: united
  10. toc: yes
  11. toc_depth: 6
  12. toc_float: yes
  13. output: html_document
  14. editor_options:
  15. chunk_output_type: inline
  16. ---
  17. # Load packages
  18. ```{r}
  19. library(Seurat)
  20. library(SeuratDisk)
  21. library(ggplot2)
  22. library(SingleR)
  23. library(biomaRt)
  24. library(org.Hs.eg.db)
  25. library(clusterProfiler)
  26. library(RColorBrewer)
  27. library(ggpubr)
  28. library(reshape2)
  29. library(org.Hs.eg.db)
  30. library(tidyverse)
  31. library(gridExtra)
  32. library(ComplexHeatmap)
  33. library(readxl)
  34. library(scCustomize)
  35. library(data.table)
  36. library(ggVennDiagram)
  37. library(slingshot)
  38. library(ggplotify)
  39. library(patchwork)
  40. library(AUCell)
  41. library(ggVennDiagram)
  42. library(nichenetr)
  43. library(viridis)
  44. library(dittoSeq)
  45. library(ggvolc)
  46. library(cowplot)
  47. library(reticulate)
  48. library(sceasy)
  49. library(MAST)
  50. library(UpSetR)
  51. library(sceasy)
  52. library(UCell)
  53. library(PCAtools)
  54. library(scIntegrationMetrics)
  55. library(topGO)
  56. library(harmony)
  57. library(genesorteR)
  58. library(ggVolcano)
  59. library(speckle)
  60. library(monocle3)
  61. library(monocle)
  62. library(SeuratWrappers)
  63. library(SingleCellExperiment)
  64. library(Nebulosa)
  65. library(org.Mm.eg.db)
  66. BiocManager::install("GeneOverlap")
  67. library("GeneOverlap")
  68. devtools::install_github("mw201608/SuperExactTest")
  69. library(SuperExactTest)
  70. sess.i <- sessionInfo()
  71. ```
  72. # Define custom functions
  73. ```{r}
  74. # barplot of DEGs from filtered FindMarkers output
  75. degs_barplot <- function(degs_df){
  76. h <- degs_df[degs_df$Regulation != "none",]
  77. f_u <- table(h$Regulation)
  78. f_uh <- data.frame(status = names(f_u),
  79. total = as.vector(f_u))
  80. degs_bp <- ggplot(f_uh, aes(x = status, y = total, fill = status))+
  81. geom_bar(stat= "identity", width = 0.9)+
  82. geom_text(aes(label = total), vjust= -0.2, size = 6)+
  83. theme_classic()+
  84. theme(aspect.ratio = 1.9,
  85. legend.position = 'none',
  86. axis.text.x = element_text(size=20, angle=0),
  87. axis.text.y = element_text(size=20, angle=0),
  88. axis.title = element_text(size = 20))+
  89. scale_fill_manual(values = c("#00798c","#cc0000"))+
  90. ylab("number of DEGs")+
  91. xlab(label= NULL)
  92. return(degs_bp)
  93. }
  94. # Filtering FindMarkers output to get up and down regulated genes
  95. up_down_degs <- function(degs_df){
  96. degs.list <- degs_df
  97. degs.list$genes <- rownames(degs_df)
  98. degs.list$Significance <- "none"
  99. degs.list$Significance <- ifelse(degs.list$p_val_adj < 0.01, "yes", degs.list$Significance)
  100. degs.list$Significance <- ifelse(degs.list$p_val_adj > 0.01, "no", degs.list$Significance)
  101. degs.list$Regulation <- "none"
  102. degs.list$Regulation <- ifelse(degs.list$avg_log2FC > 0.25 & degs.list$p_val_adj < 0.01, "up", degs.list$Regulation)
  103. degs.list$Regulation <- ifelse(degs.list$avg_log2FC < -0.25 & degs.list$p_val_adj < 0.01, "down", degs.list$Regulation)
  104. degs.list <- subset(degs.list, degs.list$Regulation != "none")
  105. return(degs.list)
  106. }
  107. # seuratv3 integration wrapper
  108. integr_wrap <- function(sobject.list, nfeatures, k_anchor, k_filter, k_score ){
  109. # select features that are repeatedly variable across datasets for integration
  110. features <- SelectIntegrationFeatures(object.list = sobject.list, nfeatures = 2000)
  111. features.to.integrate <- intersect(rownames(sobject.list[[2]]), rownames(sobject.list[[1]]))
  112. uglia.anchors <- FindIntegrationAnchors(object.list = sobject.list, anchor.features = features, k.anchor = k_anchor, k.filter = k_filter, k.score = k_score)
  113. # this command creates an 'integrated' data assay
  114. uglia.combined <- IntegrateData(anchorset = uglia.anchors, features.to.integrate = features.to.integrate)
  115. # specify that we will perform downstream analysis on the corrected data note that the
  116. # original unmodified data still resides in the 'RNA' assay
  117. DefaultAssay(uglia.combined) <- "integrated"
  118. # Run the standard workflow for visualization and clustering
  119. uglia.combined <- ScaleData(uglia.combined, verbose = FALSE)
  120. uglia.combined <- RunPCA(uglia.combined, npcs = 30, verbose = FALSE)
  121. uglia.combined <- RunUMAP(uglia.combined, reduction = "pca", dims = 1:30)
  122. uglia.combined <- FindNeighbors(uglia.combined, reduction = "pca", dims = 1:30)
  123. uglia.combined <- FindClusters(uglia.combined, resolution = 0.5)
  124. return(uglia.combined)
  125. }
  126. # dotplot to display GO enrichment results
  127. ego_dp <- function(df){
  128. plot <- df %>%
  129. arrange(Description) %>%
  130. mutate(status = factor(status, levels = c("up", "down"))) %>%
  131. ggplot(aes(x = status, y = Description, color = `qvalue`, size = Count)) +
  132. geom_point() +
  133. scale_color_gradient(low = "#006f62", high = "#b6d7a8") +
  134. ylab("") +
  135. xlab("")
  136. return(plot)
  137. }
  138. # QC plots
  139. plot_QC <- function(seurat){
  140. #Features (genes)
  141. n_feat_cl <- VlnPlot(seurat,
  142. features = c("nFeature_RNA"),
  143. pt.size = 0) +
  144. geom_hline(yintercept = 250, linetype = "dashed", colour = "red")+
  145. ylim(500, 10000)+
  146. NoLegend()
  147. #Counts (UMIs)
  148. n_count_cl <- VlnPlot(seurat,
  149. features = c("nCount_RNA"),
  150. pt.size = 0)+
  151. geom_hline(yintercept = 15000, linetype = "dashed", colour = "red")+
  152. ylim(500, 80000)+
  153. NoLegend()
  154. #Percent of mitochondrial reads
  155. # mito cutoff 10%
  156. mito_pt_cl <- VlnPlot(seurat,
  157. features = c("percent.mt"),
  158. pt.size = 0) +
  159. geom_hline(yintercept = 7, linetype = "dashed", colour = "red")+
  160. ylim(0, 40)+
  161. NoLegend()
  162. #Percent of ribosomal reads
  163. seurat[["percent.rb"]] <- PercentageFeatureSet(seurat, pattern = "^RP[SL]")
  164. ribo_pt_cl <- VlnPlot(seurat,
  165. features = c("percent.rb"),
  166. pt.size = 0) +
  167. geom_hline(yintercept = 25, linetype = "dashed", colour = "red")+
  168. ylim(0, 40)+
  169. NoLegend()
  170. plots <- list(n_feat_cl, n_count_cl, mito_pt_cl, ribo_pt_cl)
  171. print(plots)
  172. }
  173. # standard seurat pre-processing wrapper
  174. standard_preprocessing <- function(sobj){
  175. sobj <- NormalizeData(sobj, normalization.method = "LogNormalize", scale.factor = 10000)
  176. sobj <- FindVariableFeatures(sobj, selection.method = "vst", nfeatures = 2000)
  177. all.genes <- rownames(sobj)
  178. sobj <- ScaleData(sobj, features = all.genes_mancuso)
  179. sobj <- RunPCA(sobj, features = VariableFeatures(object = sobj))
  180. sobj <- FindNeighbors(sobj, reduction = "pca",dims = 1:50)
  181. sobj <- FindClusters(sobj, resolution = 0.5)
  182. sobj <- RunUMAP(sobj, reduction = "pca",dims = 1:50, seed.use = 42)
  183. return(sobj)
  184. }
  185. ```
  186. # Define colors
  187. ```{r}
  188. pal <- c("#E1BE6A","#004949","#009292","#ff6db6","#ffb6db",
  189. "#490092","#006ddb","#b66dff","#6db6ff","#b6dbff",
  190. "#920000","#924900","#db6d00","#24ff24","#ffff6d")
  191. pal_viridis <- viridis(n = 10, option = "D")
  192. sobj_3mo_pal <- c("WT Resting" = "#228b22",
  193. "KI Cluster 2" = "#ffb90f",
  194. "KI Cluster 1" = "#eae4b7",
  195. "Chemokine 3mo" = "#74d600",
  196. "Glycolytic 3mo" = "#b0bf1a",
  197. "Proliferative 3mo" = "#b2ffff")
  198. ```
  199. #_____________________________________________________________________________________________________________________________________________________
  200. #DATASET description
  201. #_____________________________________________________________________________________________________________________________________________________
  202. All 10X samples derive from human stem cell (iPSC-) derived 3D cultures made of cortical neurons (NE), astrocytes (AS) and microglia (MG). The cell types were differentiated separately, then aggregated into a spheroid-like culture, and grown for 1 month (1mo) or 3 months (3mo). For the experiment, wildtype (WT) and knock-in (KI) cultures carrying three familial Alzheimer’s disease-causing mutations in the APP gene are analyzed. The experiment was performed as indicated below:
  203. o Sample 3: WT 1mo (pooled 2 biological replicates with hashtags)
  204. o Sample 4: WT 3mo (pooled 2 biological replicates with hashtags)
  205. o Sample 5: KI 3mo (pooled 2 biological replicates with hashtags)
  206. #Load Data
  207. The code chunks relative to the loading of external objects(.csv, .xlsx) containing signature gene lists have been silenced. When loading the minimal environment it won't be necessary to load seurat objects and running pre-processing and differential expression aanlysis code chunks.
  208. ```{r}
  209. #load main seurat objects
  210. seurat_objects_figure6 <- readRDS("/path/seurat_figure6.rds")
  211. #Load environment:
  212. #In this environment are included:
  213. # - main seurat objects produced
  214. # - all signatures used for scoring
  215. # - differential analysis code
  216. #load("/path/figure6_env.RData")
  217. #extract each object from list (if environment is not loaded)
  218. #sobj_sub <- seurat_objects_figure6[[1]] # The code for pre-processing and subsetting this object are reported in Figure 3 script
  219. #sobj_mg <- seurat_objects_figure6[[2]] #seurat object filtered to have only microglia cells
  220. #sobj_3mo <- seurat_objects_figure6[[3]] # subset seurat object for 3 months old WT and KI neurocultures
  221. ```
  222. # Pre-processing
  223. ```{r}
  224. #Normalization
  225. sobj_mg <- NormalizeData(sobj_mg, normalization.method = "LogNormalize", scale.factor = 10000)
  226. #Variable features exploration
  227. sobj_mg <- FindVariableFeatures(sobj_mg, selection.method = "vst", nfeatures = 2000)
  228. # Identify the 10 most highly variable genes
  229. top10 <- head(VariableFeatures(sobj_mg), 10)
  230. #Scaling
  231. all.genes <- rownames(sobj_mg)
  232. sobj_mg <- ScaleData(sobj_mg, features = all.genes)
  233. #Dimensional reduction
  234. sobj_mg <- RunPCA(sobj_mg, features = VariableFeatures(object = sobj_mg))
  235. print(sobj_mg[["pca"]], dims = 1:5, nfeatures = 5)
  236. DimPlot(sobj_mg, reduction = "pca")
  237. #determine informative PCs
  238. ElbowPlot(sobj_mg)
  239. ```
  240. ```{r}
  241. set.seed(42)
  242. # Find clusters
  243. sobj_mg <- FindNeighbors(object=sobj_mg, dims=1:10)
  244. # Find clusters for several resolutions and choose appropriate one for downstream analysis
  245. sobj_mg_cl_tr <- FindClusters(object = sobj_mg, resolution = c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0))
  246. # Plot and save several resolutions
  247. sobj_mg_cl_tr <- RunUMAP(object=sobj_mg_cl_tr, dims=1:10, seed.use = 42)
  248. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.1", label=T, seed = 42) + ggtitle("Res 0.1")
  249. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.2", label=T, seed = 42) + ggtitle("Res 0.2")
  250. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.3", label=T, seed = 42) + ggtitle("Res 0.3")
  251. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.4", label=T, seed = 42) + ggtitle("Res 0.4")
  252. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.5", label=T, seed = 42) + ggtitle("Res 0.5")
  253. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.6", label=T, seed = 42) + ggtitle("Res 0.6")
  254. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.8", label=T, seed = 42) + ggtitle("Res 0.8")
  255. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.1", label=T, seed = 42) + ggtitle("Res 1.0")
  256. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.1.2", label=T, seed = 42) + ggtitle("Res 1.2")
  257. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.1.4", label=T, seed = 42) + ggtitle("Res 1.4")
  258. DimPlot(object=sobj_mg_cl_tr, reduction="umap", group.by="RNA_snn_res.0.7", label=T, seed = 42) + ggtitle("Res 0.7")
  259. #Here the resolution to be used was chosen empirically to avoid over-clustering. In case of re-analysis of published dataset the resolution was chosen accordingly to the information on the original publication if mentioned with the aim of replicating the published data
  260. ```
  261. ```{r}
  262. #Find clusters with chosen resolution
  263. sobj_mg <- FindClusters(object = sobj_mg, resolution=0.5)
  264. remove(sobj_mg_cl_tr) #removing object to limit memory usage
  265. ```
  266. ```{r}
  267. set.seed(42)
  268. #UMAP
  269. sobj_mg <- RunUMAP(sobj_mg, dims = 1:10, seed.use = 42)
  270. #plots
  271. DimPlot(sobj_mg, reduction = "umap", cols = pal, seed = 1) + theme(aspect.ratio=1)
  272. DimPlot(sobj_mg, split.by = "condition", cols = pal, seed = 1) + theme(aspect.ratio=1)
  273. #total number of cells and number of cells per cluster
  274. table(Idents(sobj_mg))
  275. ncol(sobj_mg)
  276. ```
  277. ```{r, fig.height=7, fig.width=20}
  278. #UMAP plot splitted by replicate
  279. DimPlot(sobj_mg, split.by = "orig.ident", cols = pal, seed = 1) + theme(aspect.ratio=1)
  280. ```
  281. # QC per cluster (only microglia)
  282. ```{r, fig.height=7, fig.width=20}
  283. #QC plots per condition
  284. Idents(sobj_mg) <- "condition"
  285. sobj_mg_QC_c <-plot_QC(sobj_mg)
  286. #QC plots per cluster
  287. Idents(sobj_mg) <- "seurat_clusters"
  288. sobj_mg_QC_cl <-plot_QC(sobj_mg)
  289. ```
  290. ## Subset to exclude sample enriched clusters
  291. some clusters may be sample specific and so not really informative in the downstream analysis. Here we excluded one cluster with such characteristics to avoid its inclusion in the downstream process.
  292. The seurat object was subject to pre-processing following the subset
  293. ```{r}
  294. set.seed(42)
  295. #subset
  296. clusters_to_keep <- c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")
  297. sobj_mg_filt <- subset(sobj_mg, subset = seurat_clusters %in% clusters_to_keep)
  298. #Normalization
  299. sobj_mg_filt <- NormalizeData(sobj_mg_filt, normalization.method = "LogNormalize", scale.factor = 10000)
  300. #Variable features exploration
  301. sobj_mg_filt <- FindVariableFeatures(sobj_mg_filt, selection.method = "vst", nfeatures = 2000)
  302. # Identify the 10 most highly variable genes
  303. top10 <- head(VariableFeatures(sobj_mg_filt), 10)
  304. #Scaling
  305. all.genes <- rownames(sobj_mg_filt)
  306. sobj_mg_filt <- ScaleData(sobj_mg_filt, features = all.genes)
  307. #Dimensional reduction
  308. sobj_mg_filt <- RunPCA(sobj_mg_filt, features = VariableFeatures(object = sobj_mg_filt))
  309. print(sobj_mg_filt[["pca"]], dims = 1:5, nfeatures = 5)
  310. DimPlot(sobj_mg_filt, reduction = "pca")
  311. #determine informative PCs
  312. ElbowPlot(sobj_mg_filt)
  313. # Find clusters
  314. sobj_mg_filt <- FindNeighbors(object=sobj_mg_filt, dims=1:10)
  315. # Explore clustering resolutions
  316. sobj_mg_filt_t <- FindClusters(object = sobj_mg_filt, resolution = c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0))
  317. # Plot
  318. sobj_mg_filt_t <- RunUMAP(object=sobj_mg_filt_t, dims=1:10, seed.use =42)
  319. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.0.2", label=T,seed = 42) + ggtitle("Res 0.1")
  320. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.0.2", label=T, seed = 42) + ggtitle("Res 0.2")
  321. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.0.2", label=T, seed = 42) + ggtitle("Res 0.3")
  322. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.0.4", label=T, seed = 42) + ggtitle("Res 0.4")
  323. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.0.5", label=T, seed = 42) + ggtitle("Res 0.5")
  324. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.0.6", label=T, seed = 42) + ggtitle("Res 0.6")
  325. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.0.8", label=T, seed = 42) + ggtitle("Res 0.8")
  326. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.1", label=T, seed = 42) + ggtitle("Res 1.0")
  327. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.1.2", label=T, seed = 42) + ggtitle("Res 1.2")
  328. DimPlot(object=sobj_mg_filt_t, reduction="umap", group.by="RNA_snn_res.1.4", label=T, seed = 42) + ggtitle("Res 1.4")
  329. #Here the resolution to be used was chosen empirically to avoid over-clustering. In case of re-analysis of published dataset the resolution was chosen accordingly to the information on the original publication if mentioned with the aim of replicating the published data
  330. ```
  331. ```{r}
  332. set.seed(42)
  333. # Find clusters this time using the good resolution. Old resolution data is automatically overwritten.
  334. sobj_mg_filt <- FindClusters(object = sobj_mg_filt, resolution=0.5)
  335. #UMAP
  336. sobj_mg_filt <- RunUMAP(sobj_mg_filt, dims = 1:10, seed.use = 42)
  337. DimPlot(sobj_mg_filt, reduction = "umap", cols = pal, seed = 1) + theme(aspect.ratio=1)
  338. DimPlot(sobj_mg_filt, split.by = "condition", cols = pal, seed = 1) + theme(aspect.ratio=1)
  339. remove(sobj_mg_filt_t) #remove objects to limit memory usage
  340. ```
  341. ```{r, fig.height=7, fig.width=20}
  342. DimPlot(sobj_mg_filt, split.by = "orig.ident", cols = pal, seed = 1) + theme(aspect.ratio=1)
  343. ```
  344. # Cell type specific markers (feature plots)
  345. Check for the presence of only microglia in the subset.
  346. ```{r, fig.height=8, fig.width=8}
  347. tyrobp <- FeaturePlot(sobj_mg_filt, features = c("TYROBP")) + theme_void()
  348. sox <- FeaturePlot(sobj_mg_filt, features = c("SOX11")) + theme(aspect.ratio=1)
  349. astro <- FeaturePlot(sobj_mg_filt, features = c("ALDH1A1")) + theme(aspect.ratio=1)
  350. grid.arrange(sox, astro)
  351. grid.arrange(tyrobp)
  352. ```
  353. # Identify cluster biomarkers
  354. To identify different cell states in the microglia data the top 10 differentially expressed genes per cluster were calculated and their averaged expression shown in a dotplot
  355. ```{r, fig.height= 6, fig.width= 18}
  356. #set idents to clusters
  357. Idents(sobj_mg_filt) <- "seurat_clusters"
  358. #Find cluster enriched markers
  359. s.markers <- FindAllMarkers(sobj_mg_filt, assay = "RNA", only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
  360. #select top 10 markers per cluster to plot
  361. s.markers %>%
  362. group_by(cluster) %>%
  363. top_n(n = 10, wt = avg_log2FC) -> top10_s
  364. ```
  365. #___________________________________________________________________________________________________________________________
  366. # SUBSET FOR 3mo (KI, WT)
  367. #_____________________________________________________________________________________________________________________________________________________________________
  368. # Subset for 3mo cells
  369. If loading directly the sobj_3mo object at the beginning of the script running the subsetting and pre-processing code chunks is not necessary
  370. ```{r}
  371. #subset by time
  372. Idents(sobj_mg_filt) <- "time"
  373. sobj_3mo <- subset(sobj_mg_filt, idents= c("3mo"))
  374. #set and check subset idents
  375. Idents(sobj_3mo) <- "genotype"
  376. levels(Idents(sobj_3mo))
  377. ```
  378. ## Pre-processing
  379. ```{r}
  380. #Normalization
  381. sobj_3mo <- NormalizeData(sobj_3mo, normalization.method = "LogNormalize", scale.factor = 10000)
  382. #Find Variable features
  383. sobj_3mo <- FindVariableFeatures(sobj_3mo, selection.method = "vst", nfeatures = 2000)
  384. # Identify the 10 most highly variable genes
  385. top10 <- head(VariableFeatures(sobj_3mo), 10)
  386. plot1 <- VariableFeaturePlot(sobj_3mo)
  387. LabelPoints(plot = plot1, points = top10, repel = TRUE)
  388. ## Scaling
  389. all.genes <- rownames(sobj_3mo)
  390. sobj_3mo <- ScaleData(sobj_3mo, features = all.genes)
  391. ## PCA
  392. sobj_3mo <- RunPCA(sobj_3mo, features = VariableFeatures(object = sobj_3mo))
  393. print(sobj_3mo[["pca"]], dims = 1:5, nfeatures = 5)
  394. DimPlot(sobj_3mo, reduction = "pca")
  395. #determine more informative principal components
  396. ElbowPlot(sobj_3mo)
  397. ```
  398. ```{r}
  399. ## Clustering
  400. set.seed(42)
  401. # Find clusters
  402. sobj_3mo <- FindNeighbors(object = sobj_3mo, dims=1:10)
  403. #Plot different clustering resolutions
  404. sobj_3mo_t <- FindClusters(object = sobj_3mo, resolution = c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0), verbose = F)
  405. # Plots
  406. sobj_3mo_t <- RunUMAP(object= sobj_3mo_t, dims=1:10, seed.use = 42)
  407. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.0.1", label=T, seed = 42) + ggtitle("Res 0.1")
  408. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.0.2", label=T, seed = 42) + ggtitle("Res 0.2")
  409. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.0.3", label=T, seed = 42) + ggtitle("Res 0.3")
  410. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.0.4", label=T, seed = 42) + ggtitle("Res 0.4")
  411. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.0.5", label=T, seed = 42) + ggtitle("Res 0.5")
  412. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.0.6", label=T, seed = 42) + ggtitle("Res 0.6")
  413. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.0.8", label=T, seed = 42) + ggtitle("Res 0.8")
  414. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.1", label=T, seed = 42) + ggtitle("Res 1.0")
  415. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.1.2", label=T, seed = 42) + ggtitle("Res 1.2")
  416. DimPlot(object=sobj_3mo_t, reduction="umap", group.by="RNA_snn_res.1.4", label=T, seed = 42) + ggtitle("Res 1.4")
  417. ```
  418. ```{r}
  419. ## UMAP
  420. set.seed(42)
  421. #remove object to reduce memory usage
  422. rm(sobj_3mo_t)
  423. #choose dimensional reduction to use
  424. sobj_3mo <- FindNeighbors(object = sobj_3mo, dims=1:10)
  425. sobj_3mo <- FindClusters(object = sobj_3mo, resolution = c(0.4), verbose = F)
  426. sobj_3mo <- RunUMAP(object= sobj_3mo, dims=1:10)
  427. #reset idents
  428. Idents(sobj_3mo) <- "seurat_clusters"
  429. ```
  430. ```{r}
  431. #plot
  432. DimPlot(sobj_3mo, split.by = "condition", cols = pal, seed = 1) + theme(aspect.ratio=1)
  433. ```
  434. ```{r, fig.height=5, fig.width=10}
  435. #plot UMAP splitted by sample
  436. DimPlot(sobj_3mo, split.by = "orig.ident", cols = pal, seed = 1) + theme(aspect.ratio=1)
  437. ```
  438. # Characterization of the clusters
  439. ## Top markers
  440. ```{r}
  441. #set idents
  442. Idents(sobj_3mo) <- "seurat_clusters"
  443. #Find cluster enriched markers
  444. s3mo.markers <- FindAllMarkers(sobj_3mo, assay = "RNA", only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
  445. #select top 10 markers per cluster to plot
  446. s3mo.markers %>%
  447. group_by(cluster) %>%
  448. top_n(n = 10, wt = avg_log2FC) -> top10_s3mo
  449. ```
  450. ```{r, fig.height= 6, fig.width= 18}
  451. #extract genes to plot
  452. to_plot_s3mo <- unique(top10_s3mo$gene)
  453. #dotplot
  454. plot_mpc_s3mo <- DotPlot(sobj_3mo, features = to_plot_s3mo, group.by = "seurat_clusters", cols = c("RdBu"))+
  455. theme(axis.text.x = element_text(angle = 90))
  456. #cell number per cluster
  457. table(Idents(sobj_3mo))
  458. ```
  459. ## Functional enrichments in specific clusters
  460. ## Cell states annotation
  461. The annotation was given looking at the markers per cluster and in accordance with the annotation of the Figure 3 UMAP
  462. ```{r}
  463. Idents(sobj_3mo) <- "seurat_clusters"
  464. cell_states <- c( "0"="WT Resting",
  465. "1"="KI Cluster 1",
  466. "2"="KI Cluster 2",
  467. "3"="Chemokine 3mo",
  468. "4"="Glycolytic 3mo",
  469. "5"="Proliferative 3mo")
  470. names(cell_states) <- levels(sobj_3mo)
  471. sobj_3mo <- RenameIdents(sobj_3mo, cell_states)
  472. sobj_3mo$cell_states <- Idents(sobj_3mo)
  473. ```
  474. # QC per cluster
  475. ```{r, fig.height=7, fig.width=10}
  476. #QC plots per cluster
  477. #set idents
  478. Idents(sobj_3mo) <- "seurat_clusters"
  479. #plots
  480. sobj_3mo_QC_cl <- plot_QC(sobj_3mo)
  481. a <- sobj_3mo_QC_cl[[1]]
  482. b <- sobj_3mo_QC_cl[[2]]
  483. c <- sobj_3mo_QC_cl[[3]]
  484. d <- sobj_3mo_QC_cl[[4]]
  485. plot_grid(a, b, c, d)
  486. ```
  487. ```{r}
  488. #here I give names to metadata columns to store percentage of mitochondrial and ribosomal genes in the object before subsetting. The information will be retained in all subsets of the object
  489. #sobj_sub[["percent.mt"]] <- PercentageFeatureSet(sobj_sub, pattern = "^MT-")
  490. #sobj_sub[["percent.rb"]] <- PercentageFeatureSet(sobj_sub, pattern = "^RP[SL]")
  491. #here I visualize such parameters in all the clusters of the 3mo subset
  492. mito <- VlnPlot(object = sobj_3mo, features = "percent.mt", group.by = "seurat_clusters", pt.size = 0)+ theme(legend.position="none") + ggtitle("Percent of mitochondrial counts") + ylab("% of all counts") + xlab("")+ylim(0, 40)+geom_hline(yintercept = 10)
  493. ribo <- VlnPlot(object = sobj_3mo, features = "percent.rb", group.by = "seurat_clusters", pt.size = 0)+ theme(legend.position="none") + ggtitle("Percent of ribosomal counts") + ylab("% of all counts") + xlab("")+ylim(0, 40)+geom_hline(yintercept = 20)
  494. mito+ribo
  495. ```
  496. #______________________________________________________________________________
  497. # Figure
  498. Umap plots for the 3 mo subset
  499. ```{r}
  500. Idents(sobj_3mo) <- "cell_states"
  501. umap_3mo <-DimPlot(sobj_3mo, reduction = "umap", group.by = "cell_states", pt.size = 0.5,
  502. cols = c(sobj_3mo_pal))+
  503. theme(aspect.ratio = 1,
  504. legend.text = element_text(size = 15),
  505. axis.line = element_blank(),
  506. axis.title = element_blank(),
  507. axis.text = element_blank(),
  508. axis.ticks = element_blank(),
  509. legend.key.size = unit(0.5, "cm"),
  510. legend.title = element_text(color = "black", size = 18, face = 2),)+
  511. guides(color = guide_legend(override.aes = list(size = 6)))+
  512. ggtitle(element_blank())
  513. umap_3mo
  514. ```
  515. # Figure
  516. UMAP plot colored by genotype
  517. ```{r}
  518. #Highlight plots
  519. levels(Idents(sobj_3mo))
  520. Idents(sobj_3mo) <- "genotype"
  521. WT <- WhichCells(sobj_3mo, idents = c("WT"))
  522. cells_wt <- list("WT" = WT)
  523. highlight_wt <- Cell_Highlight_Plot(seurat_object = sobj_3mo, cells_highlight = cells_wt, highlight_color = c("#004D00"))+
  524. theme(aspect.ratio = 1,
  525. legend.text = element_text(size = 15),
  526. axis.line = element_blank(),
  527. axis.title = element_blank(),
  528. axis.text = element_blank(),
  529. axis.ticks = element_blank(),
  530. legend.key.size = unit(0.5, "cm"),
  531. legend.title = element_text(color = "black", size = 18, face = 2))+
  532. guides(color = guide_legend(override.aes = list(size = 6)))
  533. highlight_wt
  534. KI<- WhichCells(sobj_3mo, idents = c("KI"))
  535. cells_ki <- list("KI" = KI)
  536. highlight_ki <- Cell_Highlight_Plot(seurat_object = sobj_3mo, cells_highlight = cells_ki, highlight_color = c("#c99005"))+
  537. theme(aspect.ratio = 1,
  538. legend.text = element_text(size = 15),
  539. axis.line = element_blank(),
  540. axis.title = element_blank(),
  541. axis.text = element_blank(),
  542. axis.ticks = element_blank(),
  543. legend.key.size = unit(0.5, "cm"),
  544. legend.title = element_text(color = "black", size = 18, face = 2))+
  545. guides(color = guide_legend(override.aes = list(size = 6)))
  546. highlight_ki
  547. split_3mo_umap<- plot_grid(highlight_wt, highlight_ki, ncol= 2)
  548. split_3mo_umap
  549. ```
  550. # Figure
  551. Cell proportions
  552. ```{r}
  553. #adding replicate information to the metadata
  554. levels(as.factor([email hidden]$orig.ident))
  555. sobj_3mo$replicate <- ifelse([email hidden]$orig.ident == "JK211112_J2_WT_T1", "J1WT1", ifelse(
  556. [email hidden]$orig.ident == "JK211112_J2_WT_T2", "J1WT2", ifelse(
  557. [email hidden]$orig.ident == "JK211112_J3_KI_T1", "J3KI1", ifelse(
  558. [email hidden]$orig.ident == "JK211112_J3_KI_T2", "J3KI2", ""
  559. )
  560. )
  561. ))
  562. levels(as.factor([email hidden]$replicate))
  563. #DA
  564. propeller_3mo <- propeller(clusters = sobj_3mo$cell_states, sample = sobj_3mo$replicate, group = sobj_3mo$condition)
  565. # Plot cell type proportions
  566. propeller_prop_3mo <- plotCellTypeProps(clusters=sobj_3mo$cell_states, sample=sobj_3mo$genotype)
  567. ```
  568. ```{r}
  569. #barplot
  570. KI_cell_props <- propeller_prop_3mo+
  571. scale_fill_manual(values = c("WT Resting" = "#228b22",
  572. "KI Cluster 2" = "#ffb90f",
  573. "KI Cluster 1" = "#eae4b7",
  574. "Chemokine 3mo" = "#74d600",
  575. "Glycolytic 3mo" = "#b0bf1a",
  576. "Proliferative 3mo" = "#b2ffff"))+
  577. xlab("")+
  578. ylab("Frequency")+
  579. scale_x_discrete(limits =c("WT", "KI"))+
  580. theme(aspect.ratio = 1.5,
  581. panel.background = element_blank(),
  582. axis.line = element_line(colour = "black", linewidth = 0.5),
  583. axis.text.x = element_text(face = "bold"),
  584. axis.title.y = element_text(face = "bold"))
  585. KI_cell_props
  586. ```
  587. # Figure
  588. QC per cluster
  589. ```{r, fig.height=7, fig.width=10}
  590. #QC plots per cluster
  591. Idents(sobj_3mo) <- "cell_states"
  592. plot_grid(a, b, c, d)
  593. ```
  594. #Figure
  595. ```{r}
  596. Idents(sobj_3mo) <- "cell_states"
  597. #order sample
  598. sobj_3mo$sample <- ifelse([email hidden]$orig.ident == "JK211112_J2_WT_T1", "WT rep1", ifelse(
  599. [email hidden]$orig.ident == "JK211112_J2_WT_T2", "WT rep2", ifelse(
  600. [email hidden]$orig.ident == "JK211112_J3_KI_T1", "KI rep1", ifelse(
  601. [email hidden]$orig.ident == "JK211112_J3_KI_T2", "KI rep2", ""
  602. )
  603. )
  604. ))
  605. umap.3mo.sample <- DimPlot(sobj_3mo, reduction = "umap", group.by = "cell_states", split.by = "sample", pt.size = 0.5, cols = c(sobj_3mo_pal), ncol = 2)+
  606. theme(aspect.ratio = 1,
  607. legend.text = element_text(size = 15),
  608. axis.line = element_blank(),
  609. axis.title = element_blank(),
  610. axis.text = element_blank(),
  611. axis.ticks = element_blank(),
  612. legend.key.size = unit(0.5, "cm"),
  613. legend.title = element_text(color = "black", size = 18, face = 2),)+
  614. guides(color = guide_legend(override.aes = list(size = 6)))+
  615. ggtitle(element_blank())
  616. umap.3mo.sample
  617. ```
  618. #Figure
  619. ```{r, fig.height= 6, fig.width= 18}
  620. plot_mpc_s3mo
  621. ```
  622. #______________________________________________________________________________
  623. # DEA
  624. ## Cluster-wise comparison
  625. ## KI Cluster 2 vs WT resting
  626. ```{r}
  627. set.seed(42)
  628. #set and check idents
  629. Idents(sobj_3mo) <- "cell_states"
  630. levels(Idents(sobj_3mo))
  631. #subset the object to have only the clusters interested in the comparison
  632. sobj_3mo_sub1 <- subset(sobj_3mo, idents = c("KI Cluster 2", "WT Resting"))
  633. #assess differentially expressed genes with MAST
  634. ki.c2.wt.dea <- FindMarkers(sobj_3mo_sub1, min.pct = 0.25, logfc.threshold = 0, ident.1 = "KI Cluster 2", ident.2 = "WT Resting", test.use= "MAST")
  635. #add gene names to the output dataframe
  636. ki.c2.wt.dea$genes <- rownames(ki.c2.wt.dea)
  637. #select statistically significant genes with p.adjust < 0.01 and log2FC >< 0.25
  638. ki.c2.wt.dea_filt <- up_down_degs(ki.c2.wt.dea)
  639. #determination of markers to plot
  640. #select upregulated degs
  641. up_degs_ki.c2.wt.dea <- dplyr::filter(ki.c2.wt.dea_filt, Regulation == "up")
  642. #order in function of log2FC
  643. up_degs_ki.c2.wt.dea_ord <- dplyr::arrange(up_degs_ki.c2.wt.dea, desc(avg_log2FC))
  644. #subset for top 20 genes to display
  645. top20_up_degs_fc_ord_ki.c2.wt.dea <- up_degs_ki.c2.wt.dea_ord[1:20, ]
  646. #select downregulated degs
  647. dn_degs_ki.c2.wt.dea <- dplyr::filter(ki.c2.wt.dea_filt, Regulation == "down")
  648. #order in function of log2FC
  649. dn_degs_ki.c2.wt.dea_ord <- dplyr::arrange(dn_degs_ki.c2.wt.dea, avg_log2FC)
  650. #subset for top 20 genes to display
  651. top20_dn_degs_fc_ord_ki.c2.wt.dea <- dn_degs_ki.c2.wt.dea_ord[1:20, ]
  652. ```
  653. ## KI Cluster 1 vs WT resting
  654. ```{r}
  655. set.seed(42)
  656. #set and check idents
  657. Idents(sobj_3mo) <- "cell_states"
  658. levels(Idents(sobj_3mo))
  659. #subset the object to have only the clusters interested in the comparison
  660. sobj_3mo_sub2<- subset(sobj_3mo, idents = c("KI Cluster 1", "WT Resting"))
  661. #assess differentially expressed genes with MAST
  662. ki.c1.wt.dea <- FindMarkers(sobj_3mo_sub2, min.pct = 0.25, logfc.threshold = 0, ident.1 = "KI Cluster 1", ident.2 = "WT Resting", test.use= "MAST")
  663. ki.c1.wt.dea$genes <- rownames(ki.c1.wt.dea)
  664. #filter for statistically significant genes with p.adjust < 0.01 and log2FC >< 0.25
  665. ki.c1.wt.dea_filt <- up_down_degs(ki.c1.wt.dea)
  666. #determination of markers to plot
  667. up_degs_ki.c1.wt.dea <- dplyr::filter(ki.c1.wt.dea_filt, Regulation == "up")
  668. up_degs_ki.c1.wt.dea_ord <- dplyr::arrange(up_degs_ki.c1.wt.dea, desc(avg_log2FC))
  669. top20_up_degs_fc_ord_ki.c1.wt.dea <- up_degs_ki.c1.wt.dea_ord[1:20, ]
  670. dn_degs_ki.c1.wt.dea <- dplyr::filter(ki.c1.wt.dea_filt, Regulation == "down")
  671. dn_degs_ki.c1.wt.dea_ord <- dplyr::arrange(dn_degs_ki.c1.wt.dea, avg_log2FC)
  672. top20_dn_degs_fc_ord_ki.c1.wt.dea <- dn_degs_ki.c1.wt.dea_ord[1:20, ]
  673. ```
  674. ## Union of upregulated genes in KI clusters when compared with WT Resting
  675. ```{r}
  676. #filter for upregulated genes in KI Cluster 2
  677. up_ki.c2vswt_all <- subset(ki.c2.wt.dea_filt, Regulation == "up")
  678. #fiilter for upregulated genes in KI Cluster 1
  679. up_ki.c1vswt_all <- subset(ki.c1.wt.dea_filt, Regulation == "up")
  680. #union of upregulated genes in KI Cluster 1 and 2
  681. up_kivswt_union <- unique(c(up_ki.c2vswt_all$genes, up_ki.c1vswt_all$genes))
  682. #union of all DEGs in KI Cluster 1 and 2
  683. all_kivswt_union <- unique(c(ki.c2.wt.dea_filt$genes, ki.c1.wt.dea_filt$genes))
  684. ```
  685. # GO enrichment
  686. ## KI Cluster 2 vs WT resting
  687. ```{r}
  688. ## Define universe for GO enrichment
  689. univers <- unique(rownames(sobj_3mo@assays[["RNA"]]@counts))
  690. # Perform enrichment analysis for up-regulated genes
  691. ego_up <- enrichGO(gene = up_ki.c2vswt_all$genes,
  692. OrgDb = org.Hs.eg.db,
  693. keyType = "SYMBOL",
  694. ont = "BP",
  695. pvalueCutoff = 0.05,
  696. pAdjustMethod = "BH",
  697. universe = univers,
  698. qvalueCutoff = 0.2,
  699. minGSSize = 10,
  700. maxGSSize = 500,
  701. readable = FALSE)
  702. #add information to enrich GO result to later merge results for enriched terms relative to up- and downregulated genes
  703. ego_up_res_cmplt <- ego_up@result
  704. ego_up_res_cmplt$status <- "up"
  705. # Subset down-regulated genes
  706. dn_genes <- subset(ki.c2.wt.dea_filt, Regulation == "down")
  707. # Perform enrichment analysis for down-regulated genes
  708. ego_down <- enrichGO(gene = dn_genes$genes,
  709. OrgDb = org.Hs.eg.db,
  710. keyType = "SYMBOL",
  711. ont = "BP",
  712. pvalueCutoff = 0.05,
  713. pAdjustMethod = "BH",
  714. universe = univers,
  715. qvalueCutoff = 0.2,
  716. minGSSize = 10,
  717. maxGSSize = 500,
  718. readable = FALSE)
  719. #add information to enrich GO result to later merge results for enriched terms relative to up- and downregulated genes
  720. ego_down_res_cmplt <- ego_down@result
  721. ego_down_res_cmplt$status <- "down"
  722. # Combine the results and filter for the most relevant ones
  723. ego_combined_cmplt_ki.c2 <- dplyr::bind_rows(ego_down_res_cmplt, ego_up_res_cmplt)
  724. # filter for statistically significant enriched terms
  725. ego_combined_ki.c2 <- dplyr::filter(ego_combined_cmplt_ki.c2, qvalue < 0.2)
  726. ```
  727. ## KI Cluster 1 vs WT resting
  728. ```{r}
  729. # Define a function to perform the go enrichment analysis and generate the dot plot
  730. # Subset up-regulated genes
  731. up_genes_ki.c1 <- subset(ki.c1.wt.dea_filt, Regulation == "up")
  732. # Perform enrichment analysis for up-regulated genes
  733. ego_up_ki.c1 <- enrichGO(gene = up_genes_ki.c1$genes,
  734. OrgDb = org.Hs.eg.db,
  735. keyType = "SYMBOL",
  736. ont = "BP",
  737. pvalueCutoff = 0.05,
  738. pAdjustMethod = "BH",
  739. universe = univers,
  740. qvalueCutoff = 0.2,
  741. minGSSize = 10,
  742. maxGSSize = 500,
  743. readable = FALSE)
  744. ego_up_res_cmplt_ki.c1 <- ego_up_ki.c1@result
  745. ego_up_res_cmplt_ki.c1$status <- "up"
  746. # Subset up-regulated genes
  747. dn_genes_ki.c1 <- subset(ki.c1.wt.dea_filt, Regulation == "down")
  748. # Perform enrichment analysis for down-regulated genes
  749. ego_down_ki.c1 <- enrichGO(gene = dn_genes_ki.c1$genes,
  750. OrgDb = org.Hs.eg.db,
  751. keyType = "SYMBOL",
  752. ont = "BP",
  753. pvalueCutoff = 0.05,
  754. pAdjustMethod = "BH",
  755. universe = univers,
  756. qvalueCutoff = 0.2,
  757. minGSSize = 10,
  758. maxGSSize = 500,
  759. readable = FALSE)
  760. ego_down_res_cmplt_ki.c1 <- ego_down_ki.c1@result
  761. ego_down_res_cmplt_ki.c1$status <- "down"
  762. # Combine the results
  763. ego_combined_cmplt_ki.c1 <- dplyr::bind_rows(ego_down_res_cmplt_ki.c1, ego_up_res_cmplt_ki.c1)
  764. ego_combined_ki.c1 <- dplyr::filter(ego_combined_cmplt_ki.c1, qvalue < 0.2)
  765. ```
  766. #______________________________________________________________________________
  767. # Figure
  768. ## DEGs between KI Cluster 2 and WT resting
  769. ## Highlight plots
  770. ```{r}
  771. #Highlight plots
  772. levels(Idents(sobj_3mo))
  773. Idents(sobj_3mo) <- "cell_states"
  774. WT <- WhichCells(sobj_3mo, idents = c("WT Resting"))
  775. ki.c2 <- WhichCells(sobj_3mo, idents = c("KI Cluster 2"))
  776. cells_wtki.c2 <- list("WT" = WT,
  777. "KI Cluster 2" = ki.c2)
  778. highlight_ki.c2 <- Cell_Highlight_Plot(seurat_object = sobj_3mo, cells_highlight = cells_wtki.c2, highlight_color = c("#228b22", "#ffb90f"))+
  779. theme(aspect.ratio = 1,
  780. legend.text = element_text(size = 15),
  781. axis.line = element_blank(),
  782. axis.title = element_blank(),
  783. axis.text = element_blank(),
  784. axis.ticks = element_blank(),
  785. legend.key.size = unit(0.5, "cm"),
  786. legend.title = element_text(color = "black", size = 18, face = 2),
  787. legend.position.inside = c(0.65 ,0.25))+
  788. guides(color = guide_legend(override.aes = list(size = 6)))
  789. highlight_ki.c2
  790. ```
  791. ```{r, fig.height=4, fig.width=8}
  792. #input dataframe for barplot of DEGs
  793. ki.c2.wt.degs.count <- data.frame(status = names(table(ki.c2.wt.dea_filt$Regulation)),
  794. total = as.vector(table(ki.c2.wt.dea_filt$Regulation)))
  795. #barplot
  796. ki.c2.wt.dea_bp <- ggplot(ki.c2.wt.degs.count, aes(x = status, y = total ,fill = status))+
  797. geom_bar(stat= "identity", width = 0.9)+
  798. scale_fill_manual(values = c("#00798c","#cc0000"))+
  799. geom_text(aes(label = total), vjust= -0.2, size = 6, hjust = 1)+
  800. coord_flip()+
  801. theme_classic()+
  802. theme(aspect.ratio = 0.5,
  803. legend.position = 'none',
  804. axis.text.x = element_text(size=20, angle=0),
  805. axis.text.y = element_text(size=20, angle=0),
  806. axis.title = element_text(size = 20),
  807. axis.line = element_line(linewidth = 1.5))+
  808. scale_x_discrete(labels = c("up" = "KI Cluster 2 vs WT Resting up",
  809. "down" = "KI Cluster 2 vs WT Resting down"))+
  810. ylab("number of DEGs")+
  811. xlab(label= NULL)
  812. #number of cells in the respective clusters
  813. table(Idents(sobj_3mo_sub1))
  814. ki.c2.wt.dea_bp
  815. ```
  816. #Figure
  817. ## DEGs heatmap
  818. ```{r, fig.height=7, fig.width=15}
  819. # create vector with the top 20 degs
  820. ki2wt_markers_to_plot <- dplyr::bind_rows(top20_up_degs_fc_ord_ki.c2.wt.dea, top20_dn_degs_fc_ord_ki.c2.wt.dea)
  821. ki2wt_markers_to_plot_vec <- ki2wt_markers_to_plot$gene
  822. ```
  823. ```{r, fig.height= 10, fig.width=5}
  824. Idents(sobj_3mo_sub1) <- factor(Idents(sobj_3mo_sub1),
  825. levels = c("WT Resting", "KI Cluster 2"))
  826. #heatmap of top 20 DEGs expressed between two time points (assessed with MAST)
  827. [email hidden]$HM <- Idents(sobj_3mo_sub1)
  828. wtki2_heat <- DoHeatmap(sobj_3mo_sub1, features = ki2wt_markers_to_plot_vec, size = 4,
  829. angle = 45, group.by = "HM", draw.lines = T, raster = FALSE)+
  830. scale_fill_gradientn(colors = c("blue", "white", "red"))
  831. wtki2_heat
  832. ```
  833. #Figure
  834. ## GO dotplot
  835. ```{r, fig.width=9, fig.height=3.5}
  836. #split in up and down to select non redundant terms more easily
  837. up_ki.ki2 <- subset(ego_combined_ki.c2, status== "up")
  838. dn_ki.ki2 <- subset(ego_combined_ki.c2, status== "down")
  839. #selection of non redundant terms
  840. selected_got_ki.c2vswt0 <- subset(ego_combined_ki.c2, Description %in% c("humoral immune response", "immune response-regulating cell surface receptor signaling pathway", "regulation of myeloid leukocyte differentiation", "regulation of chemotaxis", "acute inflammatory response", "regulation of neuron death", "antigen processing and presentation of peptide antigen", "MHC class II protein complex assembly", "peptide antigen assembly with MHC protein complex"))
  841. #modify aesthetics
  842. selected_got_ki.c2vswt0$Description <- factor(selected_got_ki.c2vswt0$Description, levels = unique(c("humoral immune response", "immune response-regulating cell surface receptor signaling pathway", "regulation of myeloid leukocyte differentiation", "regulation of chemotaxis", "acute inflammatory response", "regulation of neuron death", "antigen processing and presentation of peptide antigen", "MHC class II protein complex assembly", "peptide antigen assembly with MHC protein complex")))
  843. #dotplot
  844. ki.c2.wt_goe_sel <- ego_dp(selected_got_ki.c2vswt0)
  845. #modify aesthetics
  846. ki.c2.wt_goe_sel+
  847. scale_color_gradient(low ="#6a329f", high = "#cd99e7")+
  848. theme(axis.text.x = element_text(size = 14, face = "bold"),
  849. axis.text.y = element_text(size = 14, face = "bold"))
  850. ```
  851. #Figure
  852. ## DEGs between KI Cluster 1 vs WT resting
  853. ```{r}
  854. #Highlight plots
  855. levels(Idents(sobj_3mo))
  856. Idents(sobj_3mo) <- "cell_states"
  857. WT <- WhichCells(sobj_3mo, idents = c("WT Resting"))
  858. ki.c1 <- WhichCells(sobj_3mo, idents = c("KI Cluster 1"))
  859. cells_wtki.c1 <- list("WT" = WT,
  860. "KI Cluster 1" = ki.c1)
  861. highlight_ki.c1 <- Cell_Highlight_Plot(seurat_object = sobj_3mo, cells_highlight = cells_wtki.c1, highlight_color = c("#228b22", "#eae4b7"))+
  862. theme(aspect.ratio = 1,
  863. legend.text = element_text(size = 15),
  864. axis.line = element_blank(),
  865. axis.title = element_blank(),
  866. axis.text = element_blank(),
  867. axis.ticks = element_blank(),
  868. legend.key.size = unit(0.5, "cm"),
  869. legend.title = element_text(color = "black", size = 18, face = 2),
  870. legend.position.inside = c(0.65 ,0.25))+
  871. guides(color = guide_legend(override.aes = list(size = 6)))
  872. highlight_ki.c1
  873. ```
  874. barplot
  875. ```{r}
  876. #input dataframe for barplot of DEGs
  877. ki.c1.wt.degs.count <- data.frame(status = names(table(ki.c1.wt.dea_filt$Regulation)),
  878. total = as.vector(table(ki.c1.wt.dea_filt$Regulation)))
  879. #barplot
  880. ki.c1.wt.dea_bp <- ggplot(ki.c1.wt.degs.count, aes(x = status, y = total ,fill = status))+
  881. geom_bar(stat= "identity", width = 0.9)+
  882. scale_fill_manual(values = c("#00798c","#cc0000"))+
  883. geom_text(aes(label = total), vjust= -0.2, size = 6, hjust = 1)+
  884. coord_flip()+
  885. theme_classic()+
  886. theme(aspect.ratio = 0.5,
  887. legend.position = 'none',
  888. axis.text.x = element_text(size=20, angle=0),
  889. axis.text.y = element_text(size=20, angle=0),
  890. axis.title = element_text(size = 20),
  891. axis.line = element_line(linewidth = 1.5))+
  892. scale_x_discrete(labels = c("up" = "KI Cluster 1 vs WT Resting up",
  893. "down" = "KI Cluster 1 vs WT Resting down"))+
  894. ylab("number of DEGs")+
  895. xlab(label= NULL)
  896. #number of cells in the respective clusters
  897. table(Idents(sobj_3mo_sub2))
  898. ki.c1.wt.dea_bp
  899. ```
  900. #Figure
  901. ## DEGs heatmap
  902. ```{r, fig.height= 10, fig.width=5}
  903. Idents(sobj_3mo_sub2) <- factor(Idents(sobj_3mo_sub2),
  904. levels = c("WT Resting", "KI Cluster 1"))
  905. # create vector with the top 20 degs
  906. ki1wt_markers_to_plot <- dplyr::bind_rows(top20_up_degs_fc_ord_ki.c1.wt.dea, top20_dn_degs_fc_ord_ki.c1.wt.dea)
  907. ki1wt_markers_to_plot_vec <- ki1wt_markers_to_plot$gene
  908. #heatmap of top 20 DEGs expressed between two time points (assessed with MAST)
  909. [email hidden]$HM <- Idents(sobj_3mo_sub2)
  910. wtki1_heat <- DoHeatmap(sobj_3mo_sub2, features = ki1wt_markers_to_plot_vec, size = 4,
  911. angle = 45, group.by = "HM", draw.lines = T, raster = FALSE)+
  912. scale_fill_gradientn(colors = c("blue", "white", "red"))
  913. wtki1_heat
  914. ```
  915. #Figure
  916. ## GO dotplot
  917. ```{r, fig.width=6, fig.height=3.5}
  918. #split in up and down to select non redundant terms more easily
  919. up_ki.c1 <- subset(ego_combined_ki.c1, status== "up")
  920. dn_ki.c1 <- subset(ego_combined_ki.c1, status== "down")
  921. #selection of non redundant terms
  922. selected_got_ki.c1vswt0 <- subset(ego_combined_ki.c1, Description %in% c("cell junction disassembly", "positive regulation of endocytosis", "inflammatory response to antigenic stimulus", "mononuclear cell migration", "regulation of lipid metabolic process", "response to nutrient levels"))
  923. #modify aesthetics
  924. selected_got_ki.c1vswt0$Description <- factor(selected_got_ki.c1vswt0$Description, levels = unique(c("cell junction disassembly", "positive regulation of endocytosis", "inflammatory response to antigenic stimulus", "mononuclear cell migration", "regulation of lipid metabolic process", "response to nutrient levels")))
  925. #dotplot
  926. ki.c1.wt_goe_sel <- ego_dp(selected_got_ki.c1vswt0)
  927. #modify aestethics
  928. ki.c1.wt_goe_sel+
  929. scale_color_gradient(low ="#6a329f", high = "#cd99e7")+
  930. theme(axis.text.x = element_text(size = 14, face = "bold"),
  931. axis.text.y = element_text(size = 14, face = "bold"))
  932. ```
  933. #_____________________________________________________________________________________________________
  934. ## Expression of AD-risk genes
  935. Expression levels of genes curated from GWAS studies aimed at identifying risk factors in AD. The list of genes was taken from Mancuso et al., 2024 supplementary table 4
  936. Publication:
  937. Mancuso, R., Fattorelli, N., Martinez-Muriana, A. et al. Xenografted human microglia display diverse transcriptomic states in response to Alzheimer’s disease-related amyloid-β pathology. Nat Neurosci 27, 886–900 (2024). https://doi.org/10.1038/s41593-024-01600-y
  938. https://www.nature.com/articles/s41593-024-01600-y?s=31
  939. ```{r}
  940. #load gene list extrapolated from Mancuso et al., supplementary
  941. #Mancuso_2024_AD_risk_gene_list (import .xlsx file)
  942. #get list of genes
  943. ad_risk_genes <- mancuso_ad_risk$genes
  944. length(ad_risk_genes)
  945. ```
  946. ```{r, fig.width= 30, fig.height= 8}
  947. #are any of these genes DEG in the KI clusters of this dataset?
  948. ad_risk_deg_paquet <- intersect(ad_risk_genes, all_kivswt_union)
  949. ad_risk_deg_paquet
  950. #select genes
  951. ad_risk_genes_deg <- c("ANKH", "BLNK", "CLU", "SORL1", "TREM2", "HLA-DQA1", "HLA-DRB1")
  952. ```
  953. ## Signature scoring
  954. Zhou et al.,2020 signature
  955. Publication:
  956. Zhou, Y., Song, W.M., Andhey, P.S. et al. Human and mouse single-nucleus transcriptomics reveal TREM2-dependent and TREM2-independent cellular responses in Alzheimer’s disease. Nat Med 26, 131–142 (2020). https://doi.org/10.1038/s41591-019-0695-9
  957. https://www.nature.com/articles/s41591-019-0695-9
  958. Dataset description:
  959. Human and mouse single-nucleus transcriptomics reveal TREM2-dependent and -independent cellular responses in Alzheimer’s disease
  960. source of signature: supplementary table 4-Micro 0 signature
  961. ```{r}
  962. #import zhou et al supplementary from excel
  963. #zhou_supp4 <-read_excel("/path/zhou_tablesup4_micro0.xlsx")
  964. #extract gene list
  965. zhou_sig <- list("gene.symbol" = zhou_supp4$gene)
  966. #dimension of signature
  967. length(zhou_sig[[1]])
  968. ```
  969. ```{r}
  970. #set idents
  971. Idents(sobj_3mo) <- "genotype"
  972. #scoring of signature
  973. sobj_3mo <- AddModuleScore_UCell(sobj_3mo, features = zhou_sig, name = "zhou1")
  974. ```
  975. #________________________________________________________________________________________________
  976. # Figure
  977. ## AD risk genes in KI cultures
  978. ```{r, fig.height=8, fig.width=3}
  979. #stacked violin
  980. Idents(sobj_3mo) <- "cell_states"
  981. sobj_3mo_sub4 <- subset(sobj_3mo, idents = c("WT Resting", "KI Cluster 1", "KI Cluster 2"))
  982. [email hidden]$id_factor <- factor([email hidden]$cell_states, levels = c("WT Resting", "KI Cluster 1", "KI Cluster 2"))
  983. Idents(sobj_3mo_sub4) <- "id_factor"
  984. #violin plot
  985. Stacked_VlnPlot(seurat_object = sobj_3mo_sub4, features = c("ANKH", "BLNK", "SORL1", "TREM2", "HLA-DQA1", "HLA-DRB1", "CLU"),
  986. x_lab_rotate = TRUE, idents = c("WT Resting", "KI Cluster 1", "KI Cluster 2"), colors_use = c("#228b22","#eae4b7", "#ffb90f"))+
  987. theme(aspect.ratio = 1.5)
  988. ```
  989. # Fig
  990. ## Enrichment for Zhou et al, signature
  991. ```{r}
  992. #WT resting vs KI Inflammatory vs KI 2
  993. #set idents
  994. Idents(sobj_3mo_sub4) <- "cell_states"
  995. #subset for clusters of interest
  996. v.cl <- VlnPlot(sobj_3mo_sub4, assay="RNA",
  997. features = "gene.symbolzhou1" ,
  998. pt.size = 0, cols = c("#228b22", "#eae4b7", "#ffb90f")) +
  999. geom_boxplot(width = 0.4)+
  1000. ylim(0.1, 0.45)+
  1001. scale_x_discrete(limits = c("WT Resting", "KI Cluster 1", "KI Cluster 2"))+
  1002. NoLegend() +
  1003. geom_signif(test = "wilcox.test",
  1004. map_signif_level = F,
  1005. comparisons = list(c("WT Resting", "KI Cluster 1"),
  1006. c("WT Resting", "KI Cluster 2")),
  1007. y_position = c(0.37, 0.4))+
  1008. theme(aspect.ratio = 0.9,
  1009. title = element_blank(),
  1010. axis.text.x = element_text(size=14, angle=45, hjust = 1),
  1011. axis.text.y = element_text(size=14, angle=0),
  1012. axis.title.x = element_text(face = "bold", size = 14),
  1013. axis.title.y = element_text(face = "bold", size = 14))+
  1014. xlab("")+
  1015. ylab("ES")+
  1016. ggtitle("AD microglia signature", subtitle = "Zhou et al., 2020")
  1017. v.cl
  1018. #stat
  1019. es_df_ad <- [email hidden][, c("cell_states", "gene.symbolzhou1")]
  1020. #stat
  1021. es_df_ad <- [email hidden][, c("cell_states", "gene.symbolzhou1")]
  1022. #ordering
  1023. es_df_ad$cell_states <- ordered(es_df_ad$cell_states,
  1024. levels = c("WT Resting", "KI Cluster 1", "KI Cluster 2"))
  1025. kruskal.test(gene.symbolzhou1 ~ cell_states, data = es_df_ad)
  1026. ```
  1027. ```{r}
  1028. #levels(Idents(sobj_3mo_sub4))
  1029. # sobj_3mo_sub4$cell_states_subset <- Idents(sobj_3mo_sub4)
  1030. #Idents(sobj_3mo_sub4) <- "cell_states_subset"
  1031. #scoring of signature
  1032. # sobj_3mo_sub4 <- AddModuleScore_UCell(sobj_3mo_sub4, features = zhou_sig, name = "zhou_sub")
  1033. es_df <- FetchData(sobj_3mo_sub4, vars = c("cell_states_subset", "gene.symbolzhou_sub"))
  1034. summary(es_df)
  1035. table(es_df$cell_states_subset, useNA = "ifany")
  1036. table(es_df$gene.symbolzhou_sub, useNA = "ifany")
  1037. kruskal.test(gene.symbolzhou_sub ~ cell_states_subset, data = es_df)
  1038. p <- ggplot(es_df, aes(x= cell_states_subset, y = gene.symbolzhou_sub))+
  1039. geom_violin(trim = FALSE)
  1040. p <- p + geom_signif(comparisons = list(c("WT Resting", "KI Cluster 1"),
  1041. c("WT Resting", "KI Cluster 2")),
  1042. map_signif_level = FALSE,
  1043. test = "wilcox.test")
  1044. p
  1045. rm(p)
  1046. p <- ggplot(es_df, aes(x= cell_states_subset, y = gene.symbolzhou_sub))+
  1047. geom_violin(trim = FALSE)
  1048. p <- p + geom_signif(map_signif_level = FALSE,
  1049. test = "kruskal.test")
  1050. p
  1051. ```
  1052. #______________________________________________________________________________________________________________________________
  1053. #Figure
  1054. #Overlap between updegs in KI Cluster 2 and Zhou signature
  1055. ```{r}
  1056. #paquet: up_kivswt_union
  1057. #zhou:
  1058. zhou_chr <- zhou_sig[[1]]
  1059. #background: total of tested genes in differential expression analysis
  1060. total.degs <- union(x = ki.c2.wt.dea$genes, y = ki.c1.wt.dea$genes)
  1061. total.degs <- unique(total.degs)
  1062. total.degs.num <- length(total.degs)
  1063. #create gene overlap object
  1064. go.objB <- newGeneOverlap(listA = up_kivswt_union, listB = zhou_chr, genome.size = total.degs.num)
  1065. #stat
  1066. go.objB <- testGeneOverlap(go.objB)
  1067. #show odds ratio
  1068. print(go.objB)
  1069. ```
  1070. ```{r}
  1071. gene.set <- list("KI 3mo" = up_kivswt_union, "Zhou et al., 2020 signature" = zhou_chr)
  1072. resPZ <- supertest(x= gene.set, n= total.degs.num)
  1073. plot.pz <- as.ggplot(~plot(resPZ, Layout="landscape", sort.by="size", keep=FALSE,
  1074. show.elements=TRUE,
  1075. elements.cex=0.7,
  1076. elements.list=subset(summary(resPZ)$Table,Observed.Overlap <= 20),
  1077. show.expected.overlap=F,
  1078. color.expected.overlap='red',
  1079. color.on = NULL))
  1080. plot.pz
  1081. summary(resPZ)$Table
  1082. ```

Figure5_scRNA_microglia_KI.Rmd at commit 31c0793, no license · at the source

Overview

Authors: Julien Klimmt1,2, Carolina Cardoso Gonçalves1,2, Jessica Valentina Montgomery3, Stephan A. Müller4,5, Merle Bublitz1,2, Severin Filser1, Lars Paeger4,6, Brigitte Nuscher7, Angelika Dannert1,2, Sigrun Roeber6, Veronica Pravata8, Martina Schifferer4,9, Joshua J. Shrouder1, Nathalie Schulz1, Judit González-Gallego1,2, Silvia Cappello8,9,10, Thomas Misgeld4,9,11, Nikolaus Plesnila1,9, Eduardo Beltrán9,12,13, Jochen Herms4,6,9
and 7 other authorsElena De Domenico3,14, Marc D. Beyer3,14,15, Joachim L. Schultze3,14,16, Christian Haass4,7,9, Stefan F. Lichtenthaler4,5,9, Caterina Carraro3, Dominik Paquet1,9
16 affiliations
  1. Institute for Stroke and Dementia Research (ISD), LMU University Hospital, LMU Medizin, LMU Munich,Munich, Germany
  2. Graduate School of Systemic Neuroscience (GSN), LMU Munich,Munich, Germany
  3. Systems Medicine, Deutsches Zentrum für Neurodegenerative Erkrankungen (DZNE) e.V.,Bonn, Germany
  4. German Center for Neurodegenerative Diseases (DZNE) Munich,Munich, Germany
  5. Neuroproteomics, School of Medicine and Health, TUM University Hospital, Technical University of Munich,Munich, Germany
  6. Institute of Neuropathology, LMU Medizin, LMU Munich,Munich, Germany
  7. Metabolic Biochemistry, Biomedical Center (BMC), Faculty of Medicine, LMU Munich,Munich, Germany
  8. Chair of Physiological Genomics, Biomedical Center (BMC), LMU Medizin, LMU Munich,Munich, Germany
  9. Munich Cluster for Systems Neurology (SyNergy),Munich, Germany
  10. Max-Planck-Institute of Psychiatry,Munich, Germany
  11. Institute of Neuronal Cell Biology, Technical University of Munich,Munich, Germany
  12. Institute of Clinical Neuroimmunology, LMU University Hospital, LMU Medizin, LMU Munich,Munich, Germany
  13. Biomedical Center (BMC), LMU Medizin, LMU Munich,Munich, Germany
  14. PRECISE Platform for Genomics and Epigenomics, Deutsches Zentrum für Neurodegenerative Erkrankungen (DZNE) e.V. and University of Bonn and West German Genome Center,Bonn, Germany
  15. Immunogenomics & Neurodegeneration, Deutsches Zentrum für Neurodegenerative Erkrankungen (DZNE) e.V.,Bonn, Germany
  16. Genomics and Immunoregulation, Life & Medical Sciences (LIMES) Institute, University of Bonn,Bonn, Germany
Journal: Nature neuroscience, volume 29, issue 9, pages 2324-2340
Dates: received 17 October 2024; accepted 10 June 2026; published online 4 August 2026; in print 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s41593-026-02367-0 · PMID 42552384 · PMCID PMC13533838 · OpenAlex W7172420001
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: human (organism), Alzheimer's / dementia (population), cellular / molecular (subfield)
Methods: Statistics, Smoothing, state filtering, decompositions, Machine learning, Connectivity, Single-unit activity, calcium imaging
Keywords: Neuroimmunology, Induced pluripotent stem cells, Alzheimer's disease, Neurodegeneration, Experimental models of disease
MeSH: Alzheimer Disease*, Brain*, Induced Pluripotent Stem Cells*, Microglia*, Amyloid beta-Peptides, Astrocytes, Humans, Neurons, Phenotype (* major topic)
Journal subjects: Technical Report
Topic: Neuroinflammation and Neurodegeneration Mechanisms (Neurology, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 106 references in the paper
Research resources: male iPSC line GM05399 RRID:CVCL_7425, 3) KOLF2.1J cell line RRID:CVCL_B5P3, 409B2 line RRID:CVCL_K092, female iPSC line A18944 RRID:CVCL_RM92

Abstract

Stem-cell-based in vitro models offer promising potential to elucidate human brain cell functions and interactions, but limitations in reproducibility, maturation and cell-type diversity persist. Especially, prolonged incorporation of mature microglia and studies of neuroinflammation have proven challenging. Here, we developed a human induced pluripotent stem cell-based three-dimensional cortical brain tissue model (3BTM) containing neurons, astrocytes and microglia with high reproducibility, maturity and viability. 3BTMs show morphological, functional and proteomic maturation of all cell types, leading to high similarity to their in vivo counterparts. Incorporated microglia survive for over 6 months and display mature morphology, functions and gene expression. Importantly, when engineered to model Alzheimer’s disease pathology, 3BTMs recapitulate key disease hallmarks, including amyloid deposition, increased phospho-tau levels and neuroinflammation, with microglia shifting their transcriptional landscape to disease-relevant signatures. Treatment of Alzheimer’s disease 3BTMs with anti-Aβ immunotherapy cleared deposits and largely reversed disease signatures in glia. Together, our microglia-containing model provides a platform for studying physiological and pathological states of human brain tissue.

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

Repositories

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

jsschrepping/r_docker

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 187c49cdfa925ebd14226ede042ddc0122cf6215, 29 April 2024
Languages: R (10), Shell (1)
Size: 20 files, 11 scripts
Software Heritage: archived
Found in: the text, “Sample preparation for BD Rhapsody datasets”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Monocle 3 (2 files), circlize (1 file), clusterProfiler (1 file), ComplexHeatmap (1 file), data.table (1 file), DESeq2 (1 file), edgeR (1 file), ggpubr (1 file), Harmony (1 file), igraph (1 file), limma (1 file), multcomp (1 file), patchwork (1 file), pheatmap (1 file), reshape2 (1 file), reticulate (1 file), Seurat (1 file), SingleCellExperiment (1 file), Subread (featureCounts) (1 file), tidyverse (1 file), WGCNA (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
13 files

gitlab.dzne.de/ag-beyer/singlecell_analysis_3btm

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 31c079315b8210b043d0b6d72b92ad5a18e0d168, 8 May 2026
Languages: R (6)
Size: 10 files, 6 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, 6 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: clusterProfiler (6 files), ComplexHeatmap (6 files), cowplot (6 files), ggpubr (6 files), Harmony (6 files), patchwork (6 files), reshape2 (6 files), Seurat (6 files), tidyverse (6 files), data.table (5 files), ggplot2 (5 files), reticulate (5 files), DESeq2 (4 files), edgeR (4 files), circlize (3 files), Monocle 3 (2 files), igraph (1 file), SingleCellExperiment (1 file), WGCNA (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
7 files

Code availability

All original code to analyze the scRNA-seq data, and the tool and package information to fully reproduce the analysis is publicly available via GitLab at https://gitlab.dzne.de/ag-beyer/singlecell_analysis_3btm. Any additional information required to reanalyze the data reported in this article is available from the lead contact upon reasonable request.

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

Tracing map

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

What the map holds:

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

The scRNA-seq profiling datasets have been deposited with the European Genome-phenome Archive (EGA) (10X dataset: EGAS50000000469 (https://ega-archive.org/studies/EGAS50000000469); Rhapsody dataset 2D versus 3D: EGAS50000001392 (https://ega-archive.org/studies/EGAS50000001392); Rhapsody dataset SA2 + A18 WT versus knock-in and sAβ42 ± aducanumab treatment: EGAS50000001397 (https://ega-archive.org/studies/EGAS50000001397)). Access to these datasets will be granted upon request to the Data Access Committee to protect the rights of human donors. The MS proteomic datasets have been deposited with the ProteomeXchange Consortium via the PRIDE partner repository with dataset ID PXD055254 (https://www.ebi.ac.uk/pride/archive/projects/PXD055254) (dataset 1–3BTM maturation in SA2 line in comparison to NOs and human brain samples), PXD069984 (https://www.ebi.ac.uk/pride/archive/projects/PXD069984) (dataset 2–reproducibility of 3BTMs across iPSC lines and comparison to 2D co-cultures) and PXD071849 (https://www.ebi.ac.uk/pride/archive/projects/PXD071849) (dataset 3–comparison of WT and knock-in 3BTMs). The original microscopy data reported in this article will be shared by the lead contact upon request because of large file sizes. Source data are provided with this paper.

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

Versions

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

Version 3, 28 September 2026

  • Publisher: n/a → Nature Portfolio

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 27 authors, 5 keywords, 9 MeSH terms, 2 funders, 104 references, 4 RRIDs.

Cite

This paper

Klimmt, J., Cardoso Gonçalves, C., Montgomery, J. V., Müller, S. A., Bublitz, M., Filser, S., Paeger, L., Nuscher, B., Dannert, A., Roeber, S., Pravata, V., Schifferer, M., Shrouder, J. J., Schulz, N., González-Gallego, J., Cappello, S., Misgeld, T., Plesnila, N., Beltrán, E., . . . Paquet, D. (2026). A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes. Nature neuroscience, 29(9), 2324-2340. https://doi.org/10.1038/s41593-026-02367-0

BibTeX

@article{klimmt2026reproducible,
author = {Klimmt, Julien and Cardoso Gonçalves, Carolina and Montgomery, Jessica Valentina and Müller, Stephan A. and Bublitz, Merle and Filser, Severin and Paeger, Lars and Nuscher, Brigitte and Dannert, Angelika and Roeber, Sigrun and Pravata, Veronica and Schifferer, Martina and Shrouder, Joshua J. and Schulz, Nathalie and González-Gallego, Judit and Cappello, Silvia and Misgeld, Thomas and Plesnila, Nikolaus and Beltrán, Eduardo and Herms, Jochen and De Domenico, Elena and Beyer, Marc D. and Schultze, Joachim L. and Haass, Christian and Lichtenthaler, Stefan F. and Carraro, Caterina and Paquet, Dominik},
title = {{A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes}},
journal = {Nature neuroscience},
year = {2026},
month = aug,
volume = {29},
number = {9},
pages = {2324--2340},
publisher = {Nature Portfolio},
issn = {1097-6256},
doi = {10.1038/s41593-026-02367-0},
url = {https://doi.org/10.1038/s41593-026-02367-0},
pmid = {42552384},
pmcid = {PMC13533838}
}

RIS

TY - JOUR
AU - Klimmt, Julien
AU - Cardoso Gonçalves, Carolina
AU - Montgomery, Jessica Valentina
AU - Müller, Stephan A.
AU - Bublitz, Merle
AU - Filser, Severin
AU - Paeger, Lars
AU - Nuscher, Brigitte
AU - Dannert, Angelika
AU - Roeber, Sigrun
AU - Pravata, Veronica
AU - Schifferer, Martina
AU - Shrouder, Joshua J.
AU - Schulz, Nathalie
AU - González-Gallego, Judit
AU - Cappello, Silvia
AU - Misgeld, Thomas
AU - Plesnila, Nikolaus
AU - Beltrán, Eduardo
AU - Herms, Jochen
AU - De Domenico, Elena
AU - Beyer, Marc D.
AU - Schultze, Joachim L.
AU - Haass, Christian
AU - Lichtenthaler, Stefan F.
AU - Carraro, Caterina
AU - Paquet, Dominik
TI - A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes
T2 - Nature neuroscience
J2 - Nat Neurosci
PY - 2026
DA - 2026/08/04
VL - 29
IS - 9
SP - 2324
EP - 2340
SN - 1097-6256
PB - Nature Portfolio
DO - 10.1038/s41593-026-02367-0
UR - https://doi.org/10.1038/s41593-026-02367-0
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41593-026-02367-0",
"type": "article-journal",
"title": "A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes",
"container-title": "Nature neuroscience",
"author": [
{
"family": "Klimmt",
"given": "Julien"
},
{
"family": "Cardoso Gonçalves",
"given": "Carolina"
},
{
"family": "Montgomery",
"given": "Jessica Valentina"
},
{
"family": "Müller",
"given": "Stephan A."
},
{
"family": "Bublitz",
"given": "Merle"
},
{
"family": "Filser",
"given": "Severin"
},
{
"family": "Paeger",
"given": "Lars"
},
{
"family": "Nuscher",
"given": "Brigitte"
},
{
"family": "Dannert",
"given": "Angelika"
},
{
"family": "Roeber",
"given": "Sigrun"
},
{
"family": "Pravata",
"given": "Veronica"
},
{
"family": "Schifferer",
"given": "Martina"
},
{
"family": "Shrouder",
"given": "Joshua J."
},
{
"family": "Schulz",
"given": "Nathalie"
},
{
"family": "González-Gallego",
"given": "Judit"
},
{
"family": "Cappello",
"given": "Silvia"
},
{
"family": "Misgeld",
"given": "Thomas"
},
{
"family": "Plesnila",
"given": "Nikolaus"
},
{
"family": "Beltrán",
"given": "Eduardo"
},
{
"family": "Herms",
"given": "Jochen"
},
{
"family": "De Domenico",
"given": "Elena"
},
{
"family": "Beyer",
"given": "Marc D."
},
{
"family": "Schultze",
"given": "Joachim L."
},
{
"family": "Haass",
"given": "Christian"
},
{
"family": "Lichtenthaler",
"given": "Stefan F."
},
{
"family": "Carraro",
"given": "Caterina"
},
{
"family": "Paquet",
"given": "Dominik"
}
],
"container-title-short": "Nat Neurosci",
"volume": "29",
"issue": "9",
"page": "2324-2340",
"DOI": "10.1038/s41593-026-02367-0",
"PMID": "42552384",
"PMCID": "PMC13533838",
"ISSN": "1097-6256",
"publisher": "Nature Portfolio",
"URL": "https://doi.org/10.1038/s41593-026-02367-0",
"language": "en",
"issued": {
"date-parts": [
[
2026,
8,
4
]
]
}
}

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.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: Monocle 3, WGCNA, Harmony, 17 other tools, cellular / molecular, 6 references
[2] doi:10.1038/s41586-026-10214-2 [code]
Multidimensional profiling of heterogeneity in supratentorial ependymomas.
Journal: Nature
In common: Monocle 3, Harmony, SingleCellExperiment, 16 other tools, 2 references
[3] doi:10.1038/s42003-026-10957-8 [code]
Brain defence by the extracellular matrix protein Cochlin.
Journal: Communications biology
In common: Subread (featureCounts), Monocle 3, WGCNA, 16 other tools, cellular / molecular
[4] 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: multcomp, Subread (featureCounts), WGCNA, 16 other tools
[5] doi:10.1002/imt2.70163 [code]
Spatial multi-omics unveils sphingolipid metabolic reprogramming within the retinal pathological niche.
Journal: iMeta
In common: Monocle 3, Harmony, SingleCellExperiment, 16 other tools, cellular / molecular
[6] doi:10.1038/s41467-026-70232-6 [code]
Gene expression dynamics of human and mouse craniofacial development at the single-cell level.
Journal: Nature communications
In common: Harmony, SingleCellExperiment, edgeR, 13 other tools, cellular / molecular, 3 references
[7] doi:10.1016/j.isci.2026.115573 [code]
Female cortical cellular mosaicism underlies shared MeCP2 and PCB impacted gene pathways.
Journal: iScience
In common: WGCNA, SingleCellExperiment, edgeR, 13 other tools, cellular / molecular, 2 references
[8] doi:10.1016/j.isci.2026.115657 [code]
Integration of machine learning to develop a disulfidptosis model for predicting glioma prognosis, immunotherapy response, and drug.
Journal: iScience
In common: WGCNA, Harmony, edgeR, 15 other tools
[9] doi:10.1016/j.xcrm.2026.102682 [code]
TET CpG sequence-context-specific DNA demethylation shapes progression of IDH-mutant gliomas.
Journal: Cell reports. Medicine
In common: multcomp, edgeR, limma, 13 other tools, 2 references
[10] doi:10.1016/j.celrep.2026.117500 [code]
Spatio-molecular gene expression reflects dorsal anterior cingulate cortex structure and function in the human brain.
Journal: Cell reports
In common: Harmony, SingleCellExperiment, edgeR, 12 other tools, cellular / molecular, 4 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.