
MethylSurroGetRR Package for Calculating DNA Methylation-Based
Surrogate Biomarkers
University of Michigan
November 7, 2026
Weights are published, but there is no standard way to generate predicted values.
Core computation is just matrix multiplication, which is rarely where things go wrong.
Real failures happen before computation:
Choices are often undocumented in papers, and they can quietly change results.
Reproducibility
Same weights, same data, different scores. Results can’t be compared across studies.
Silent Errors
A flawed setup rarely throws an error. It returns a plausible but wrong number.
Access
The researchers with the most to gain shouldn’t need a bioinformatician to use surrogates safely.
MethylSurroGetR

MethylSurroGetR’s Three-Step Pipeline



MethylSurroGetR Demo Setup
Install Package
install.packages("remotes")
remotes::install_github("jagoode27/MethylSurroGetR")Load Package
MethylSurroGetR Demo Inputs
Load Sample Weights
data(wts_df)
wts_vec_lin <- with(wts_df, setNames(wt_lin, rownames(wts_df)))
wts_vec_lin <- wts_vec_lin[!is.na(wts_vec_lin)]
print(wts_vec_lin) cg02 cg03 cg06 cg07 cg08 cg11
-0.009083377 -0.001155999 0.005978497 -0.007562015 0.001218960 -0.005869372
cg13 cg15 cg17 cg18 Intercept
-0.007449367 0.005066157 0.007900907 -0.002510744 1.211000000
MethylSurroGetR Demo Inputs
Load Sample Methylation Data
samp1 samp2 samp3 samp4 samp5
cg01 0.1028646 0.32037324 0.48290240 NA 0.36948887
cg02 0.2875775 NA NA 0.8830174 NA
cg04 0.4348927 0.18769112 0.89035022 0.1422943 0.98421920
cg05 0.9849570 0.78229430 0.91443819 0.5492847 0.15420230
cg07 0.8998250 0.24608773 NA 0.3279207 0.95450365
cg08 0.8895393 0.69280341 0.64050681 0.9942698 0.65570580
cg09 NA 0.09359499 0.60873498 0.9540912 NA
cg10 0.8864691 NA NA 0.5854834 0.14190691
cg12 0.1750527 NA 0.14709469 NA 0.69000710
cg13 0.9630242 0.90229905 0.69070528 0.7954674 0.02461368
cg14 0.1306957 NA 0.93529980 0.6478935 NA
cg16 0.6531019 0.33282354 0.30122890 0.3198206 0.89139412
cg17 0.1428000 0.41454634 0.41372433 0.3688455 0.15244475
cg19 0.3435165 0.48861303 0.06072057 0.3077200 NA
cg20 0.6567581 0.95447383 0.94772694 0.2197676 NA
MethylSurroGetR Demo Inputs
| CpG | Weight | Target |
|---|---|---|
| cg01 | 80% | |
| cg02 | ✔ | 40% |
| cg03 | ✔ | 0% |
| cg04 | 100% | |
| cg05 | 100% | |
| cg06 | ✔ | 0% |
| cg07 | ✔ | 80% |
| cg08 | ✔ | 100% |
| cg09 | 60% | |
| cg10 | 60% | |
| cg11 | ✔ | 0% |
| cg12 | 60% | |
| cg13 | ✔ | 100% |
| cg14 | 60% | |
| cg15 | ✔ | 0% |
| cg16 | 100% | |
| cg17 | ✔ | 100% |
| cg18 | ✔ | 0% |
| cg19 | 80% | |
| cg20 | 80% |
10 CpGs in the target data are not part of the weight set
5 weight-set CpGs were not found in the target data
2 matched CpGs have missing values in some target samples
MethylSurroGetR Demo Step 1 · Prepare Data
Create methyl_surro Object
my_surro <- surro_set(
methyl = beta_matrix_miss,
weights = wts_vec_lin,
intercept = "Intercept"
)Added 5 missing probes with NA values (50.0% of weight probes missing from methylation data).
Filtered methylation matrix from 15 to 10 probes to match weights.
MethylSurroGetR Demo Step 1 · Prepare Data
Create methyl_surro Object
print(my_surro)$methyl
samp1 samp2 samp3 samp4 samp5
cg02 0.2875775 NA NA 0.8830174 NA
cg07 0.8998250 0.2460877 NA 0.3279207 0.95450365
cg08 0.8895393 0.6928034 0.6405068 0.9942698 0.65570580
cg13 0.9630242 0.9022990 0.6907053 0.7954674 0.02461368
cg17 0.1428000 0.4145463 0.4137243 0.3688455 0.15244475
cg03 NA NA NA NA NA
cg06 NA NA NA NA NA
cg11 NA NA NA NA NA
cg15 NA NA NA NA NA
cg18 NA NA NA NA NA
$weights
cg02 cg03 cg06 cg07 cg08 cg11
-0.009083377 -0.001155999 0.005978497 -0.007562015 0.001218960 -0.005869372
cg13 cg15 cg17 cg18
-0.007449367 0.005066157 0.007900907 -0.002510744
$intercept
Intercept
1.211
attr(,"class")
[1] "methyl_surro"
MethylSurroGetR Demo Step 2 · Missing Data
| CpG | Sample1 | Sample2 | Sample3 | Sample4 | Sample5 |
|---|---|---|---|---|---|
| cg02 | 0.288 | NA | NA | 0.883 | NA |
| cg07 | 0.9 | 0.246 | NA | 0.328 | 0.955 |
| cg08 | 0.89 | 0.693 | 0.641 | 0.994 | 0.656 |
| cg13 | 0.963 | 0.902 | 0.691 | 0.795 | 0.025 |
| cg17 | 0.143 | 0.415 | 0.414 | 0.369 | 0.152 |
| cg03 | NA | NA | NA | NA | NA |
| cg06 | NA | NA | NA | NA | NA |
| cg11 | NA | NA | NA | NA | NA |
| cg15 | NA | NA | NA | NA | NA |
| cg18 | NA | NA | NA | NA | NA |
Two Types of Missing Data
Missing Observations: CpGs present in the target data but missing for some samples
Missing Probes: CpGs absent from the target data entirely
MethylSurroGetR Demo Step 2 · Missing Data
Check for Missing Data
methyl_miss(my_surro)Missing Data Summary for methyl_surro Object
============================================
Total probes: 10
Total samples: 5
Complete probes: 3 (30.0%)
Probes with missing observations: 2 (20.0%)
Completely missing probes: 5 (50.0%)
Overall missing rate: 58.0%
Probes with partial missing data:
cg02 cg07
0.6 0.2
Completely missing probes:
cg03, cg06, cg11, cg15, cg18
MethylSurroGetR Demo Step 2 · Missing Data
Impute Missing Observations
my_surro <- impute_obs(
methyl_surro = my_surro,
method = "median",
min_nonmiss_prop = 0
)Imputed 4 values in 2 probes using median method.
print(my_surro$methyl) samp1 samp2 samp3 samp4 samp5
cg02 0.2875775 0.5852975 0.5852975 0.8830174 0.58529746
cg07 0.8998250 0.2460877 0.6138728 0.3279207 0.95450365
cg08 0.8895393 0.6928034 0.6405068 0.9942698 0.65570580
cg13 0.9630242 0.9022990 0.6907053 0.7954674 0.02461368
cg17 0.1428000 0.4145463 0.4137243 0.3688455 0.15244475
cg03 NA NA NA NA NA
cg06 NA NA NA NA NA
cg11 NA NA NA NA NA
cg15 NA NA NA NA NA
cg18 NA NA NA NA NA
MethylSurroGetR Demo Inputs
Load External Reference Data
data(ref_df)
ref_vec_mean <- with(ref_df, setNames(mean, rownames(ref_df)))
ref_vec_mean <- ref_vec_mean[!is.na(ref_vec_mean)]
print(ref_vec_mean) cg01 cg02 cg03 cg04 cg05 cg06 cg07 cg08
0.3992451 0.6616689 0.4948262 0.5278895 0.6770353 0.5526592 0.4940793 0.7745650
cg09 cg10 cg11 cg12 cg13 cg14 cg15 cg16
0.5281033 0.4982656 0.4566024 0.3856340 0.6752219 0.5866269 0.4004940 0.4996738
cg17 cg18 cg19 cg20
0.2984722 0.3923206 0.3747138 0.7031609
MethylSurroGetR Demo Step 2 · Missing Data
Fill Missing Probes from Reference
my_surro <- reference_fill(
methyl_surro = my_surro,
reference = ref_vec_mean,
type = "probes"
)Filled 25 values using reference data (probes strategy).
print(my_surro$methyl) samp1 samp2 samp3 samp4 samp5
cg02 0.2875775 0.5852975 0.5852975 0.8830174 0.58529746
cg07 0.8998250 0.2460877 0.6138728 0.3279207 0.95450365
cg08 0.8895393 0.6928034 0.6405068 0.9942698 0.65570580
cg13 0.9630242 0.9022990 0.6907053 0.7954674 0.02461368
cg17 0.1428000 0.4145463 0.4137243 0.3688455 0.15244475
cg03 0.4948262 0.4948262 0.4948262 0.4948262 0.49482616
cg06 0.5526592 0.5526592 0.5526592 0.5526592 0.55265924
cg11 0.4566024 0.4566024 0.4566024 0.4566024 0.45660238
cg15 0.4004940 0.4004940 0.4004940 0.4004940 0.40049405
cg18 0.3923206 0.3923206 0.3923206 0.3923206 0.39232059
MethylSurroGetR Demo Step 3 · Calculate Score
Calculate Predicted Values
surro_predvals <- surro_calc(
methyl_surro = my_surro,
transform = "linear"
)
print(surro_predvals) samp1 samp2 samp3 samp4 samp5
1.197718 1.202317 1.201042 1.199796 1.201382
MethylSurroGetR Demo Steps 1–3
Piping Commands
surro_predvals <- beta_matrix_miss |>
surro_set(weights = wts_vec_lin, intercept = "Intercept") |>
impute_obs(method = "median", min_nonmiss_prop = 0) |>
reference_fill(reference = ref_vec_mean, type = "probes") |>
surro_calc(transform = "linear")
print(surro_predvals) samp1 samp2 samp3 samp4 samp5
1.197718 1.202317 1.201042 1.199796 1.201382
MethylSurroGetR Fit?Not the Right Solution
methylCIPHER)Great Fit

Coauthors
Testing
Funding
This work was supported in part by the National Institute on Aging (NIA; R01AG071071) and a Eunice Kennedy Shriver National Institute of Child Health and Human Development (NICHD) training grant to the Population Studies Center at the University of Michigan (T32HD007339).
The content is solely the responsibility of the authors and does not necessarily represent the official views of the National Institutes of Health.
Disclosures
The authors have no financial conflicts of interest to disclose.
AI tools were used for proofreading and slide formatting.
Scan/Click QR Code to Visit
