Software

library(Seurat)
library(tidyverse)
library(patchwork)
library(pheatmap)
library(RColorBrewer)
library(data.table)
library(knitr)
library(presto)

Data

Input: Pre-processed Seurat object of integrated thymocyte and T-cell subsets from canine thymus and lymph node.

setwd("C:/Users/edlarsen/Documents/240828_scRNAseq/T_Cells")
all_Tcells <- readRDS(file = "integrated_Tcells.Rdata")
all_Tcells <- FindNeighbors(all_Tcells, dims = 1:10)
all_Tcells <- FindClusters(all_Tcells, resolution = 0.2)
all_Tcells <- RunUMAP(all_Tcells, dims = 1:10)

Module scoring

Park et al. human thymus feature expression

Calculates the average expression levels of each cluster on a single-cell level, subtracted by the aggregated expression of control feature sets. All analyzed features are binned based on averaged expression, and the control features are randomly selected from each bin.

Top 20 marker genes for each cell type in human thymus atlas

Source: Park et al., Supplementary Table 4 (https://www.science.org/doi/10.1126/science.aay3224#supplementary-materials)

# make gene lists
setwd("C:/Users/edlarsen/Documents/240828_scRNAseq/T_Cells")
human_thymus_atlas_top20 <- read.csv("Parketal_SupTable4_Top20MarkersForTCellTypes.csv")
colnames(human_thymus_atlas_top20)
##  [1] "CD4.CTL"   "CD4.PD1"   "CD4.T"     "CD4.Tmem"  "CD8.T"     "CD8.Tmem" 
##  [7] "CD8aa_I"   "CD8aa_II"  "DN_P"      "DN_Q"      "DN_early"  "DP_P"     
## [13] "DP_Q"      "ETP"       "ILC3"      "Lymph"     "NK"        "NKT"      
## [19] "NMP"       "T_agonist" "Tfh"       "Th17"      "Treg"      "Treg_diff"
## [25] "abT_entry" "gdT"
plot_list <- list() # initiate empty list for individual plots

for (column in colnames(human_thymus_atlas_top20)){
  genes <- list(human_thymus_atlas_top20[[column]])
  name <- paste(column, "Score", sep="_")
  all_Tcells <- AddModuleScore(all_Tcells, features = genes, name = name)
  newname <- paste(name, "1", sep="")
  modscoreplot <- FeaturePlot(all_Tcells, features = newname) + scale_color_gradientn(colours = brewer.pal(name = "RdPu", n=11))
  plot_list[[name]] <- modscoreplot # add plot to list
}

# split plot_list into groups of 6 and handle any remaining plots
plot_groups <- split(plot_list, ceiling(seq_along(plot_list) / 6))

# combined plot with dynamic number of columns/rows
combine_plots <- function(group, ncol = 3){
  n_plots <- length(group)
  nrow <- ceiling(n_plots / ncol)
  wrap_plots(group, ncol = ncol, nrow = nrow)
}
combined_plots <- lapply(plot_groups, function(group) {
  combine_plots(group, ncol = 3)
})

# display each combined plot
for (i in seq_along(combined_plots)) {
  print(combined_plots[[i]])
}

Conde et al. human immune cell atlas

Module scoring the average expression levels of each cluster on a single-cell level, subtracted by the aggregated expression of control feature sets. All analyzed features are binned based on averaged expression, and the control features are randomly selected from each bin. Source: https://cells.ucsc.edu/?ds=pan-immune+global. The top 51 markers were exported from UCSC Cell Browser for each annotated cell type.

# make gene lists
human_ln_atlas_top51 <- read.csv("../Cluster_Annotation/CondeEtAl_HumanImmuneCellAtlas_Global.csv")
colnames(human_ln_atlas_top51)
##  [1] "Trm_gut_CD8"                  "TnaiveCM_CD4"                
##  [3] "Tregs"                        "Pro_B"                       
##  [5] "Naive_B"                      "Pre_B"                       
##  [7] "Plasma_Cell"                  "Plasmablasts"                
##  [9] "Memory_B"                     "Erythroid"                   
## [11] "Plasmacytoid_DC"              "Megakaryocytes"              
## [13] "Mast_cells"                   "ILC3"                        
## [15] "Cycling_T_NK"                 "DC_1"                        
## [17] "DC_2"                         "Classical_Monocyte"          
## [19] "Cycling"                      "Progenitor"                  
## [21] "CD8_TEMRA"                    "Migratory_DC"                
## [23] "Trm_Tgd"                      "NK_CD56_Bright_CD16_Negative"
## [25] "NK_CD16_Positive"             "Tgd_CRTAM_Positive"          
## [27] "Tmem_CD8"                     "MAIT"                        
## [29] "T_naive_CM_CD4_activated"     "Trm_Th1_Th17"                
## [31] "T_CD4_CD8"                    "T_naive_CM_CD8"              
## [33] "TEM_CD4"                      "Tfh"
plot_list <- list() # initiate empty list for individual plots

for (column in colnames(human_ln_atlas_top51)){
  genes <- list(human_ln_atlas_top51[[column]])
  name <- paste(column, "Score", sep="_")
  all_Tcells <- AddModuleScore(all_Tcells, features = genes, name = name)
  newname <- paste(name, "1", sep="")
  modscoreplot <- FeaturePlot(all_Tcells, features = newname) + scale_color_gradientn(colours = brewer.pal(name = "RdPu", n=11))
  plot_list[[name]] <- modscoreplot # add plot to list
}

# split plot_list into groups of 6 and handle any remaining plots
plot_groups <- split(plot_list, ceiling(seq_along(plot_list) / 6))

# combined plot with dynamic number of columns/rows
combine_plots <- function(group, ncol = 3){
  n_plots <- length(group)
  nrow <- ceiling(n_plots / ncol)
  wrap_plots(group, ncol = ncol, nrow = nrow)
}
combined_plots <- lapply(plot_groups, function(group) {
  combine_plots(group, ncol = 3)
})

# display each combined plot
for (i in seq_along(combined_plots)) {
  print(combined_plots[[i]])
}

Ammons canine circulating leukocyte atlas

Source: https://cells.ucsc.edu/?ds=canine-leukocyte-atlas+healthy

# make gene lists
ammonsk9_ln_atlas_top51 <- read.csv("../Cluster_Annotation/Ammons_CanineCirculatingLeukocyteAtlas.csv")
colnames(ammonsk9_ln_atlas_top51)
##  [1] "Immature_B_cell"        "Naive_B_cell"           "CD8_gd_T_cell"         
##  [4] "Cycling_T_cell"         "CD34_Unclassified"      "Unclassified_DC"       
##  [7] "Pre_DC"                 "PMN_MDSC"               "Plasmacytoid_DC"       
## [10] "Plasma_cell"            "NKT_cell"               "DN_T_cell"             
## [13] "CD8_Naive"              "CD4_Naive"              "CD4_TCM"               
## [16] "CD4_Treg"               "CD4_IFN_signature"      "CD4_TEM"               
## [19] "CD4_TEM_Th1_like"       "CD4_TEM_Th17_like"      "CD4_TEM_Th2_like"      
## [22] "CD8_Memory"             "CD8_Effector"           "NK_cell"               
## [25] "gd_T_cell"              "Myeloid_c_DC2"          "Monocyte_CD4_neg"      
## [28] "Myeloid_c_DC2.1"        "Monocyte_IFN_signature" "Monocyte_CD4_pos"      
## [31] "M_MDSC"                 "Basophil"               "Neutrophil"            
## [34] "Eosinophil"             "Class_switched_B_cell"  "Activated_B_cell"
plot_list <- list() # initiate empty list for individual plots

for (column in colnames(ammonsk9_ln_atlas_top51)){
  genes <- list(ammonsk9_ln_atlas_top51[[column]])
  name <- paste(column, "Score", sep="_")
  all_Tcells <- AddModuleScore(all_Tcells, features = genes, name = name)
  newname <- paste(name, "1", sep="")
  modscoreplot <- FeaturePlot(all_Tcells, features = newname) + scale_color_gradientn(colours = brewer.pal(name = "RdPu", n=11))
  plot_list[[name]] <- modscoreplot # add plot to list
}

# split plot_list into groups of 6 and handle any remaining plots
plot_groups <- split(plot_list, ceiling(seq_along(plot_list) / 6))

# combined plot with dynamic number of columns/rows
combine_plots <- function(group, ncol = 3){
  n_plots <- length(group)
  nrow <- ceiling(n_plots / ncol)
  wrap_plots(group, ncol = ncol, nrow = nrow)
}
combined_plots <- lapply(plot_groups, function(group) {
  combine_plots(group, ncol = 3)
})

# display each combined plot
for (i in seq_along(combined_plots)) {
  print(combined_plots[[i]])
}

Citations

sessionInfo()
## R version 4.4.0 (2024-04-24 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 22631)
## 
## Matrix products: default
## 
## 
## locale:
## [1] LC_COLLATE=English_United States.utf8 
## [2] LC_CTYPE=English_United States.utf8   
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.utf8    
## 
## time zone: America/Denver
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] presto_1.0.0       Rcpp_1.0.14        knitr_1.49         data.table_1.16.4 
##  [5] RColorBrewer_1.1-3 pheatmap_1.0.12    patchwork_1.3.0    lubridate_1.9.4   
##  [9] forcats_1.0.0      stringr_1.5.1      dplyr_1.1.4        purrr_1.0.2       
## [13] readr_2.1.5        tidyr_1.3.1        tibble_3.2.1       ggplot2_3.5.1     
## [17] tidyverse_2.0.0    Seurat_5.2.1       SeuratObject_5.0.2 sp_2.1-4          
## 
## loaded via a namespace (and not attached):
##   [1] deldir_2.0-4           pbapply_1.7-2          gridExtra_2.3         
##   [4] rlang_1.1.3            magrittr_2.0.3         RcppAnnoy_0.0.22      
##   [7] spatstat.geom_3.3-5    matrixStats_1.5.0      ggridges_0.5.6        
##  [10] compiler_4.4.0         png_0.1-8              vctrs_0.6.5           
##  [13] reshape2_1.4.4         pkgconfig_2.0.3        fastmap_1.2.0         
##  [16] labeling_0.4.3         promises_1.3.2         rmarkdown_2.29        
##  [19] tzdb_0.4.0             xfun_0.49              cachem_1.1.0          
##  [22] jsonlite_1.8.9         goftest_1.2-3          later_1.4.1           
##  [25] spatstat.utils_3.1-2   irlba_2.3.5.1          parallel_4.4.0        
##  [28] cluster_2.1.6          R6_2.5.1               ica_1.0-3             
##  [31] bslib_0.8.0            stringi_1.8.4          spatstat.data_3.1-4   
##  [34] reticulate_1.40.0      parallelly_1.42.0      spatstat.univar_3.1-1 
##  [37] lmtest_0.9-40          jquerylib_0.1.4        scattermore_1.2       
##  [40] tensor_1.5             future.apply_1.11.3    zoo_1.8-12            
##  [43] sctransform_0.4.1      timechange_0.3.0       httpuv_1.6.15         
##  [46] Matrix_1.7-0           splines_4.4.0          igraph_2.1.4          
##  [49] tidyselect_1.2.1       abind_1.4-8            rstudioapi_0.17.1     
##  [52] yaml_2.3.10            spatstat.random_3.3-2  codetools_0.2-20      
##  [55] miniUI_0.1.1.1         spatstat.explore_3.3-4 listenv_0.9.1         
##  [58] lattice_0.22-6         plyr_1.8.9             withr_3.0.2           
##  [61] shiny_1.10.0           ROCR_1.0-11            evaluate_1.0.3        
##  [64] Rtsne_0.17             future_1.34.0          fastDummies_1.7.5     
##  [67] survival_3.5-8         polyclip_1.10-7        fitdistrplus_1.2-2    
##  [70] pillar_1.10.1          KernSmooth_2.23-22     plotly_4.10.4         
##  [73] generics_0.1.3         RcppHNSW_0.6.0         hms_1.1.3             
##  [76] munsell_0.5.1          scales_1.3.0           globals_0.16.3        
##  [79] xtable_1.8-4           glue_1.8.0             lazyeval_0.2.2        
##  [82] tools_4.4.0            RSpectra_0.16-2        RANN_2.6.2            
##  [85] dotCall64_1.2          cowplot_1.1.3          grid_4.4.0            
##  [88] colorspace_2.1-1       nlme_3.1-164           cli_3.6.2             
##  [91] spatstat.sparse_3.1-0  spam_2.11-1            viridisLite_0.4.2     
##  [94] uwot_0.2.2             gtable_0.3.6           sass_0.4.9            
##  [97] digest_0.6.35          progressr_0.15.1       ggrepel_0.9.6         
## [100] htmlwidgets_1.6.4      farver_2.1.2           htmltools_0.5.8.1     
## [103] lifecycle_1.0.4        httr_1.4.7             mime_0.12             
## [106] MASS_7.3-60.2
citation()
## To cite R in publications use:
## 
##   R Core Team (2024). _R: A Language and Environment for Statistical
##   Computing_. R Foundation for Statistical Computing, Vienna, Austria.
##   <https://www.R-project.org/>.
## 
## A BibTeX entry for LaTeX users is
## 
##   @Manual{,
##     title = {R: A Language and Environment for Statistical Computing},
##     author = {{R Core Team}},
##     organization = {R Foundation for Statistical Computing},
##     address = {Vienna, Austria},
##     year = {2024},
##     url = {https://www.R-project.org/},
##   }
## 
## We have invested a lot of time and effort in creating R, please cite it
## when using it for data analysis. See also 'citation("pkgname")' for
## citing R packages.