library(RedoxRRI)
Overview
RedoxRRI provides a transparent framework to quantify holobiont redox resilience by integrating three complementary domains:
Plant physiology / oxidative–nitrosative buffering (e.g., ROS-related traits) Soil redox stability (e.g., Eh and redox-coupled chemistry) Microbial resilience, represented as a single blended domain that can incorporate: microbial abundance / functional composition (micro_data) microbial network organization (igraph network metrics)
The output is:
a per-sample Redox Resilience Index (RRI) scaled to [0, 1] a ternary-ready composition (Physio, Soil, Micro) with row sums equal to 1 a system-level index attr(x, “RRI_index”) (mean across samples)
Conceptual model
RRI_pipeline()The default domain-level equation implemented in RRI_pipeline() is:
\[ \mathrm{RRI} = w_1 \exp\!\left(-\mathrm{ROS}^{\ast}\right) + w_2 \left(\mathrm{Eh}^{\ast}\right)^2 + w_3 \mathrm{Micro}^{\ast}, \qquad w_1 + w_2 + w_3 = 1. \]
Each domain is first summarized into a 1D latent score (per sample) and normalized to \([0,1]\).
To preserve a three-part ternary representation, microbial resilience is modeled as a single domain score:
\[ \mathrm{Micro}^{\ast} = \alpha\,\mathrm{Micro}^{\ast}_{\mathrm{abund}} + (1-\alpha)\,\mathrm{Micro}^{\ast}_{\mathrm{net}}. \]
alpha_micro = 1 \(\rightarrow\) abundance/functional onlyalpha_micro = 0 \(\rightarrow\) network onlyalpha_micro = 0.5 \(\rightarrow\) equal blend (default)data(redoxrri_example)
str(redoxrri_example, max.level = 1)
## List of 4
## $ ROS_flux :'data.frame': 30 obs. of 4 variables:
## $ Eh_stability:'data.frame': 30 obs. of 4 variables:
## $ micro_data : num [1:30, 1:50] 0.151 0.192 0.26 0.815 0.204 ...
## ..- attr(*, "dimnames")=List of 2
## $ graph :Class 'igraph' hidden list of 10
The object contains:
ROS_flux: physiology traits (samples × variables) Eh_stability: soil variables (samples × variables) micro_data: microbial feature matrix (samples × features) graph: an igraph network
out <- RRI_pipeline(
ROS_flux = redoxrri_example$ROS_flux,
Eh_stability = redoxrri_example$Eh_stability,
micro_data = redoxrri_example$micro_data,
graph = redoxrri_example$graph,
alpha_micro = 0.6, # 60% abundance, 40% network
method_phys = "pca",
method_soil = "pca",
method_micro = "pca",
network_agg = "equation",
w1 = 0.4, w2 = 0.35, w3 = 0.25
)
head(out)
## Physio Soil Micro RRI Micro_abundance Micro_network
## 1 0.72912340 0.2182748 0.05260180 0.0000000 0.07214390 0.5
## 2 0.44345174 0.5565483 0.00000000 0.2927327 0.00000000 0.5
## 3 0.43719288 0.5350623 0.02774483 0.3665788 0.03314344 0.5
## 4 0.43827891 0.3136359 0.24808522 0.3003901 0.23796049 0.5
## 5 0.02833661 0.6505190 0.32114439 0.6807505 0.26008667 0.5
## 6 0.44373432 0.4149157 0.14134999 0.2875466 0.10742758 0.5
## RRI_index
## 1 0.4622054
## 2 0.4622054
## 3 0.4622054
## 4 0.4622054
## 5 0.4622054
## 6 0.4622054
System-level index
attr(out, "RRI_index")
## [1] 0.4622054
summary(out$RRI)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0000 0.2946 0.4786 0.4622 0.6056 1.0000
Interpret the ternary components
The columns Physio, Soil, and Micro are returned in compositional form: Physio+Soil+Micro=1 This makes them directly suitable for ternary visualization.
rowSums(out[, c("Physio", "Soil", "Micro")])[1:6]
## [1] 1 1 1 1 1 1
Microbial components (abundance vs network)
The output also provides the two microbial subcomponents (when available): Micro_abundance: latent score from micro_data Micro_network: latent score from graph (system-level replicated, or sample-specific if graph is a list)
summary(out$Micro_abundance)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0000 0.1913 0.2886 0.3255 0.4569 1.0000
summary(out$Micro_network)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.5 0.5 0.5 0.5 0.5 0.5
Choosing latent-dimension methods Different domains may justify different latent methods.
Common choices:
pca: interpretable linear gradient (often good for physiology) wgcna: co-regulated modules (often appropriate for soil redox syndromes) umap: nonlinear regimes (useful for threshold-like responses) nmf: parts-based factors for nonnegative microbial features Below we compare two plausible specifications. Spec A: Soil as WGCNA (if available), others PCA
specA <- out
if (requireNamespace("WGCNA", quietly = TRUE)) {
specA <- RRI_pipeline(
ROS_flux = redoxrri_example$ROS_flux,
Eh_stability = redoxrri_example$Eh_stability,
micro_data = redoxrri_example$micro_data,
graph = redoxrri_example$graph,
alpha_micro = 0.6,
method_phys = "pca",
method_soil = "wgcna",
method_micro = "pca"
)
c(RRI_index = attr(specA, "RRI_index"))
} else {
message("WGCNA not installed; skipping WGCNA example (Suggests).")
}
##
## Power SFT.R.sq slope truncated.R.sq mean.k. median.k. max.k.
## 1 1 0.031900 6.150 0.2990 4.02e-01 4.32e-01 5.31e-01
## 2 2 0.001230 -0.667 0.3050 7.14e-02 7.85e-02 1.07e-01
## 3 3 0.000309 -0.251 0.0923 1.39e-02 1.52e-02 2.28e-02
## 4 4 0.012500 -1.250 0.0576 2.86e-03 3.07e-03 5.04e-03
## 5 5 0.026700 -1.510 0.0914 6.11e-04 6.45e-04 1.13e-03
## 6 6 0.051900 -1.770 0.0741 1.34e-04 1.39e-04 2.55e-04
## 7 7 0.069000 -1.770 0.0703 2.98e-05 3.06e-05 5.77e-05
## 8 8 0.093700 -1.820 0.0640 6.71e-06 6.82e-06 1.31e-05
## 9 9 0.105000 -1.720 0.0632 1.52e-06 1.54e-06 3.00e-06
## 10 10 0.115000 -1.620 0.0633 3.47e-07 3.49e-07 6.88e-07
## 11 12 0.141000 -1.500 0.0981 1.83e-08 1.83e-08 3.64e-08
## 12 14 0.151000 -1.330 0.0967 9.73e-10 9.74e-10 1.94e-09
## 13 16 0.159000 -1.190 0.0967 5.23e-11 5.23e-11 1.05e-10
## 14 18 0.105000 -2.970 0.6290 2.83e-12 2.83e-12 5.66e-12
## 15 20 0.124000 -3.020 0.6420 1.54e-13 1.54e-13 3.08e-13
## RRI_index
## 0.4622054
Spec B: Nonlinear embedding (UMAP) where available
specB <- out
if (requireNamespace("uwot", quietly = TRUE)) {
specB <- RRI_pipeline(
ROS_flux = redoxrri_example$ROS_flux,
Eh_stability = redoxrri_example$Eh_stability,
micro_data = redoxrri_example$micro_data,
graph = redoxrri_example$graph,
alpha_micro = 0.6,
method_phys = "umap",
method_soil = "umap",
method_micro = "pca"
)
c(RRI_index = attr(specB, "RRI_index"))
} else {
message("uwot not installed; skipping UMAP example (Suggests).")
}
## RRI_index
## 0.5712151
Compare RRI scores across specifications
cmp <- data.frame(
RRI_default = out$RRI,
RRI_specA = if (exists("specA")) specA$RRI else NA_real_,
RRI_specB = if (exists("specB")) specB$RRI else NA_real_
)
stats::cor(cmp, use = "pairwise.complete.obs")
## RRI_default RRI_specA RRI_specB
## RRI_default 1.0000000 1.0000000 0.3877185
## RRI_specA 1.0000000 1.0000000 0.3877185
## RRI_specB 0.3877185 0.3877185 1.0000000
Ternary visualization
This plot requires suggested packages: ggtern, ggplot2, and viridis.
if (requireNamespace("ggtern", quietly = TRUE) &&
requireNamespace("ggplot2", quietly = TRUE) &&
requireNamespace("viridis", quietly = TRUE)) {
plot_RRI_ternary(out)
} else {
message("Install ggtern + ggplot2 + viridis to enable ternary plotting.")
}
Practical guidance and recommended workflow
Assemble domain matrices with samples in rows (same sample order across inputs). Choose a latent method per domain:
physiology: pca or fa soil: pca or wgcna (when syndromic co-regulation is expected) microbial abundance: pca, nmf, or wgcna Decide microbial blending parameter alpha_micro: emphasize composition (alpha_micro high) vs network structure (low) Sensitivity-test weights w1,w2,w3 and methods. Validate RRI against independent outcomes (recovery, stress tolerance, ecosystem function).
sessionInfo()
## R version 4.5.1 (2025-06-13)
## Platform: aarch64-apple-darwin20
## Running under: macOS Tahoe 26.1
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## time zone: Europe/Berlin
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] RedoxRRI_0.99.0 BiocStyle_2.38.0
##
## loaded via a namespace (and not attached):
## [1] DBI_1.2.3 gridExtra_2.3 rlang_1.1.6
## [4] magrittr_2.0.4 matrixStats_1.5.0 compiler_4.5.1
## [7] RSQLite_2.4.3 png_0.1-8 vctrs_0.6.5
## [10] stringr_1.6.0 pkgconfig_2.0.3 crayon_1.5.3
## [13] fastmap_1.2.0 magick_2.9.0 backports_1.5.0
## [16] XVector_0.50.0 labeling_0.4.3 rmarkdown_2.30
## [19] preprocessCore_1.72.0 tinytex_0.58 bit_4.6.0
## [22] xfun_0.54 cachem_1.1.0 jsonlite_2.0.0
## [25] blob_1.2.4 irlba_2.3.5.1 parallel_4.5.1
## [28] cluster_2.1.8.1 R6_2.6.1 bslib_0.9.0
## [31] stringi_1.8.7 RColorBrewer_1.1-3 compositions_2.0-9
## [34] rpart_4.1.24 jquerylib_0.1.4 Rcpp_1.1.0
## [37] Seqinfo_1.0.0 bookdown_0.45 iterators_1.0.14
## [40] knitr_1.50 WGCNA_1.73 base64enc_0.1-3
## [43] IRanges_2.44.0 FNN_1.1.4.1 Matrix_1.7-4
## [46] splines_4.5.1 nnet_7.3-20 igraph_2.2.1
## [49] tidyselect_1.2.1 viridis_0.6.5 rstudioapi_0.17.1
## [52] yaml_2.3.10 doParallel_1.0.17 codetools_0.2-20
## [55] lattice_0.22-7 tibble_3.3.0 plyr_1.8.9
## [58] withr_3.0.2 Biobase_2.70.0 KEGGREST_1.50.0
## [61] S7_0.2.1 evaluate_1.0.5 foreign_0.8-90
## [64] survival_3.8-3 ggtern_4.0.0 bayesm_3.1-6
## [67] Biostrings_2.78.0 pillar_1.11.1 BiocManager_1.30.26
## [70] tensorA_0.36.2.1 checkmate_2.3.3 foreach_1.5.2
## [73] stats4_4.5.1 generics_0.1.4 S4Vectors_0.48.0
## [76] ggplot2_4.0.1 scales_1.4.0 glue_1.8.0
## [79] Hmisc_5.2-4 tools_4.5.1 hexbin_1.28.5
## [82] robustbase_0.99-6 data.table_1.17.8 fastcluster_1.3.0
## [85] grid_4.5.1 impute_1.84.0 AnnotationDbi_1.72.0
## [88] colorspace_2.1-2 htmlTable_2.4.3 latex2exp_0.9.6
## [91] proto_1.0.0 Formula_1.2-5 cli_3.6.5
## [94] viridisLite_0.4.2 dplyr_1.1.4 uwot_0.2.3
## [97] DEoptimR_1.1-4 gtable_0.3.6 dynamicTreeCut_1.63-1
## [100] sass_0.4.10 digest_0.6.39 BiocGenerics_0.56.0
## [103] htmlwidgets_1.6.4 farver_2.1.2 memoise_2.0.1
## [106] htmltools_0.5.8.1 lifecycle_1.0.4 httr_1.4.7
## [109] GO.db_3.22.0 bit64_4.6.0-1 MASS_7.3-65