1. load libraries
2. Load Seurat
Object
All_samples_Merged <- readRDS("../../../PHD_3rd_YEAR_Analysis/0-Seurat_RDS_OBJECT_FINAL/All_samples_Merged_with_Renamed_Clusters_Cell_state-03-12-2025.rds.rds")
pbmc <- All_samples_Merged
rm(All_samples_Merged)
gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 10768195 575.1 19539392 1043.6 13168465 703.3
Vcells 1236377650 9432.9 1535543907 11715.3 1236510487 9433.9
pbmc
An object of class Seurat
62900 features across 49305 samples within 6 assays
Active assay: RNA (36601 features, 0 variable features)
2 layers present: data, counts
5 other assays present: ADT, prediction.score.celltype.l1, prediction.score.celltype.l2, prediction.score.celltype.l3, SCT
5 dimensional reductions calculated: integrated_dr, ref.umap, pca, umap, harmony
3. The post-integration
(Pi) object
my.pbmc.pi <- CreatePostIntegrationObject(object = pbmc)
my.pbmc.pi
An object of class Pi
6 fields in the object: seurat.obj, exp.freq, markers, ds, cell.prop, parent.meta.data.
The following field has been processed:
seurat.obj: A Seurat object of 36601 features and 49305 cells.
6 assays: RNA, ADT, prediction.score.celltype.l1, prediction.score.celltype.l2, prediction.score.celltype.l3, SCT, and 5 reductions: integrated_dr, ref.umap, pca, umap, harmony
Metadata from the parent object provided? No
Subclusters integrated? No
4. run UMAP and check
clusters of all the cells in the object.
RunDimPlot(object = my.pbmc.pi)

4. run UMAP and check
Prediction of all the cells in the object.
RunDimPlot(object = my.pbmc.pi,
group.by = "cell_state", label = F)

run UMAP and check
Prediction of all the cells in the object.
RunDimPlot(object = my.pbmc.pi,
group.by = "Prediction",label = F)

run UMAP and check
Prediction of all the cells in the object.
RunDimPlot(object = my.pbmc.pi,
group.by = "predicted.celltype.l2",label = F)

5. Marker analysis and
matrix plot(Clusters)
filter_markers <- function(markers_df) {
blacklist_patterns <- c(
"^TRAV", "^TRBV", "^TRGV", "^TRDV", "^TRBC", "^TRAC", "^TRDC", "^TRGC", # TCR
"^IGH", "^IGK", "^IGL", "^IGJ", # Ig genes
"^RPL", "^RPS", # ribosomal
"^MT-", # mitochondria
"^HBA", "^HBB", "^HB[ABZ]", # hemoglobins
"^NEAT1$", "^MALAT1$", # optional lncRNAs
"^XIST$"
)
blacklist_regex <- paste(blacklist_patterns, collapse = "|")
markers_filtered <- markers_df %>%
filter(!grepl(blacklist_regex, gene, ignore.case = TRUE))
return(markers_filtered)
}
my.pbmc.pi <- RunFindAllMarkers(
my.pbmc.pi,
ident = "seurat_clusters",
logfc.threshold = 0.25,
min.pct = 0.25,
min.pct.diff = 0.2,
only.pos = TRUE,
return.thresh = 0.05
)
markers_clusters <- my.pbmc.pi$markers$`Markers|seurat_clusters|AllMarkers|test.use=wilcox`
# Extract the data frame
markers_clusters_df <- markers_clusters$data
markers_clusters_filtered <- filter_markers(markers_clusters_df)
my.pbmc.pi$markers$`Markers|seurat_clusters|AllMarkers|test.use=wilcox`$data <- markers_clusters_filtered
##. Matrix plot(Clusters)
p1 <- RunMatrixPlot(my.pbmc.pi,
markers.key = "Markers|seurat_clusters|AllMarkers|test.use=wilcox",
column.anno.name.rot = 45,
heatmap.height = 7)
Performing relative-counts-normalization
|
| | 0%
|
|===============================================================================| 100%
p1
library(ComplexHeatmap)
# --- Save as PNG ---
png(filename = "Top5_Markers_Heatmap.png", width = 3000, height = 1000, res = 300)
draw(p1)
dev.off()
png
2
# --- Save as PDF ---
pdf(file = "Top5_Markers_Heatmap.pdf", width = 30, height = 10) # width/height in inches
draw(p1)
dev.off()
png
2

message("✅ Heatmap saved successfully as both PNG and PDF.")
6. Marker analysis and
matrix plot (Predictions)
my.pbmc.pi <- RunFindAllMarkers(
my.pbmc.pi,
ident = "cell_state",
logfc.threshold = 0.25,
min.pct = 0.25,
min.pct.diff = 0.2,
only.pos = TRUE,
return.thresh = 0.05
)
markers_clusters <- my.pbmc.pi$markers$`Markers|renamed_clusters|AllMarkers|test.use=wilcox`
# Extract the data frame
markers_clusters_df <- markers_clusters$data
markers_clusters_filtered <- filter_markers(markers_clusters_df)
Error in UseMethod("filter") :
no applicable method for 'filter' applied to an object of class "NULL"
##. Matrix plot (Predictions)
p2 <- RunMatrixPlot(my.pbmc.pi,
markers.key = "Markers|cell_state|AllMarkers|test.use=wilcox",
column.anno.name.rot = 90,
heatmap.height = 9)
Performing relative-counts-normalization
|
| | 0%
|
|===============================================================================| 100%
p2
library(ComplexHeatmap)
# --- Save as PNG ---
png(filename = "Top5_Markers_Heatmap_p2_cell_state.png", width = 5000, height = 3000, res = 300)
draw(p2)
dev.off()
png
2
# --- Save as PDF ---
pdf(file = "Top5_Markers_Heatmap_p2_cell_state.pdf", width = 50, height = 30) # width/height in inches
draw(p2)
dev.off()
png
2

message("✅ Heatmap saved successfully as both PNG and PDF.")
LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpemF0aW9uIChSYWdhcyktY2VsbF9zdGF0ZV92aXN1YWxpemF0aW9uIgphdXRob3I6ICJOYXNpciBNYWhtb29kIEFiYmFzaSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogdHJ1ZQogICAgdGhlbWU6IGpvdXJuYWwKLS0tCgoKIyAxLiBsb2FkIGxpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoU2V1cmF0V3JhcHBlcnMpCmxpYnJhcnkobW9ub2NsZTMpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShTQ3B1YnIpCgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KE1hdHJpeCkKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KHBhdGNod29yaykKCmxpYnJhcnkoU2V1cmF0RXh0ZW5kKQpsaWJyYXJ5KFNldXJhdEV4dGVuZERhdGEpCmxpYnJhcnkoUmFnYXMpCgpgYGAKCiMgMi4gTG9hZCBTZXVyYXQgT2JqZWN0IApgYGB7cn0KCkFsbF9zYW1wbGVzX01lcmdlZCA8LSByZWFkUkRTKCIuLi8uLi8uLi9QSERfM3JkX1lFQVJfQW5hbHlzaXMvMC1TZXVyYXRfUkRTX09CSkVDVF9GSU5BTC9BbGxfc2FtcGxlc19NZXJnZWRfd2l0aF9SZW5hbWVkX0NsdXN0ZXJzX0NlbGxfc3RhdGUtMDMtMTItMjAyNS5yZHMucmRzIikKCnBibWMgPC0gQWxsX3NhbXBsZXNfTWVyZ2VkCgpybShBbGxfc2FtcGxlc19NZXJnZWQpCgpnYygpCgpwYm1jCmBgYAoKIyAzLiBUaGUgcG9zdC1pbnRlZ3JhdGlvbiAoUGkpIG9iamVjdApgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KbXkucGJtYy5waSA8LSBDcmVhdGVQb3N0SW50ZWdyYXRpb25PYmplY3Qob2JqZWN0ID0gcGJtYykKCm15LnBibWMucGkKYGBgCgoKCiMgNC4gcnVuIFVNQVAgYW5kIGNoZWNrIGNsdXN0ZXJzIG9mIGFsbCB0aGUgY2VsbHMgaW4gdGhlIG9iamVjdC4KYGBge3IsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9ClJ1bkRpbVBsb3Qob2JqZWN0ID0gbXkucGJtYy5waSkKYGBgCgoKCgoKIyA0LiBydW4gVU1BUCBhbmQgY2hlY2sgUHJlZGljdGlvbiBvZiBhbGwgdGhlIGNlbGxzIGluIHRoZSBvYmplY3QuCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMn0KUnVuRGltUGxvdChvYmplY3QgPSBteS5wYm1jLnBpLAogICAgICAgICAgIGdyb3VwLmJ5ID0gImNlbGxfc3RhdGUiLCBsYWJlbCA9IEYpCmBgYAoKIyMgcnVuIFVNQVAgYW5kIGNoZWNrIFByZWRpY3Rpb24gb2YgYWxsIHRoZSBjZWxscyBpbiB0aGUgb2JqZWN0LgpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9ClJ1bkRpbVBsb3Qob2JqZWN0ID0gbXkucGJtYy5waSwKICAgICAgICAgICBncm91cC5ieSA9ICJQcmVkaWN0aW9uIixsYWJlbCA9IEYpCmBgYAoKIyMgcnVuIFVNQVAgYW5kIGNoZWNrIFByZWRpY3Rpb24gb2YgYWxsIHRoZSBjZWxscyBpbiB0aGUgb2JqZWN0LgpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9ClJ1bkRpbVBsb3Qob2JqZWN0ID0gbXkucGJtYy5waSwKICAgICAgICAgICBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLGxhYmVsID0gRikKYGBgCgoKIyA1LiBNYXJrZXIgYW5hbHlzaXMgYW5kIG1hdHJpeCBwbG90KENsdXN0ZXJzKQpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KCmZpbHRlcl9tYXJrZXJzIDwtIGZ1bmN0aW9uKG1hcmtlcnNfZGYpIHsKICBibGFja2xpc3RfcGF0dGVybnMgPC0gYygKICAgICJeVFJBViIsICJeVFJCViIsICJeVFJHViIsICJeVFJEViIsICJeVFJCQyIsICJeVFJBQyIsICJeVFJEQyIsICJeVFJHQyIsICMgVENSCiAgICAiXklHSCIsICJeSUdLIiwgIl5JR0wiLCAiXklHSiIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIElnIGdlbmVzCiAgICAiXlJQTCIsICJeUlBTIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHJpYm9zb21hbAogICAgIl5NVC0iLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtaXRvY2hvbmRyaWEKICAgICJeSEJBIiwgIl5IQkIiLCAiXkhCW0FCWl0iLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaGVtb2dsb2JpbnMKICAgICJeTkVBVDEkIiwgIl5NQUxBVDEkIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgb3B0aW9uYWwgbG5jUk5BcwogICAgIl5YSVNUJCIKICApCiAgYmxhY2tsaXN0X3JlZ2V4IDwtIHBhc3RlKGJsYWNrbGlzdF9wYXR0ZXJucywgY29sbGFwc2UgPSAifCIpCiAgCiAgbWFya2Vyc19maWx0ZXJlZCA8LSBtYXJrZXJzX2RmICU+JQogICAgZmlsdGVyKCFncmVwbChibGFja2xpc3RfcmVnZXgsIGdlbmUsIGlnbm9yZS5jYXNlID0gVFJVRSkpCiAgCiAgcmV0dXJuKG1hcmtlcnNfZmlsdGVyZWQpCn0KCgoKbXkucGJtYy5waSA8LSBSdW5GaW5kQWxsTWFya2VycygKICBteS5wYm1jLnBpLAogIGlkZW50ID0gInNldXJhdF9jbHVzdGVycyIsCiAgbG9nZmMudGhyZXNob2xkID0gMC4yNSwKICBtaW4ucGN0ID0gMC4yNSwKICBtaW4ucGN0LmRpZmYgPSAwLjIsCiAgb25seS5wb3MgPSBUUlVFLAogIHJldHVybi50aHJlc2ggPSAwLjA1CikKCgptYXJrZXJzX2NsdXN0ZXJzIDwtIG15LnBibWMucGkkbWFya2VycyRgTWFya2Vyc3xzZXVyYXRfY2x1c3RlcnN8QWxsTWFya2Vyc3x0ZXN0LnVzZT13aWxjb3hgCgojIEV4dHJhY3QgdGhlIGRhdGEgZnJhbWUKbWFya2Vyc19jbHVzdGVyc19kZiA8LSBtYXJrZXJzX2NsdXN0ZXJzJGRhdGEKCgoKbWFya2Vyc19jbHVzdGVyc19maWx0ZXJlZCA8LSBmaWx0ZXJfbWFya2VycyhtYXJrZXJzX2NsdXN0ZXJzX2RmKQoKCm15LnBibWMucGkkbWFya2VycyRgTWFya2Vyc3xzZXVyYXRfY2x1c3RlcnN8QWxsTWFya2Vyc3x0ZXN0LnVzZT13aWxjb3hgJGRhdGEgPC0gbWFya2Vyc19jbHVzdGVyc19maWx0ZXJlZAoKYGBgCgoKIyMuIE1hdHJpeCBwbG90KENsdXN0ZXJzKQpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CnAxIDwtIFJ1bk1hdHJpeFBsb3QobXkucGJtYy5waSwKICAgICAgICAgICAgICBtYXJrZXJzLmtleSA9ICJNYXJrZXJzfHNldXJhdF9jbHVzdGVyc3xBbGxNYXJrZXJzfHRlc3QudXNlPXdpbGNveCIsIAogICAgICAgICAgICAgIGNvbHVtbi5hbm5vLm5hbWUucm90ID0gNDUsIAogICAgICAgICAgICAgIGhlYXRtYXAuaGVpZ2h0ID0gNykKCnAxCgpsaWJyYXJ5KENvbXBsZXhIZWF0bWFwKQoKIyAtLS0gU2F2ZSBhcyBQTkcgLS0tCnBuZyhmaWxlbmFtZSA9ICJUb3A1X01hcmtlcnNfSGVhdG1hcC5wbmciLCB3aWR0aCA9IDMwMDAsIGhlaWdodCA9IDEwMDAsIHJlcyA9IDMwMCkKZHJhdyhwMSkKZGV2Lm9mZigpCgojIC0tLSBTYXZlIGFzIFBERiAtLS0KcGRmKGZpbGUgPSAiVG9wNV9NYXJrZXJzX0hlYXRtYXAucGRmIiwgd2lkdGggPSAzMCwgaGVpZ2h0ID0gMTApICAjIHdpZHRoL2hlaWdodCBpbiBpbmNoZXMKZHJhdyhwMSkKZGV2Lm9mZigpCgptZXNzYWdlKCLinIUgSGVhdG1hcCBzYXZlZCBzdWNjZXNzZnVsbHkgYXMgYm90aCBQTkcgYW5kIFBERi4iKQoKYGBgCgoKCgoKCiMgNi4gTWFya2VyIGFuYWx5c2lzIGFuZCBtYXRyaXggcGxvdCAoUHJlZGljdGlvbnMpCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCm15LnBibWMucGkgPC0gUnVuRmluZEFsbE1hcmtlcnMoCiAgbXkucGJtYy5waSwKICBpZGVudCA9ICJjZWxsX3N0YXRlIiwKICBsb2dmYy50aHJlc2hvbGQgPSAwLjI1LAogIG1pbi5wY3QgPSAwLjI1LAogIG1pbi5wY3QuZGlmZiA9IDAuMiwKICBvbmx5LnBvcyA9IFRSVUUsCiAgcmV0dXJuLnRocmVzaCA9IDAuMDUKKQoKCm1hcmtlcnNfY2x1c3RlcnMgPC0gbXkucGJtYy5waSRtYXJrZXJzJGBNYXJrZXJzfHJlbmFtZWRfY2x1c3RlcnN8QWxsTWFya2Vyc3x0ZXN0LnVzZT13aWxjb3hgCgojIEV4dHJhY3QgdGhlIGRhdGEgZnJhbWUKbWFya2Vyc19jbHVzdGVyc19kZiA8LSBtYXJrZXJzX2NsdXN0ZXJzJGRhdGEKCgoKbWFya2Vyc19jbHVzdGVyc19maWx0ZXJlZCA8LSBmaWx0ZXJfbWFya2VycyhtYXJrZXJzX2NsdXN0ZXJzX2RmKQoKCm15LnBibWMucGkkbWFya2VycyRgTWFya2Vyc3xyZW5hbWVkX2NsdXN0ZXJzfEFsbE1hcmtlcnN8dGVzdC51c2U9d2lsY294YCRkYXRhIDwtIG1hcmtlcnNfY2x1c3RlcnNfZmlsdGVyZWQKCmBgYAoKCiMjLiBNYXRyaXggcGxvdCAoUHJlZGljdGlvbnMpCmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTR9CnAyIDwtIFJ1bk1hdHJpeFBsb3QobXkucGJtYy5waSwKICAgICAgICAgICAgICBtYXJrZXJzLmtleSA9ICJNYXJrZXJzfGNlbGxfc3RhdGV8QWxsTWFya2Vyc3x0ZXN0LnVzZT13aWxjb3giLCAKICAgICAgICAgICAgICBjb2x1bW4uYW5uby5uYW1lLnJvdCA9IDkwLCAKICAgICAgICAgICAgICBoZWF0bWFwLmhlaWdodCA9IDkpCgpwMgoKCmxpYnJhcnkoQ29tcGxleEhlYXRtYXApCgojIC0tLSBTYXZlIGFzIFBORyAtLS0KcG5nKGZpbGVuYW1lID0gIlRvcDVfTWFya2Vyc19IZWF0bWFwX3AyX2NlbGxfc3RhdGUucG5nIiwgd2lkdGggPSA1MDAwLCBoZWlnaHQgPSAzMDAwLCByZXMgPSAzMDApCmRyYXcocDIpCmRldi5vZmYoKQoKIyAtLS0gU2F2ZSBhcyBQREYgLS0tCnBkZihmaWxlID0gIlRvcDVfTWFya2Vyc19IZWF0bWFwX3AyX2NlbGxfc3RhdGUucGRmIiwgd2lkdGggPSA1MCwgaGVpZ2h0ID0gMzApICAjIHdpZHRoL2hlaWdodCBpbiBpbmNoZXMKZHJhdyhwMikKZGV2Lm9mZigpCgptZXNzYWdlKCLinIUgSGVhdG1hcCBzYXZlZCBzdWNjZXNzZnVsbHkgYXMgYm90aCBQTkcgYW5kIFBERi4iKQoKYGBgCg==