24 Regulon Activity Scoring

Each regulon identified in the GRN chapter is a TF paired with its positively and negatively regulated target genes. To make regulon activity usable for per-cell visualisation and differential testing, each regulon’s gene set is converted into a per-cell module score (AddModuleScore), separately for the positive and negative target sets, and stored as a new regulon assay on the Seurat object. Downstream, this assay is used both for per-cluster regulon-activity plots and as the input to pseudobulk differential expression between conditions.

24.1 Load GRN-annotated object

library(Pando)
library(dplyr)

regulons <- NetworkModules(grn_object)

24.2 Extract positive and negative regulon gene sets

positive_regulons_genes   <- regulons@features$genes_pos
positive_regulons_regions <- regulons@features$regions_pos
positive_regulons_peaks   <- regulons@features$peaks_pos

negative_regulons_genes   <- regulons@features$genes_neg
negative_regulons_regions <- regulons@features$regions_neg
negative_regulons_peaks   <- regulons@features$peaks_neg

24.3 Score regulon activity per cell

DefaultAssay(combined) <- "RNA"

mod_act_pos <- AddModuleScore(combined,
                              features = names(positive_regulons_genes),
                              name = "regulon_")@meta.data
mod_act_pos <- mod_act_pos[, grep("^regulon_", colnames(mod_act_pos))] %>%
  setNames(paste0(names(positive_regulons_genes), "(+)"))

mod_act_neg <- AddModuleScore(combined,
                              features = names(negative_regulons_genes),
                              name = "regulon_")@meta.data
mod_act_neg <- mod_act_neg[, grep("^regulon_", colnames(mod_act_neg))] %>%
  setNames(paste0(names(negative_regulons_genes), "(-)"))

combined@assays[['regulon']] <- CreateAssayObject(data = t(cbind(mod_act_pos, mod_act_neg)))

24.4 Regulon-to-target gene table

A long-format table linking each regulon to its target genes and regulation sign, for reference and export.

df_negative_regulation <- do.call(rbind, lapply(names(negative_regulons_genes), function(group) {
  data.frame(group = group, item = negative_regulons_genes[[group]], stringsAsFactors = FALSE)
}))
df_positive_regulation <- do.call(rbind, lapply(names(positive_regulons_genes), function(group) {
  data.frame(group = group, item = positive_regulons_genes[[group]], stringsAsFactors = FALSE)
}))

df_positive_regulation$name <- paste0(df_positive_regulation$group, "(+)")
df_negative_regulation$name <- paste0(df_negative_regulation$group, "(-)")
df_positive_regulation$regulation <- "positive"
df_negative_regulation$regulation <- "negative"

TF_regulation <- rbind(df_positive_regulation, df_negative_regulation)

write.table(TF_regulation, "data/TF_regulation.txt", row.names = FALSE)

24.5 Save regulon-scored object

SaveSeuratRds(combined, "data/seurat_object_cross_modal_integration_peakslinks_motifs_grn_regulons.rds")