The Molecular Degree of Perturbation allows you to quantify the heterogeneity of transcriptome data samples. The mdp takes data containing at least two classes (control and test) and assigns a score to all samples based on how perturbed they are compared to the controls. Gene perturbation scores are calculated for each gene within each class. The algorithm is based on the Molecular Distance to Health which was first implemented in Pankla et al. 2009. It expands on this algorithm by adding the options to calculate the z-score using the modified z-score (using median absolute deviation), change the z-score zeroing threshold, and look at genes that are most perturbed in the test versus control classes.
Load expression and pheno data and run:
library(mdp)
data(example_data) # expression data has gene names in the rows
data(example_pheno) # pheno data needs a Sample and Class column
mdp.results <- mdp(data=example_data, pdata=example_pheno, control_lab = "baseline")
#> [1] "Calculating Z score"
#> [1] "Calculating gene scores"
#> [1] "Calculating sample scores"
#> [1] "printing"The sample scores can be accessed from the sample_scores element of the mdp results.
sample_scores_list <- mdp.results$sample_scores
sample_scores <- sample_scores_list[["perturbedgenes"]]# select sample scores calculated using the perturbed genes
head(sample_scores)
#> Sample Score Class
#> GSM429241 GSM429241 0.1053827 baseline
#> GSM429243 GSM429243 0.4366993 baseline
#> GSM429245 GSM429245 0.1171049 baseline
#> GSM429247 GSM429247 0.2003615 baseline
#> GSM429249 GSM429249 0.3008283 baseline
#> GSM429251 GSM429251 0.1389337 baseline
sample_plot(sample_scores,control_lab = "baseline", title="perturbed")The mdp works by calulating the z-score relative to the control samples, taking the absolute value of this matrix and setting all vlaues below a threshold (2 as a default) to 0. Expression values that are not 0 are perturbed. You can access this thresholded z-score matrix by,
zscore <- mdp.results$zscoreFor each gene in each class, a gene score is calculated, which is the average thresholded z-score value for that gene. A gene frequency is also calculated, which is the frequency that the gene is perturbed in a class.
gene_scores <- mdp.results$gene_scores
gene_freq <- mdp.results$gene_freq
head(gene_scores)
#> Symbol baseline Symptomatic Asymptomatic
#> HBA2 HBA2 0.0000000 0.4846994 0.0000000
#> HBA1 HBA1 0.1112191 0.2330308 0.0000000
#> ACTB ACTB 0.3158824 1.0790862 0.7333072
#> UBB UBB 0.0000000 0.0000000 0.0000000
#> HBB HBB 1.2688805 1.0924193 0.2398949
#> IFITM2 IFITM2 0.0000000 0.0000000 0.0000000The mdp ranks genes according to the difference between their gene score in the test versus the control samples. The fraction_genes option for the mdp function allows you to control what top fraction of these ranked genes will count as the perturbed_genes. You can obtain a list of the perturbed genes from the mdp results,
perturbed_genes <- mdp.results$perturbed_genesSample scores can also be calculated using genes that are within certain genesets. The mdp will accept genesets that are in the form of a list (see example below). You can read in a .gmt file of genesets using the fgsea::gmtPathways function from the fgsea package.
file_address <- system.file("extdata", "ReactomePathways.gmt", package = "mdp")
pathways <- fgsea::gmtPathways(file_address)
mdp.results <- mdp(data=example_data, pdata=example_pheno, control_lab = "baseline",pathways=pathways)For each pathway, the signal-to-noise ratio of the test versus control sample scores will be calculated. You can access these results in the pathways element of the mdp results.
head(mdp.results$pathways)
#> Geneset Sig2noise
#> 2 perturbedgenes 0.7836282
#> 7 Interferon alpha/beta signaling 0.7347052
#> 3 Antigen processing-Cross presentation 0.4685116
#> 8 Interleukin-6 signaling 0.4641631
#> 4 Apoptosis 0.3521704
#> 13 Transport of fatty acids 0.2611615
sample_scores <- mdp.results$sample_scores[["Interferon alpha/beta signaling"]]# select sample scores calculated using the perturbed genes
sample_plot(sample_scores,control_lab = "baseline", title="Interferon a/b")As a default, the mdp z-score normalises the expression data using the median as the averaging statistic. The standard deviation is estimated using the median absolute deviation mad function from the Stats package. If you would like to use the mean instead, select “mean”.
mdp.results <- mdp(data=example_data, pdata=example_pheno, control_lab = "baseline", measure = "mean")You can calculate the thresholded z-score using the compute_zscore function. A vector of control sample names must be provided.
control_samples <- example_pheno[example_pheno$Class == "baseline","Sample"]
zscore <- compute_zscore(data = example_data,control_samples = control_samples,measure = "mean",std = 2)