MetaboDynamics 1.1.7
The MetaboDynamics vignette explains the package workflow and interpretation of results with a SummarizedExperiment object as input. In this vignette I will show the usage of MetaboDynamics with a data frame as input.
library(MetaboDynamics)
library(SummarizedExperiment) # storing and manipulating simulated metabolomics data
library(ggplot2) # visualization
library(dplyr) # data handling
library(tidyr) # data handling
The MetaboDynamics package also includes a simulated example data set in a data frame format. To load the data set in data frame format, execute the following code:
data("longitudinalMetabolomics_df", package = "MetaboDynamics")
To keep run time of this vignette short we will execute the workflow on a subset of five metabolites across all conditions.
data("longitudinalMetabolomics_df")
# take a sample (of five metabolites and subset data
samples <- c(
"UMP", "PEP",
"2-Aminomuconate","ATP"
)
data <- longitudinalMetabolomics_df %>% filter(metabolite %in% samples)
head(data)
## # A tibble: 6 × 8
## # Groups: metabolite, condition [1]
## metabolite condition time replicate measurement log_m m_scaled KEGG
## <chr> <chr> <int> <int> <dbl> <dbl> <dbl> <chr>
## 1 PEP A 1 1 459223. 5.66 1.66 C00074
## 2 PEP A 1 2 63932. 4.81 -0.207 C00074
## 3 PEP A 1 3 34766. 4.54 -0.783 C00074
## 4 PEP A 2 1 9522. 3.98 -2.01 C00074
## 5 PEP A 2 2 70377. 4.85 -0.116 C00074
## 6 PEP A 2 3 46996. 4.67 -0.498 C00074
The measured metabolites are stored in column “metabolite”, time points are specified in column “time”, and column “condition” specifies the experimental condition.
The required log-transformed and scaled (per metabolite and condition to a mean of 0 and sd of 1) metabolite abundances are stored in column “m_scaled”. The function fit_dynamics_model() allows to specify other column names for metabolite, time points, condition and scaled measurement.
First we will fit the dynamics model and extract the diagnostics:
# fit dynamics model
fit <- # when using a data frame as input fits have to stored in a separate object
fit_dynamics_model(
model = "scaled_log",
data = data,
scaled_measurement = "m_scaled", # in which column are scaled measurments stored?
max_treedepth = 10,
adapt_delta = 0.99, # default 0.95
iter = 2000,
warmup = 2000 / 4, # default is 1/4 of iterations
chains = 1, # only set to 1 in vignette, recommended default is 4!
cores = 1 # only set to 1 in vignette, can be same as chains if machine allows for parallelization
)
## Are your metabolite concentrations normalized and standardized?
## We recommend normalization by log-transformation.
## Scaling and centering (mean=0, sd=1) should be metabolite and condition specific.
##
## SAMPLING FOR MODEL 'm_ANOVA_partial_pooling_euclidean_distance' NOW (CHAIN 1).
## Chain 1:
## Chain 1: Gradient evaluation took 6.6e-05 seconds
## Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.66 seconds.
## Chain 1: Adjust your expectations accordingly!
## Chain 1:
## Chain 1:
## Chain 1: Iteration: 1 / 2000 [ 0%] (Warmup)
## Chain 1: Iteration: 200 / 2000 [ 10%] (Warmup)
## Chain 1: Iteration: 400 / 2000 [ 20%] (Warmup)
## Chain 1: Iteration: 501 / 2000 [ 25%] (Sampling)
## Chain 1: Iteration: 700 / 2000 [ 35%] (Sampling)
## Chain 1: Iteration: 900 / 2000 [ 45%] (Sampling)
## Chain 1: Iteration: 1100 / 2000 [ 55%] (Sampling)
## Chain 1: Iteration: 1300 / 2000 [ 65%] (Sampling)
## Chain 1: Iteration: 1500 / 2000 [ 75%] (Sampling)
## Chain 1: Iteration: 1700 / 2000 [ 85%] (Sampling)
## Chain 1: Iteration: 1900 / 2000 [ 95%] (Sampling)
## Chain 1: Iteration: 2000 / 2000 [100%] (Sampling)
## Chain 1:
## Chain 1: Elapsed Time: 1.189 seconds (Warm-up)
## Chain 1: 2.893 seconds (Sampling)
## Chain 1: 4.082 seconds (Total)
## Chain 1:
## Warning: Tail Effective Samples Size (ESS) is too low, indicating posterior variances and tail quantiles may be unreliable.
## Running the chains for more iterations may help. See
## https://mc-stan.org/misc/warnings.html#tail-ess
This returns a model fit.
# Extract diagnostics
diagnostics <- # when using a data frame as input diagnostics have to be stored in a separate object
diagnostics_dynamics(
data = data, # data frame that was used to fit the dynamics model,
fit = fit, # list of fits from dynamics model, result of fit_dynamics_mode function
iter = 2000, # how many iterations were used to fit the dynamics model
chains = 1, # how many chains were used to fit the dynamics model
)
That returns a list with elements [[“model_diagnostics”]] which holds a summary of the model diagnostics and the extracted posterior estimates. [["posterior]] holds the posterior predictions needed for the posterior predictive check (PPC)
To visualize the diagnostics and the PPC the following code can be used:
plot_diagnostics(
data = data, # data frame used to fit the dynamics model
diagnostics = diagnostics[["model_diagnostics"]] # summary of diagnostics
)
## $divergences
##
## $max_treedepth
##
## $Rhat
##
## $n_eff
plot_PPC(
data = data, posterior = diagnostics[["posterior"]],
scaled_measurement = "m_scaled"
)
## Warning: Removed 2156 rows containing non-finite outside the scale range
## (`stat_ydensity()`).
In this case the diagnostics are all indicating a sane model fit: The model fitting did not result in
divergent transitions, the maximum tree depth was not exceeded, Rhat values were
below 1.01 and number of effective samples exceeded 100.
To extract the estimates one has to specify again the data, list of fits and number of iterations and chains used to fit the model. Additionally is is possible to specify the columns in which metabolite names, experimental conditions and time points are stored. This is equivalent to the fit_dynamics_model function.
Additionally one can specify how many samples should be drawn from the posterior to for example test clustering performance.
estimates <- # estimates have to be stored in a separate object when using data frames
estimates_dynamics(
data = data,
fit = fit)
This returns a list containing the estimates for every experimental condition. The estimates can be visualized in two ways by the following code:
# only visualize differences between time points
plot_estimates(
# does not need data as input
estimates = estimates,
delta_t = TRUE, # choose to visualize differences between time points
dynamics = FALSE,
distance_conditions = FALSE
)
## $delta_t
## $delta_t$`A_2-1`
##
## $delta_t$`A_3-1`
##
## $delta_t$`A_4-1`
##
## $delta_t$`A_4-3`
##
## $delta_t$`A_4-2`
##
## $delta_t$`A_3-2`
##
## $delta_t$`B_4-2`
##
## $delta_t$`B_4-1`
##
## $delta_t$`B_3-1`
##
## $delta_t$`B_4-3`
##
## $delta_t$`B_3-2`
##
## $delta_t$`B_2-1`
# only visualize dynamics
plot_estimates(
estimates = estimates,
delta_t = FALSE,
distance_conditions = FALSE,
dynamics = TRUE
) # choose to visualize the dynamics
## $dynamcis
# only visualize euclidean distance between dynamics vectors
# only visualize dynamics
plot_estimates(
estimates = estimates,
delta_t = FALSE,
distance_conditions = TRUE,
dynamics = FALSE
) # choose to visualize the dynamics
## $distance_conditions
## $distance_conditions$A_B
## `height` was translated to `width`.
To cluster the dynamics we need either the estimates from the dynamics model (stored in object “estimates”) or a data frame in which the means of measurements are stored in a column named “mu_mean”, categorical time points are stored in ascending order in column “time.ID” and experimental conditions in a column named “condition”.
The following chunk of code shows the needed data frame format for the clustering function:
head(estimates)
## $mu
## metabolite time condition parameter mean 2.5%
## mu[1,1,1] PEP 1 A mu 0.99009667 -0.03338333
## mu[1,1,2] PEP 1 B mu 0.70833281 -0.97771332
## mu[1,2,1] PEP 2 A mu -0.49309670 -1.37517778
## mu[1,2,2] PEP 2 B mu -0.09052507 -1.11744478
## mu[1,3,1] PEP 3 A mu -0.30448409 -1.26813077
## mu[1,3,2] PEP 3 B mu -0.22919138 -1.07579937
## mu[1,4,1] PEP 4 A mu -0.14426922 -1.88314461
## mu[1,4,2] PEP 4 B mu -0.36393909 -2.16623165
## mu[2,1,1] UMP 1 A mu 0.23169358 -1.00391221
## mu[2,1,2] UMP 1 B mu 0.27419367 -0.55542551
## mu[2,2,1] UMP 2 A mu -0.21445970 -0.98213138
## mu[2,2,2] UMP 2 B mu 0.81075905 -0.65269145
## mu[2,3,1] UMP 3 A mu 0.53138877 -0.47209952
## mu[2,3,2] UMP 3 B mu -0.08241471 -0.95035265
## mu[2,4,1] UMP 4 A mu -0.40682043 -2.44344699
## mu[2,4,2] UMP 4 B mu -0.99018373 -2.38941942
## mu[3,1,1] ATP 1 A mu 0.20561736 -1.50745576
## mu[3,1,2] ATP 1 B mu 0.04186331 -1.02968715
## mu[3,2,1] ATP 2 A mu -0.75407858 -2.32569016
## mu[3,2,2] ATP 2 B mu -0.39841838 -2.20791116
## mu[3,3,1] ATP 3 A mu 0.16981843 -1.43047355
## mu[3,3,2] ATP 3 B mu 0.08048724 -1.82886404
## mu[3,4,1] ATP 4 A mu 0.45320576 -0.53202813
## mu[3,4,2] ATP 4 B mu 0.37389284 -0.57393448
## mu[4,1,1] 2-Aminomuconate 1 A mu 0.62667279 -1.25489800
## mu[4,1,2] 2-Aminomuconate 1 B mu -0.76181039 -1.40400821
## mu[4,2,1] 2-Aminomuconate 2 A mu -0.84627374 -1.92706415
## mu[4,2,2] 2-Aminomuconate 2 B mu 0.70911495 -1.38313782
## mu[4,3,1] 2-Aminomuconate 3 A mu 0.35803029 0.01679223
## mu[4,3,2] 2-Aminomuconate 3 B mu -0.07830068 -0.59395436
## mu[4,4,1] 2-Aminomuconate 4 A mu -0.06466956 -1.20529273
## mu[4,4,2] 2-Aminomuconate 4 B mu -0.06723204 -0.58176489
## 97.5%
## mu[1,1,1] 1.95293403
## mu[1,1,2] 2.42571636
## mu[1,2,1] 0.41430577
## mu[1,2,2] 1.13352581
## mu[1,3,1] 0.83133453
## mu[1,3,2] 0.42164607
## mu[1,4,1] 1.92037727
## mu[1,4,2] 1.52481206
## mu[2,1,1] 1.42257888
## mu[2,1,2] 1.03994082
## mu[2,2,1] 0.85246053
## mu[2,2,2] 2.01598113
## mu[2,3,1] 1.55352182
## mu[2,3,2] 0.78846815
## mu[2,4,1] 1.87535248
## mu[2,4,2] 0.57529201
## mu[3,1,1] 1.95544330
## mu[3,1,2] 1.06277726
## mu[3,2,1] 0.89817339
## mu[3,2,2] 1.49577603
## mu[3,3,1] 1.85967027
## mu[3,3,2] 1.82910362
## mu[3,4,1] 1.45372335
## mu[3,4,2] 1.35203164
## mu[4,1,1] 2.36123950
## mu[4,1,2] 0.04863224
## mu[4,2,1] 0.49815879
## mu[4,2,2] 2.58704143
## mu[4,3,1] 0.94715079
## mu[4,3,2] 0.24713287
## mu[4,4,1] 1.25785777
## mu[4,4,2] 0.43257229
##
## $sigma
## metabolite time condition parameter mean 2.5%
## sigma[1,1,1] PEP 1 A sigma 0.8070124 0.28308291
## sigma[1,1,2] PEP 1 B sigma 1.5437245 0.66816567
## sigma[1,2,1] PEP 2 A sigma 0.6078980 0.18180906
## sigma[1,2,2] PEP 2 B sigma 0.8974251 0.31119602
## sigma[1,3,1] PEP 3 A sigma 0.7484721 0.23798573
## sigma[1,3,2] PEP 3 B sigma 0.5626159 0.16052866
## sigma[1,4,1] PEP 4 A sigma 1.8449063 0.79503713
## sigma[1,4,2] PEP 4 B sigma 1.7382627 0.77199746
## sigma[2,1,1] UMP 1 A sigma 1.0323267 0.36822888
## sigma[2,1,2] UMP 1 B sigma 0.6641572 0.23355735
## sigma[2,2,1] UMP 2 A sigma 0.6427721 0.20206880
## sigma[2,2,2] UMP 2 B sigma 1.1392360 0.45091627
## sigma[2,3,1] UMP 3 A sigma 0.7450329 0.24264158
## sigma[2,3,2] UMP 3 B sigma 0.5939405 0.17012878
## sigma[2,4,1] UMP 4 A sigma 2.0349291 0.92233356
## sigma[2,4,2] UMP 4 B sigma 1.3331624 0.55760902
## sigma[3,1,1] ATP 1 A sigma 1.6125518 0.65476234
## sigma[3,1,2] ATP 1 B sigma 0.8514598 0.29303899
## sigma[3,2,1] ATP 2 A sigma 1.3715825 0.51989876
## sigma[3,2,2] ATP 2 B sigma 1.7948599 0.78858589
## sigma[3,3,1] ATP 3 A sigma 1.4533624 0.58637284
## sigma[3,3,2] ATP 3 B sigma 1.7883781 0.73235683
## sigma[3,4,1] ATP 4 A sigma 0.6715807 0.17499100
## sigma[3,4,2] ATP 4 B sigma 0.7173768 0.22413147
## sigma[4,1,1] 2-Aminomuconate 1 A sigma 1.7317967 0.76183592
## sigma[4,1,2] 2-Aminomuconate 1 B sigma 0.5070940 0.16337492
## sigma[4,2,1] 2-Aminomuconate 2 A sigma 0.9297348 0.33906176
## sigma[4,2,2] 2-Aminomuconate 2 B sigma 1.8245812 0.86942258
## sigma[4,3,1] 2-Aminomuconate 3 A sigma 0.2731804 0.05629313
## sigma[4,3,2] 2-Aminomuconate 3 B sigma 0.2480887 0.06158296
## sigma[4,4,1] 2-Aminomuconate 4 A sigma 1.0912904 0.39894210
## sigma[4,4,2] 2-Aminomuconate 4 B sigma 0.4221063 0.12677388
## 97.5%
## sigma[1,1,1] 2.2113224
## sigma[1,1,2] 3.4956700
## sigma[1,2,1] 1.8742706
## sigma[1,2,2] 2.6399296
## sigma[1,3,1] 2.2536308
## sigma[1,3,2] 1.8013884
## sigma[1,4,1] 4.2700785
## sigma[1,4,2] 4.0186862
## sigma[2,1,1] 2.8842857
## sigma[2,1,2] 1.8304160
## sigma[2,2,1] 2.0817808
## sigma[2,2,2] 2.6880880
## sigma[2,3,1] 2.2481879
## sigma[2,3,2] 1.9876424
## sigma[2,4,1] 4.4007287
## sigma[2,4,2] 3.1370003
## sigma[3,1,1] 4.2108238
## sigma[3,1,2] 2.4744355
## sigma[3,2,1] 3.3510240
## sigma[3,2,2] 4.2136549
## sigma[3,3,1] 3.7466727
## sigma[3,3,2] 3.9541708
## sigma[3,4,1] 2.2805030
## sigma[3,4,2] 2.1151344
## sigma[4,1,1] 3.9727159
## sigma[4,1,2] 1.5519083
## sigma[4,2,1] 2.6548205
## sigma[4,2,2] 4.1071591
## sigma[4,3,1] 1.0883248
## sigma[4,3,2] 0.9586288
## sigma[4,4,1] 2.9096801
## sigma[4,4,2] 1.3010807
##
## $lambda
## metabolite condition parameter mean 2.5% 97.5%
## lambda[1,1] PEP A lambda 0.8623909 0.2590959 1.999619
## lambda[1,2] PEP B lambda 0.7763662 0.2522274 1.781064
## lambda[2,1] UMP A lambda 0.8165463 0.2570569 1.739908
## lambda[2,2] UMP B lambda 0.9121827 0.2866137 1.985118
## lambda[3,1] ATP A lambda 0.7375798 0.2043557 1.581576
## lambda[3,2] ATP B lambda 0.7284867 0.2111588 1.568833
## lambda[4,1] 2-Aminomuconate A lambda 0.8636440 0.2411239 1.925152
## lambda[4,2] 2-Aminomuconate B lambda 1.0333131 0.3073939 2.180532
##
## $delta_mu
## metabolite condition timepoint_1 timepoint_2 parameter
## delta_mu[1,1,1,2] PEP A 1 2 delta_mu
## delta_mu[1,1,1,3] PEP A 1 3 delta_mu
## delta_mu[1,1,1,4] PEP A 1 4 delta_mu
## delta_mu[1,1,2,3] PEP A 2 3 delta_mu
## delta_mu[1,1,2,4] PEP A 2 4 delta_mu
## delta_mu[1,1,3,4] PEP A 3 4 delta_mu
## delta_mu[1,2,1,2] PEP B 1 2 delta_mu
## delta_mu[1,2,1,3] PEP B 1 3 delta_mu
## delta_mu[1,2,1,4] PEP B 1 4 delta_mu
## delta_mu[1,2,2,3] PEP B 2 3 delta_mu
## delta_mu[1,2,2,4] PEP B 2 4 delta_mu
## delta_mu[1,2,3,4] PEP B 3 4 delta_mu
## delta_mu[2,1,1,2] UMP A 1 2 delta_mu
## delta_mu[2,1,1,3] UMP A 1 3 delta_mu
## delta_mu[2,1,1,4] UMP A 1 4 delta_mu
## delta_mu[2,1,2,3] UMP A 2 3 delta_mu
## delta_mu[2,1,2,4] UMP A 2 4 delta_mu
## delta_mu[2,1,3,4] UMP A 3 4 delta_mu
## delta_mu[2,2,1,2] UMP B 1 2 delta_mu
## delta_mu[2,2,1,3] UMP B 1 3 delta_mu
## delta_mu[2,2,1,4] UMP B 1 4 delta_mu
## delta_mu[2,2,2,3] UMP B 2 3 delta_mu
## delta_mu[2,2,2,4] UMP B 2 4 delta_mu
## delta_mu[2,2,3,4] UMP B 3 4 delta_mu
## delta_mu[3,1,1,2] ATP A 1 2 delta_mu
## delta_mu[3,1,1,3] ATP A 1 3 delta_mu
## delta_mu[3,1,1,4] ATP A 1 4 delta_mu
## delta_mu[3,1,2,3] ATP A 2 3 delta_mu
## delta_mu[3,1,2,4] ATP A 2 4 delta_mu
## delta_mu[3,1,3,4] ATP A 3 4 delta_mu
## delta_mu[3,2,1,2] ATP B 1 2 delta_mu
## delta_mu[3,2,1,3] ATP B 1 3 delta_mu
## delta_mu[3,2,1,4] ATP B 1 4 delta_mu
## delta_mu[3,2,2,3] ATP B 2 3 delta_mu
## delta_mu[3,2,2,4] ATP B 2 4 delta_mu
## delta_mu[3,2,3,4] ATP B 3 4 delta_mu
## delta_mu[4,1,1,2] 2-Aminomuconate A 1 2 delta_mu
## delta_mu[4,1,1,3] 2-Aminomuconate A 1 3 delta_mu
## delta_mu[4,1,1,4] 2-Aminomuconate A 1 4 delta_mu
## delta_mu[4,1,2,3] 2-Aminomuconate A 2 3 delta_mu
## delta_mu[4,1,2,4] 2-Aminomuconate A 2 4 delta_mu
## delta_mu[4,1,3,4] 2-Aminomuconate A 3 4 delta_mu
## delta_mu[4,2,1,2] 2-Aminomuconate B 1 2 delta_mu
## delta_mu[4,2,1,3] 2-Aminomuconate B 1 3 delta_mu
## delta_mu[4,2,1,4] 2-Aminomuconate B 1 4 delta_mu
## delta_mu[4,2,2,3] 2-Aminomuconate B 2 3 delta_mu
## delta_mu[4,2,2,4] 2-Aminomuconate B 2 4 delta_mu
## delta_mu[4,2,3,4] 2-Aminomuconate B 3 4 delta_mu
## mean 2.5% 97.5%
## delta_mu[1,1,1,2] -1.48319337 -2.8001065 -0.03559863
## delta_mu[1,1,1,3] -1.29458075 -2.6408441 0.37985141
## delta_mu[1,1,1,4] -1.13436589 -3.1663031 0.95353664
## delta_mu[1,1,2,3] 0.18861261 -1.1421673 1.68839790
## delta_mu[1,1,2,4] 0.34882748 -1.5257651 2.43010459
## delta_mu[1,1,3,4] 0.16021486 -1.8620975 2.37025975
## delta_mu[1,2,1,2] -0.79885788 -2.8606687 1.29766788
## delta_mu[1,2,1,3] -0.93752420 -2.8539603 0.84074939
## delta_mu[1,2,1,4] -1.07227190 -3.4197356 1.47572086
## delta_mu[1,2,2,3] -0.13866632 -1.6992512 1.05511171
## delta_mu[1,2,2,4] -0.27341402 -2.2719496 1.96340627
## delta_mu[1,2,3,4] -0.13474770 -2.0640282 2.02237961
## delta_mu[2,1,1,2] -0.44615328 -1.8563286 1.25060765
## delta_mu[2,1,1,3] 0.29969518 -1.3368677 1.95150257
## delta_mu[2,1,1,4] -0.63851401 -2.9243974 2.03845730
## delta_mu[2,1,2,3] 0.74584846 -0.8371440 1.96744802
## delta_mu[2,1,2,4] -0.19236073 -2.4039324 2.16624996
## delta_mu[2,1,3,4] -0.93820920 -3.1410351 1.46627165
## delta_mu[2,2,1,2] 0.53656538 -1.1257211 2.07205507
## delta_mu[2,2,1,3] -0.35660838 -1.5274464 0.92155292
## delta_mu[2,2,1,4] -1.26437740 -2.8963874 0.41476351
## delta_mu[2,2,2,3] -0.89317376 -2.4440301 0.88776235
## delta_mu[2,2,2,4] -1.80094278 -3.6446308 0.28558685
## delta_mu[2,2,3,4] -0.90776902 -2.5741474 0.90669258
## delta_mu[3,1,1,2] -0.95969594 -3.1423620 1.16913906
## delta_mu[3,1,1,3] -0.03579893 -2.2999374 2.30561844
## delta_mu[3,1,1,4] 0.24758840 -1.5776359 2.23302812
## delta_mu[3,1,2,3] 0.92389701 -1.2969329 3.14638866
## delta_mu[3,1,2,4] 1.20728433 -0.5861976 2.95046993
## delta_mu[3,1,3,4] 0.28338733 -1.7150282 2.22832639
## delta_mu[3,2,1,2] -0.44028169 -2.7091595 1.76360022
## delta_mu[3,2,1,3] 0.03862393 -2.1076235 2.07842083
## delta_mu[3,2,1,4] 0.33202954 -1.0249043 1.74945237
## delta_mu[3,2,2,3] 0.47890562 -2.2081470 3.01432893
## delta_mu[3,2,2,4] 0.77231122 -1.3765757 2.79796104
## delta_mu[3,2,3,4] 0.29340560 -1.6760161 2.33416538
## delta_mu[4,1,1,2] -1.47294653 -3.5103604 0.86119328
## delta_mu[4,1,1,3] -0.26864250 -2.0731077 1.77301745
## delta_mu[4,1,1,4] -0.69134235 -2.6827307 1.58853779
## delta_mu[4,1,2,3] 1.20430403 -0.1922844 2.44716709
## delta_mu[4,1,2,4] 0.78160418 -0.9514046 2.41454389
## delta_mu[4,1,3,4] -0.42269985 -1.7265548 0.97640141
## delta_mu[4,2,1,2] 1.47092535 -0.7433318 3.41451178
## delta_mu[4,2,1,3] 0.68350971 -0.2196902 1.39224020
## delta_mu[4,2,1,4] 0.69457835 -0.2946551 1.52603234
## delta_mu[4,2,2,3] -0.78741564 -2.6897537 1.40195553
## delta_mu[4,2,2,4] -0.77634700 -2.7355133 1.27590197
## delta_mu[4,2,3,4] 0.01106864 -0.6144561 0.71924238
##
## $euclidean_distances
## metabolite condition_1 condition_2
## euclidean_distance[1,1,2] PEP A B
## euclidean_distance[2,1,2] UMP A B
## euclidean_distance[3,1,2] ATP A B
## euclidean_distance[4,1,2] 2-Aminomuconate A B
## parameter mean 2.5% 97.5%
## euclidean_distance[1,1,2] euclidean_distance 1.778490 0.5943682 3.700455
## euclidean_distance[2,1,2] euclidean_distance 2.091480 0.8524882 3.980323
## euclidean_distance[3,1,2] euclidean_distance 1.886103 0.6184997 3.854299
## euclidean_distance[4,1,2] euclidean_distance 2.546216 1.0535744 4.467523
With the output from the estimates_dynamics function we can cluster metabolite dynamics per experimental condition.
cluster <- # clustering results have to be stored in separate object when using data frame as input
cluster_dynamics(
estimates = estimates, # data is now the estimates or a data frame ob similar structure
fit = fit,
distance = "euclidean", # which distance method should be used
agglomeration = "ward.D2", # which agglomeration method for hierarchical clustering should be used
deepSplit = 2, # sensitivity of cluster analysis,
minClusterSize = 1, # minimum number of metabolites in one cluster
B = 10, # number of bootstrapps
)
## ..cutHeight not given, setting it to 1.14 ===> 99% of the (truncated) height range in dendro.
## ..done.
## ..cutHeight not given, setting it to 1.82 ===> 99% of the (truncated) height range in dendro.
## ..done.
To visualize the clustering results we can use the function plot_cluster which returns a list of plots. For details see Vignette “MetaboDynamics”.
plots <- plot_cluster(cluster)
## Warning in fortify(data, ...): Arguments in `...` must be used.
## ✖ Problematic arguments:
## • as.Date = as.Date
## • yscale_mapping = yscale_mapping
## • hang = hang
## • linetype = "solid"
## ℹ Did you misspell an argument name?
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
## Warning in fortify(data, ...): Arguments in `...` must be used.
## ✖ Problematic arguments:
## • as.Date = as.Date
## • yscale_mapping = yscale_mapping
## • hang = hang
## • linetype = "solid"
## ℹ Did you misspell an argument name?
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
plots$trees$A
plots$clusterplots$A
plots$lineplots$A
plots$patchwork$A
To conduct the over-representation analysis KEGG IDs of the experimental metabolites are needed. Additionally, information on all metabolites that are stored in the KEGG database is needed. This KEGG background information is stored in the data set “modules_compounds”. To apply ORA to a specific dataset a second dataset “metabolite_modules” is needed that can be obtained by filtering “modules_compounds” for the experimental metabolites.
The clustering result also needs to be converted from a list to a single data frame.
# load background dataset
data("modules_compounds")
data("metabolite_modules")
# get KEGGs from data
data("IDs")
The over-representation analysis and visualization can be achieved with the following code:
ora <- # store ORA result to separate object when using data frames as input
ORA_hypergeometric(
background = modules_compounds,
annotations = metabolite_modules,
data = cluster, # dataframe format of clustering output
tested_column = "middle_hierarchy",
IDs = IDs
)
# Visualization
plot_ORA(
data = ora,
tested_column = "middle_hierarchy"
)
## $plot
## Warning in min(x): no non-missing arguments to min; returning Inf
## Warning in max(x): no non-missing arguments to max; returning -Inf
## Warning in min(x): no non-missing arguments to min; returning Inf
## Warning in max(x): no non-missing arguments to max; returning -Inf
##
## $ora_patchwork
## list()
For the comparison of dynamics clusters between experimental conditions one can employ two apporaches: comparing dynamics between clusters and comparing metabolite composition between clusters.
To compare dynamics between clusters awhile using a data frame as input use the following code:
comparison_dynamics <- # result needs to be stored in a separate object when using data frames
compare_dynamics(
data = cluster,
# clustering result
cores = 1 # only set to 1 for vignette, can be increased to 4 for parallelization
)
##
## SAMPLING FOR MODEL 'm_cluster_distances_padded' NOW (CHAIN 1).
## Chain 1:
## Chain 1: Gradient evaluation took 1.6e-05 seconds
## Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.16 seconds.
## Chain 1: Adjust your expectations accordingly!
## Chain 1:
## Chain 1:
## Chain 1: Iteration: 1 / 2000 [ 0%] (Warmup)
## Chain 1: Iteration: 200 / 2000 [ 10%] (Warmup)
## Chain 1: Iteration: 400 / 2000 [ 20%] (Warmup)
## Chain 1: Iteration: 501 / 2000 [ 25%] (Sampling)
## Chain 1: Iteration: 700 / 2000 [ 35%] (Sampling)
## Chain 1: Iteration: 900 / 2000 [ 45%] (Sampling)
## Chain 1: Iteration: 1100 / 2000 [ 55%] (Sampling)
## Chain 1: Iteration: 1300 / 2000 [ 65%] (Sampling)
## Chain 1: Iteration: 1500 / 2000 [ 75%] (Sampling)
## Chain 1: Iteration: 1700 / 2000 [ 85%] (Sampling)
## Chain 1: Iteration: 1900 / 2000 [ 95%] (Sampling)
## Chain 1: Iteration: 2000 / 2000 [100%] (Sampling)
## Chain 1:
## Chain 1: Elapsed Time: 0.051 seconds (Warm-up)
## Chain 1: 0.105 seconds (Sampling)
## Chain 1: 0.156 seconds (Total)
## Chain 1:
##
## SAMPLING FOR MODEL 'm_cluster_distances_padded' NOW (CHAIN 2).
## Chain 2:
## Chain 2: Gradient evaluation took 1e-05 seconds
## Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.1 seconds.
## Chain 2: Adjust your expectations accordingly!
## Chain 2:
## Chain 2:
## Chain 2: Iteration: 1 / 2000 [ 0%] (Warmup)
## Chain 2: Iteration: 200 / 2000 [ 10%] (Warmup)
## Chain 2: Iteration: 400 / 2000 [ 20%] (Warmup)
## Chain 2: Iteration: 501 / 2000 [ 25%] (Sampling)
## Chain 2: Iteration: 700 / 2000 [ 35%] (Sampling)
## Chain 2: Iteration: 900 / 2000 [ 45%] (Sampling)
## Chain 2: Iteration: 1100 / 2000 [ 55%] (Sampling)
## Chain 2: Iteration: 1300 / 2000 [ 65%] (Sampling)
## Chain 2: Iteration: 1500 / 2000 [ 75%] (Sampling)
## Chain 2: Iteration: 1700 / 2000 [ 85%] (Sampling)
## Chain 2: Iteration: 1900 / 2000 [ 95%] (Sampling)
## Chain 2: Iteration: 2000 / 2000 [100%] (Sampling)
## Chain 2:
## Chain 2: Elapsed Time: 0.04 seconds (Warm-up)
## Chain 2: 0.092 seconds (Sampling)
## Chain 2: 0.132 seconds (Total)
## Chain 2:
##
## SAMPLING FOR MODEL 'm_cluster_distances_padded' NOW (CHAIN 3).
## Chain 3:
## Chain 3: Gradient evaluation took 8e-06 seconds
## Chain 3: 1000 transitions using 10 leapfrog steps per transition would take 0.08 seconds.
## Chain 3: Adjust your expectations accordingly!
## Chain 3:
## Chain 3:
## Chain 3: Iteration: 1 / 2000 [ 0%] (Warmup)
## Chain 3: Iteration: 200 / 2000 [ 10%] (Warmup)
## Chain 3: Iteration: 400 / 2000 [ 20%] (Warmup)
## Chain 3: Iteration: 501 / 2000 [ 25%] (Sampling)
## Chain 3: Iteration: 700 / 2000 [ 35%] (Sampling)
## Chain 3: Iteration: 900 / 2000 [ 45%] (Sampling)
## Chain 3: Iteration: 1100 / 2000 [ 55%] (Sampling)
## Chain 3: Iteration: 1300 / 2000 [ 65%] (Sampling)
## Chain 3: Iteration: 1500 / 2000 [ 75%] (Sampling)
## Chain 3: Iteration: 1700 / 2000 [ 85%] (Sampling)
## Chain 3: Iteration: 1900 / 2000 [ 95%] (Sampling)
## Chain 3: Iteration: 2000 / 2000 [100%] (Sampling)
## Chain 3:
## Chain 3: Elapsed Time: 0.048 seconds (Warm-up)
## Chain 3: 0.095 seconds (Sampling)
## Chain 3: 0.143 seconds (Total)
## Chain 3:
##
## SAMPLING FOR MODEL 'm_cluster_distances_padded' NOW (CHAIN 4).
## Chain 4:
## Chain 4: Gradient evaluation took 8e-06 seconds
## Chain 4: 1000 transitions using 10 leapfrog steps per transition would take 0.08 seconds.
## Chain 4: Adjust your expectations accordingly!
## Chain 4:
## Chain 4:
## Chain 4: Iteration: 1 / 2000 [ 0%] (Warmup)
## Chain 4: Iteration: 200 / 2000 [ 10%] (Warmup)
## Chain 4: Iteration: 400 / 2000 [ 20%] (Warmup)
## Chain 4: Iteration: 501 / 2000 [ 25%] (Sampling)
## Chain 4: Iteration: 700 / 2000 [ 35%] (Sampling)
## Chain 4: Iteration: 900 / 2000 [ 45%] (Sampling)
## Chain 4: Iteration: 1100 / 2000 [ 55%] (Sampling)
## Chain 4: Iteration: 1300 / 2000 [ 65%] (Sampling)
## Chain 4: Iteration: 1500 / 2000 [ 75%] (Sampling)
## Chain 4: Iteration: 1700 / 2000 [ 85%] (Sampling)
## Chain 4: Iteration: 1900 / 2000 [ 95%] (Sampling)
## Chain 4: Iteration: 2000 / 2000 [100%] (Sampling)
## Chain 4:
## Chain 4: Elapsed Time: 0.048 seconds (Warm-up)
## Chain 4: 0.089 seconds (Sampling)
## Chain 4: 0.137 seconds (Total)
## Chain 4:
## Warning: There were 44 divergent transitions after warmup. See
## https://mc-stan.org/misc/warnings.html#divergent-transitions-after-warmup
## to find out why this is a problem and how to eliminate them.
## Warning: Examine the pairs() plot to diagnose sampling problems
The data frame needed for visualization of the results is the list element [[“estimates”]] of the function results. To visualize the results run the following code:
# Visualize comparison results
heatmap_dynamics(
estimates = comparison_dynamics[["estimates"]],
data = cluster
)
The comparison of metabolite composition follows the same principle as the comparison of dynamics between clusters:
# compare metabolite composition
compare_metabolites <-
compare_metabolites(
data = cluster
)
# Visualization
heatmap_metabolites(
distances = compare_metabolites,
data = cluster
)
The combination of both comparisons may facilitate detection of differences of longitudinal metabolomes between experimental conditions.
# combine comparison results
temp <- left_join(
comparison_dynamics[["estimates"]], # dynamics comparison
compare_metabolites,
join_by("cluster_a", "cluster_b") # join by cluster comparisons
)
# get unique clusters
x <- unique(c(temp[, "cluster_a"], temp[, "cluster_b"]))
# draw plot
ggplot(temp, aes(x = cluster_b, y = cluster_a)) +
geom_point(aes(size = Jaccard, col = mu_mean)) +
theme_bw() +
scale_color_viridis_c(option = "magma") +
scale_x_discrete(limits = x) +
xlab("") +
ylab("") +
scale_y_discrete(limits = x) +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) +
labs(col = "dynamics distance", size = "metabolite similarity") +
ggtitle("comparison of clusters", "label = condition + cluster ID")
sessionInfo()
## R version 4.5.1 Patched (2025-08-23 r88802)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.3 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.22-bioc/R/lib/libRblas.so
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0 LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_GB LC_COLLATE=C
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: America/New_York
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats4 stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] patchwork_1.3.2 tidyr_1.3.1
## [3] dplyr_1.1.4 ggplot2_4.0.0
## [5] SummarizedExperiment_1.39.1 Biobase_2.69.0
## [7] GenomicRanges_1.61.2 Seqinfo_0.99.2
## [9] IRanges_2.43.0 S4Vectors_0.47.0
## [11] BiocGenerics_0.55.1 generics_0.1.4
## [13] MatrixGenerics_1.21.0 matrixStats_1.5.0
## [15] MetaboDynamics_1.1.7 BiocStyle_2.37.1
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.2.1 viridisLite_0.4.2 farver_2.1.2
## [4] loo_2.8.0 Biostrings_2.77.2 S7_0.2.0
## [7] fastmap_1.2.0 lazyeval_0.2.2 digest_0.6.37
## [10] lifecycle_1.0.4 StanHeaders_2.32.10 KEGGREST_1.49.1
## [13] tidytree_0.4.6 magrittr_2.0.3 compiler_4.5.1
## [16] rlang_1.1.6 sass_0.4.10 tools_4.5.1
## [19] utf8_1.2.6 yaml_2.3.10 knitr_1.50
## [22] labeling_0.4.3 S4Arrays_1.9.1 curl_7.0.0
## [25] pkgbuild_1.4.8 DelayedArray_0.35.2 RColorBrewer_1.1-3
## [28] aplot_0.2.8 abind_1.4-8 withr_3.0.2
## [31] purrr_1.1.0 dynamicTreeCut_1.63-1 grid_4.5.1
## [34] inline_0.3.21 scales_1.4.0 tinytex_0.57
## [37] dichromat_2.0-0.1 cli_3.6.5 rmarkdown_2.29
## [40] crayon_1.5.3 treeio_1.33.0 RcppParallel_5.1.11-1
## [43] ggtree_3.17.1 httr_1.4.7 ape_5.8-1
## [46] cachem_1.1.0 rstan_2.32.7 stringr_1.5.2
## [49] parallel_4.5.1 ggplotify_0.1.2 BiocManager_1.30.26
## [52] XVector_0.49.0 yulab.utils_0.2.1 vctrs_0.6.5
## [55] V8_7.0.0 Matrix_1.7-4 jsonlite_2.0.0
## [58] bookdown_0.44 gridGraphics_0.5-1 magick_2.9.0
## [61] jquerylib_0.1.4 glue_1.8.0 codetools_0.2-20
## [64] stringi_1.8.7 gtable_0.3.6 QuickJSR_1.8.0
## [67] tibble_3.3.0 pillar_1.11.0 rappdirs_0.3.3
## [70] htmltools_0.5.8.1 R6_2.6.1 evaluate_1.0.5
## [73] lattice_0.22-7 png_0.1-8 ggfun_0.2.0
## [76] bslib_0.9.0 rstantools_2.5.0 Rcpp_1.1.0
## [79] gridExtra_2.3 SparseArray_1.9.1 nlme_3.1-168
## [82] xfun_0.53 fs_1.6.6 pkgconfig_2.0.3