6. Testing Rescue by IGF Supplementation
6.1 Primary IGF1-versus-IGF2 rescue model
model_igf_split <- lmerTest::lmer(
Perc.Regeneration ~
Week * Perc.WeightLoss * IGF_type + Tail +
(1 | Animal_ID),
data = data
)
summary(model_igf_split)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Perc.Regeneration ~ Week * Perc.WeightLoss * IGF_type + Tail +
## (1 | Animal_ID)
## Data: data
##
## REML criterion at convergence: 2717.5
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -3.05240 -0.58328 0.07647 0.53288 3.14152
##
## Random effects:
## Groups Name Variance Std.Dev.
## Animal_ID (Intercept) 15.52 3.940
## Residual 19.87 4.457
## Number of obs: 443, groups: Animal_ID, 65
##
## Fixed effects:
## Estimate Std. Error df t value
## (Intercept) 8.95632 5.37444 66.82767 1.666
## Week 5.57153 0.22507 390.98913 24.755
## Perc.WeightLoss 0.16173 0.06336 418.47176 2.553
## IGF_typeIGF1 6.23221 2.90106 308.60824 2.148
## IGF_typeIGF2 4.86116 3.88987 361.49614 1.250
## Tail -0.22402 0.07251 66.89851 -3.090
## Week:Perc.WeightLoss -0.05150 0.01184 388.69919 -4.350
## Week:IGF_typeIGF1 -1.60695 0.50288 411.98772 -3.196
## Week:IGF_typeIGF2 -2.61979 0.61694 399.53649 -4.246
## Perc.WeightLoss:IGF_typeIGF1 -0.25717 0.14183 423.73347 -1.813
## Perc.WeightLoss:IGF_typeIGF2 -0.23525 0.17665 422.61347 -1.332
## Week:Perc.WeightLoss:IGF_typeIGF1 0.03935 0.02919 424.77894 1.348
## Week:Perc.WeightLoss:IGF_typeIGF2 0.11330 0.02987 393.97138 3.793
## Pr(>|t|)
## (Intercept) 0.100302
## Week < 2e-16 ***
## Perc.WeightLoss 0.011041 *
## IGF_typeIGF1 0.032472 *
## IGF_typeIGF2 0.212219
## Tail 0.002919 **
## Week:Perc.WeightLoss 1.74e-05 ***
## Week:IGF_typeIGF1 0.001503 **
## Week:IGF_typeIGF2 2.70e-05 ***
## Perc.WeightLoss:IGF_typeIGF1 0.070503 .
## Perc.WeightLoss:IGF_typeIGF2 0.183676
## Week:Perc.WeightLoss:IGF_typeIGF1 0.178340
## Week:Perc.WeightLoss:IGF_typeIGF2 0.000172 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(model_igf_split)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## Week 5315.5 5315.5 1 405.93 267.5724 < 2.2e-16
## Perc.WeightLoss 0.0 0.0 1 419.69 0.0011 0.9735115
## IGF_type 107.4 53.7 2 336.71 2.7031 0.0684535
## Tail 189.6 189.6 1 66.90 9.5458 0.0029187
## Week:Perc.WeightLoss 0.0 0.0 1 413.66 0.0021 0.9634575
## Week:IGF_type 486.0 243.0 2 406.02 12.2327 6.939e-06
## Perc.WeightLoss:IGF_type 87.4 43.7 2 422.06 2.1996 0.1121193
## Week:Perc.WeightLoss:IGF_type 296.9 148.5 2 412.47 7.4732 0.0006484
##
## Week ***
## Perc.WeightLoss
## IGF_type .
## Tail **
## Week:Perc.WeightLoss
## Week:IGF_type ***
## Perc.WeightLoss:IGF_type
## Week:Perc.WeightLoss:IGF_type ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Manuscript interpretation: IGF2 significantly
altered the increasingly negative relationship between energetic deficit
and regeneration ( P = 0.00017), whereas IGF1 did not (p =0.178) .
6.1.2 Alternative regeneration metrics
These models retain the same fixed- and random-effect structure while
replacing the response variable.
model_weightloss_rate <- lmerTest::lmer(
Rate_Reg ~ Week * Perc.WeightLoss *IGF_type + Tail +
(1 | Animal_ID),
data = data
)
model_weightloss_absolute <- lmerTest::lmer(
Regeneration ~ Week * Perc.WeightLoss *IGF_type + Tail +
(1 | Animal_ID),
data = data
)
summary(model_weightloss_rate)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Rate_Reg ~ Week * Perc.WeightLoss * IGF_type + Tail + (1 | Animal_ID)
## Data: data
##
## REML criterion at convergence: 1876.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.3778 -0.6999 -0.2014 0.5595 6.1085
##
## Random effects:
## Groups Name Variance Std.Dev.
## Animal_ID (Intercept) 0.02198 0.1482
## Residual 7.35988 2.7129
## Number of obs: 380, groups: Animal_ID, 64
##
## Fixed effects:
## Estimate Std. Error df t value
## (Intercept) 3.983893 1.592815 62.654178 2.501
## Week 0.022785 0.150929 344.637628 0.151
## Perc.WeightLoss 0.078408 0.043764 366.933538 1.792
## IGF_typeIGF1 0.174182 1.704939 355.773477 0.102
## IGF_typeIGF2 -1.023781 2.207736 325.606939 -0.464
## Tail -0.018409 0.020299 42.917758 -0.907
## Week:Perc.WeightLoss -0.013048 0.008160 336.923711 -1.599
## Week:IGF_typeIGF1 -0.121004 0.326578 366.982012 -0.371
## Week:IGF_typeIGF2 -0.151883 0.409571 366.830455 -0.371
## Perc.WeightLoss:IGF_typeIGF1 -0.051345 0.097548 357.354390 -0.526
## Perc.WeightLoss:IGF_typeIGF2 -0.006471 0.110176 344.373932 -0.059
## Week:Perc.WeightLoss:IGF_typeIGF1 0.011185 0.019099 360.490004 0.586
## Week:Perc.WeightLoss:IGF_typeIGF2 0.015650 0.020760 364.824718 0.754
## Pr(>|t|)
## (Intercept) 0.015 *
## Week 0.880
## Perc.WeightLoss 0.074 .
## IGF_typeIGF1 0.919
## IGF_typeIGF2 0.643
## Tail 0.370
## Week:Perc.WeightLoss 0.111
## Week:IGF_typeIGF1 0.711
## Week:IGF_typeIGF2 0.711
## Perc.WeightLoss:IGF_typeIGF1 0.599
## Perc.WeightLoss:IGF_typeIGF2 0.953
## Week:Perc.WeightLoss:IGF_typeIGF1 0.558
## Week:Perc.WeightLoss:IGF_typeIGF2 0.451
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(model_weightloss_rate)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## Week 1.2234 1.2234 1 366.99 0.1662 0.6837
## Perc.WeightLoss 11.8232 11.8232 1 346.80 1.6064 0.2058
## IGF_type 1.8351 0.9176 2 340.62 0.1247 0.8828
## Tail 6.0531 6.0531 1 42.92 0.8224 0.3695
## Week:Perc.WeightLoss 1.5280 1.5280 1 366.17 0.2076 0.6489
## Week:IGF_type 1.7282 0.8641 2 366.60 0.1174 0.8893
## Perc.WeightLoss:IGF_type 2.0494 1.0247 2 350.20 0.1392 0.8701
## Week:Perc.WeightLoss:IGF_type 5.7791 2.8896 2 362.92 0.3926 0.6756
summary(model_weightloss_absolute)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Regeneration ~ Week * Perc.WeightLoss * IGF_type + Tail + (1 |
## Animal_ID)
## Data: data
##
## REML criterion at convergence: 2318.5
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -2.63135 -0.56996 0.08751 0.58321 3.08045
##
## Random effects:
## Groups Name Variance Std.Dev.
## Animal_ID (Intercept) 6.837 2.615
## Residual 7.847 2.801
## Number of obs: 442, groups: Animal_ID, 65
##
## Fixed effects:
## Estimate Std. Error df t value
## (Intercept) -1.926997 3.529452 66.015831 -0.546
## Week 3.286170 0.141627 388.192452 23.203
## Perc.WeightLoss 0.049363 0.039961 415.191120 1.235
## IGF_typeIGF1 2.509958 1.855201 301.514022 1.353
## IGF_typeIGF2 1.628220 2.477492 361.831869 0.657
## Tail -0.028452 0.047614 66.202786 -0.598
## Week:Perc.WeightLoss -0.016560 0.007448 386.035519 -2.223
## Week:IGF_typeIGF1 -0.529278 0.317018 409.527055 -1.670
## Week:IGF_typeIGF2 -1.338341 0.388458 396.681548 -3.445
## Perc.WeightLoss:IGF_typeIGF1 -0.112795 0.089886 423.495021 -1.255
## Perc.WeightLoss:IGF_typeIGF2 -0.104107 0.111946 424.229848 -0.930
## Week:Perc.WeightLoss:IGF_typeIGF1 0.005680 0.018437 423.020369 0.308
## Week:Perc.WeightLoss:IGF_typeIGF2 0.062718 0.018801 391.245932 3.336
## Pr(>|t|)
## (Intercept) 0.586923
## Week < 2e-16 ***
## Perc.WeightLoss 0.217422
## IGF_typeIGF1 0.177091
## IGF_typeIGF2 0.511467
## Tail 0.552170
## Week:Perc.WeightLoss 0.026772 *
## Week:IGF_typeIGF1 0.095772 .
## Week:IGF_typeIGF2 0.000631 ***
## Perc.WeightLoss:IGF_typeIGF1 0.210217
## Perc.WeightLoss:IGF_typeIGF2 0.352911
## Week:Perc.WeightLoss:IGF_typeIGF1 0.758172
## Week:Perc.WeightLoss:IGF_typeIGF2 0.000932 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(model_weightloss_absolute)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## Week 2166.04 2166.04 1 403.24 276.0261 < 2.2e-16
## Perc.WeightLoss 1.96 1.96 1 421.07 0.2495 0.617681
## IGF_type 15.79 7.90 2 333.50 1.0061 0.366741
## Tail 2.80 2.80 1 66.20 0.3571 0.552170
## Week:Perc.WeightLoss 4.31 4.31 1 411.44 0.5492 0.459063
## Week:IGF_type 103.05 51.53 2 403.37 6.5661 0.001563
## Perc.WeightLoss:IGF_type 16.65 8.33 2 422.70 1.0610 0.347023
## Week:Perc.WeightLoss:IGF_type 87.74 43.87 2 410.23 5.5902 0.004024
##
## Week ***
## Perc.WeightLoss
## IGF_type
## Tail
## Week:Perc.WeightLoss
## Week:IGF_type **
## Perc.WeightLoss:IGF_type
## Week:Perc.WeightLoss:IGF_type **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Manuscript results: As a sensitivity analysis, the
primary model was repeated using alternative measures of regeneration,
including weekly regeneration rate (mm/week) and cumulative regenerated
tail length (mm). For weekly regeneration rate, neither week, percent
body mass loss, IGF supplementation, nor any interaction terms
significantly predicted regeneration rate, although percent body mass
loss exhibited a weak positive trend (β = 0.078, p = 0.074). Similarly,
when regeneration was expressed as cumulative regenerated tail length,
regeneration increased significantly over time (β = 3.29, p <
0.0001), and the interaction between week and percent body mass loss
remained significantly negative (β = −0.0166, p = 0.027), indicating
that the energetic trade-off became stronger as regeneration progressed.
Consistent with the primary analysis, IGF2 significantly attenuated this
negative relationship over time (Week × IGF2: β = −1.34, p = 0.0006;
Week × Percent Weight Loss × IGF2: β = 0.0627, p = 0.0009), whereas IGF1
showed no significant effects. Together, these analyses demonstrate that
the primary conclusions are robust to alternative measures of
regeneration, with cumulative regeneration yielding results that closely
mirror those obtained using percent regeneration.
6.2 Model-based predictions
predicted_all_weeks <- ggpredict(
model_igf_split,
terms = c(
"Perc.WeightLoss",
"IGF_type",
"Week [2,4,6,8]"
)
)
predicted_all_weeks
## # Predicted values of Perc.Regeneration
##
## IGF_type: No_IGF
## Week: 2
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | -0.54 | -7.95, 6.87
## -35 | 0.93 | -4.17, 6.02
## -5 | 2.69 | 0.13, 5.25
## 50 | 5.92 | 2.18, 9.66
##
## IGF_type: No_IGF
## Week: 4
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | 16.78 | 10.10, 23.46
## -35 | 15.67 | 11.04, 20.30
## -5 | 14.35 | 11.96, 16.73
## 50 | 11.91 | 8.62, 15.21
##
## IGF_type: No_IGF
## Week: 6
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | 34.10 | 26.42, 41.78
## -35 | 30.42 | 25.11, 35.73
## -5 | 26.00 | 23.33, 28.68
## 50 | 17.91 | 14.19, 21.62
##
## IGF_type: No_IGF
## Week: 8
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | 51.42 | 41.52, 61.33
## -35 | 45.17 | 38.37, 51.96
## -5 | 37.66 | 34.36, 40.97
## 50 | 23.90 | 19.12, 28.68
##
## IGF_type: IGF1
## Week: 2
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | 13.18 | -0.91, 27.28
## -35 | 10.19 | 0.49, 19.90
## -5 | 6.60 | 1.95, 11.25
## 50 | 0.01 | -6.19, 6.21
##
## IGF_type: IGF1
## Week: 4
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | 22.57 | 10.39, 34.75
## -35 | 18.97 | 10.59, 27.35
## -5 | 14.65 | 10.60, 18.70
## 50 | 6.73 | 1.18, 12.28
##
## IGF_type: IGF1
## Week: 6
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | 31.96 | 17.01, 46.91
## -35 | 27.75 | 17.61, 37.89
## -5 | 22.70 | 18.08, 27.32
## 50 | 13.44 | 6.29, 20.59
##
## IGF_type: IGF1
## Week: 8
##
## Perc.WeightLoss | Predicted | 95% CI
## ------------------------------------------
## -60 | 41.34 | 20.75, 61.94
## -35 | 36.53 | 22.67, 50.38
## -5 | 30.75 | 24.72, 36.78
## 50 | 20.16 | 10.19, 30.13
##
## IGF_type: IGF2
## Week: 2
##
## Perc.WeightLoss | Predicted | 95% CI
## -------------------------------------------
## -60 | -0.40 | -20.36, 19.55
## -35 | 0.85 | -13.01, 14.71
## -5 | 2.35 | -4.34, 9.04
## 50 | 5.11 | -2.43, 12.65
##
## IGF_type: IGF2
## Week: 4
##
## Perc.WeightLoss | Predicted | 95% CI
## -------------------------------------------
## -60 | -1.92 | -17.92, 14.09
## -35 | 2.43 | -8.71, 13.56
## -5 | 7.64 | 2.20, 13.07
## 50 | 17.19 | 11.02, 23.36
##
## IGF_type: IGF2
## Week: 6
##
## Perc.WeightLoss | Predicted | 95% CI
## -------------------------------------------
## -60 | -3.43 | -19.66, 12.80
## -35 | 4.00 | -7.25, 15.26
## -5 | 12.92 | 7.47, 18.37
## 50 | 29.28 | 22.83, 35.72
##
## IGF_type: IGF2
## Week: 8
##
## Perc.WeightLoss | Predicted | 95% CI
## -------------------------------------------
## -60 | -4.94 | -25.43, 15.54
## -35 | 5.58 | -8.57, 19.73
## -5 | 18.21 | 11.48, 24.94
## 50 | 41.36 | 33.15, 49.56
##
## Adjusted for:
## * Tail = 76.41
## * Animal_ID = 0 (population-level)
plot_predictions <- ggplot(
predicted_all_weeks,
aes(
x = x,
y = predicted,
color = group,
fill = group
)
) +
geom_ribbon(
aes(ymin = conf.low, ymax = conf.high),
alpha = 0.15,
color = NA
) +
geom_line(linewidth = 1.2) +
facet_wrap(~facet) +
scale_color_manual(values = igf_colors) +
scale_fill_manual(values = igf_colors) +
labs(
x = "Percent body-mass loss",
y = "Predicted cumulative percent regeneration",
color = "IGF treatment",
fill = "IGF treatment"
) +
theme_classic()
plot_predictions

Depiction: Predicted regeneration trajectories
demonstrate that the relationship between energetic state and
regeneration strengthened over time. By Weeks 6–8, IGF2 reversed the
negative association between body mass loss and regeneration observed in
untreated and IGF1-treated animals, indicating progressive attenuation
of the energetic trade-off.
6.3 Week-specific energetic-state slopes
week_specific_slopes <- emtrends(
model_igf_split,
~ IGF_type | Week,
var = "Perc.WeightLoss",
at = list(Week = c(2, 4, 6, 8))
)
summary(week_specific_slopes, infer = TRUE)
## Week = 2:
## IGF_type Perc.WeightLoss.trend SE df lower.CL upper.CL t.ratio p.value
## No_IGF 0.0587 0.0491 430 -0.0377 0.1552 1.197 0.2321
## IGF1 -0.1197 0.0915 392 -0.2996 0.0602 -1.308 0.1915
## IGF2 0.0501 0.1260 366 -0.1976 0.2978 0.398 0.6911
##
## Week = 4:
## IGF_type Perc.WeightLoss.trend SE df lower.CL upper.CL t.ratio p.value
## No_IGF -0.0442 0.0437 414 -0.1301 0.0416 -1.013 0.3116
## IGF1 -0.1440 0.0796 408 -0.3004 0.0124 -1.810 0.0710
## IGF2 0.1737 0.1010 307 -0.0255 0.3729 1.716 0.0872
##
## Week = 6:
## IGF_type Perc.WeightLoss.trend SE df lower.CL upper.CL t.ratio p.value
## No_IGF -0.1472 0.0503 422 -0.2461 -0.0484 -2.928 0.0036
## IGF1 -0.1683 0.1000 430 -0.3650 0.0284 -1.682 0.0933
## IGF2 0.2973 0.1030 367 0.0943 0.5003 2.880 0.0042
##
## Week = 8:
## IGF_type Perc.WeightLoss.trend SE df lower.CL upper.CL t.ratio p.value
## No_IGF -0.2502 0.0654 430 -0.3787 -0.1217 -3.828 0.0001
## IGF1 -0.1926 0.1390 425 -0.4665 0.0813 -1.382 0.1677
## IGF2 0.4209 0.1310 430 0.1639 0.6780 3.218 0.0014
##
## Degrees-of-freedom method: kenward-roger
## Confidence level used: 0.95
week_specific_slopes_df <- as.data.frame(
summary(week_specific_slopes, infer = TRUE)
)
Manuscript Result: Week-specific slope estimates
demonstrated that energetic state had little influence on regeneration
during the early stages of tail regrowth (Weeks 2–4), as none of the
treatment-specific slopes differed significantly from zero. By Week 6,
untreated animals exhibited a significant negative relationship between
body mass loss and regeneration (β = −0.147, p = 0.0036), whereas
IGF2-treated animals exhibited a significant positive relationship (β =
0.297, p = 0.0042), indicating attenuation of the energetic trade-off.
This divergence became even more pronounced by Week 8, with untreated
animals showing a stronger negative relationship (β = −0.250, p =
0.0001) and IGF2-treated animals showing a stronger positive
relationship (β = 0.421, p = 0.0014). Although IGF1 exhibited a modest
positive trend at Week 4 (p = 0.071), it did not differ significantly
from zero at any time point.
6.4 Pairwise comparisons of slopes
The manuscript describes Tukey-adjusted comparisons among
supplementation groups. Both the full pairwise comparisons and
treatment-versus-control contrasts are retained.
# All pairwise comparisons within week, Tukey adjusted
pairwise_slopes_tukey <- pairs(
week_specific_slopes,
adjust = "tukey"
)
pairwise_slopes_tukey
## Week = 2:
## contrast estimate SE df t.ratio p.value
## No_IGF - IGF1 0.17847 0.1040 408 1.713 0.2014
## No_IGF - IGF2 0.00865 0.1350 379 0.064 0.9977
## IGF1 - IGF2 -0.16982 0.1560 376 -1.090 0.5206
##
## Week = 4:
## contrast estimate SE df t.ratio p.value
## No_IGF - IGF1 0.09976 0.0911 412 1.095 0.5176
## No_IGF - IGF2 -0.21795 0.1100 325 -1.980 0.1189
## IGF1 - IGF2 -0.31771 0.1290 350 -2.467 0.0375
##
## Week = 6:
## contrast estimate SE df t.ratio p.value
## No_IGF - IGF1 0.02106 0.1120 430 0.188 0.9808
## No_IGF - IGF2 -0.44454 0.1150 379 -3.876 0.0004
## IGF1 - IGF2 -0.46560 0.1440 412 -3.238 0.0037
##
## Week = 8:
## contrast estimate SE df t.ratio p.value
## No_IGF - IGF1 -0.05765 0.1540 426 -0.374 0.9258
## No_IGF - IGF2 -0.67114 0.1460 430 -4.594 <0.0001
## IGF1 - IGF2 -0.61349 0.1910 429 -3.210 0.0041
##
## Degrees-of-freedom method: kenward-roger
## P value adjustment: tukey method for comparing a family of 3 estimates
Manuscript Result: Tukey-adjusted pairwise
comparisons of week-specific slopes showed no significant differences
among treatments at Week 2. By Week 4, the slope for IGF2 differed
significantly from IGF1 (p = 0.038) but not from untreated controls (p =
0.119). Significant differences between IGF2-treated and untreated
animals emerged by Week 6 (p = 0.0004) and became even more pronounced
by Week 8 (p < 0.0001), indicating that IGF2 progressively attenuated
the energetic trade-off over time. IGF1 did not differ from untreated
controls at any time point.
8. Additional and Sensitivity Analyses
8.1 Administered hormone dose
igf_data <- data %>%
filter(Treatment %in% c("DR.IGF1", "DR.IGF2")) %>%
mutate(
IGF_type = factor(
Treatment,
levels = c("DR.IGF1", "DR.IGF2")
)
) %>%
group_by(Animal_ID) %>%
fill(Dose, .direction = "downup") %>%
ungroup()
model_dose <- lmerTest::lmer(
Rate_Reg ~ Week * Dose * IGF_type +
Tail +
(1 | Animal_ID),
data = igf_data
)
summary(model_dose)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Rate_Reg ~ Week * Dose * IGF_type + Tail + (1 | Animal_ID)
## Data: igf_data
##
## REML criterion at convergence: 964.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.3156 -0.6620 -0.1643 0.4927 6.1166
##
## Random effects:
## Groups Name Variance Std.Dev.
## Animal_ID (Intercept) 0.000 0.000
## Residual 7.389 2.718
## Number of obs: 200, groups: Animal_ID, 33
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) -0.34343 6.62219 191.00000 -0.052 0.959
## Week 0.37140 1.17613 191.00000 0.316 0.753
## Dose 2.27038 2.74356 191.00000 0.828 0.409
## IGF_typeDR.IGF2 4.14492 7.97901 191.00000 0.519 0.604
## Tail -0.01755 0.03851 191.00000 -0.456 0.649
## Week:Dose -0.23512 0.54290 191.00000 -0.433 0.665
## Week:IGF_typeDR.IGF2 -0.78700 1.57735 191.00000 -0.499 0.618
## Dose:IGF_typeDR.IGF2 -1.96201 3.65967 191.00000 -0.536 0.593
## Week:Dose:IGF_typeDR.IGF2 0.38027 0.72186 191.00000 0.527 0.599
##
## Correlation of Fixed Effects:
## (Intr) Week Dose IGF_DR Tail Wek:Ds W:IGF_ D:IGF_
## Week -0.810
## Dose -0.884 0.911
## IGF_DR.IGF2 -0.644 0.684 0.738
## Tail -0.445 -0.029 -0.010 -0.049
## Week:Dose 0.807 -0.993 -0.920 -0.680 0.023
## W:IGF_DR.IG 0.606 -0.745 -0.679 -0.923 0.016 0.740
## D:IGF_DR.IG 0.645 -0.684 -0.750 -0.992 0.047 0.690 0.914
## W:D:IGF_DR. -0.609 0.746 0.692 0.916 -0.013 -0.752 -0.992 -0.923
## optimizer (nloptwrap) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
anova(model_dose)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## Week 0.0058 0.0058 1 191 0.0008 0.9777
## Dose 3.6730 3.6730 1 191 0.4971 0.4816
## IGF_type 1.9939 1.9939 1 191 0.2699 0.6040
## Tail 1.5350 1.5350 1 191 0.2077 0.6491
## Week:Dose 0.1147 0.1147 1 191 0.0155 0.9010
## Week:IGF_type 1.8394 1.8394 1 191 0.2489 0.6184
## Dose:IGF_type 2.1237 2.1237 1 191 0.2874 0.5925
## Week:Dose:IGF_type 2.0505 2.0505 1 191 0.2775 0.5989
Interpretation: Modest individual variation in
administered dose did not detectably influence regeneration rate or
explain the different responses to IGF1 and IGF2.
model.rescue2 <- lmer(
Perc.Regeneration ~ Week * Perc.WeightLoss * IGF_type + Tail +
(1 | Animal_ID),
data = data,
REML = FALSE
)
model.rescue.dose <- lmer(
Perc.Regeneration ~ Week * Perc.WeightLoss * IGF_type + Tail + Dose +
(1 | Animal_ID),
data = data,
REML = FALSE
)
AIC(model.rescue2, model.rescue.dose)
## df AIC
## model.rescue2 15 2715.726
## model.rescue.dose 16 2717.558
Result: Adding IGF dose as an additional covariate
did not improve model fit (ΔAIC = 1.91), indicating that variation in
administered dose did not explain additional variation in regeneration
beyond treatment identity.
8.2 Endpoint covariance between energetic state and
regeneration
final_regeneration_data <- data %>%
group_by(Animal_ID) %>%
summarise(
final_regeneration = max(Regeneration, na.rm = TRUE),
weight_loss = first(Perc.WeightLoss),
Treatment = first(Treatment),
.groups = "drop"
)
cor.test(
final_regeneration_data$weight_loss,
final_regeneration_data$final_regeneration
)
##
## Pearson's product-moment correlation
##
## data: final_regeneration_data$weight_loss and final_regeneration_data$final_regeneration
## t = 0.56258, df = 61, p-value = 0.5758
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## -0.1791079 0.3140206
## sample estimates:
## cor
## 0.0718454
model_endpoint_tradeoff <- lm(
final_regeneration ~ weight_loss * Treatment,
data = final_regeneration_data
)
summary(model_endpoint_tradeoff)
##
## Call:
## lm(formula = final_regeneration ~ weight_loss * Treatment, data = final_regeneration_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -13.0612 -3.8851 -0.1858 3.8499 13.4936
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 17.65763 3.43266 5.144 3.7e-06 ***
## weight_loss 0.03591 0.21771 0.165 0.870
## TreatmentDR -5.52370 4.36111 -1.267 0.211
## TreatmentDR.IGF1 1.13593 5.18537 0.219 0.827
## TreatmentDR.IGF2 -9.61449 6.61079 -1.454 0.152
## weight_loss:TreatmentDR 0.14270 0.24926 0.572 0.569
## weight_loss:TreatmentDR.IGF1 -0.36936 0.28830 -1.281 0.206
## weight_loss:TreatmentDR.IGF2 0.38573 0.33340 1.157 0.252
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 6.379 on 55 degrees of freedom
## (13 observations deleted due to missingness)
## Multiple R-squared: 0.2204, Adjusted R-squared: 0.1212
## F-statistic: 2.222 on 7 and 55 DF, p-value: 0.04612
anova(model_endpoint_tradeoff)
## Analysis of Variance Table
##
## Response: final_regeneration
## Df Sum Sq Mean Sq F value Pr(>F)
## weight_loss 1 14.82 14.821 0.3642 0.54868
## Treatment 3 320.43 106.809 2.6245 0.05954 .
## weight_loss:Treatment 3 297.71 99.238 2.4385 0.07418 .
## Residuals 55 2238.30 40.696
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
This endpoint analysis is retained because it demonstrates that the
longitudinal mixed-effects model is more sensitive to changes in
regenerative dynamics than a single final-time-point comparison.
8.4 Final percent body-mass loss among treatment groups
final_weight_loss <- data %>%
ungroup() %>%
group_by(Animal_ID) %>%
summarise(
final_weight_loss = max(Perc.WeightLoss, na.rm = TRUE),
Treatment = first(na.omit(Treatment)),
.groups = "drop"
) %>%
filter(
!is.na(final_weight_loss),
is.finite(final_weight_loss),
!is.na(Treatment)
) %>%
mutate(
Treatment = droplevels(as.factor(Treatment))
)
model_final_weight_loss <- lm(
final_weight_loss ~ Treatment,
data = final_weight_loss
)
anova(model_final_weight_loss)
## Analysis of Variance Table
##
## Response: final_weight_loss
## Df Sum Sq Mean Sq F value Pr(>F)
## Treatment 3 602.9 200.972 2.953 0.03951 *
## Residuals 61 4151.5 68.057
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
final_weight_loss_emmeans <- emmeans(
model_final_weight_loss,
pairwise ~ Treatment,
adjust = "tukey"
)
final_weight_loss_emmeans
## $emmeans
## Treatment emmean SE df lower.CL upper.CL
## AdLib 17.9 1.94 61 14.0 21.7
## DR 25.6 2.29 61 21.0 30.2
## DR.IGF1 23.1 2.00 61 19.1 27.1
## DR.IGF2 24.7 2.00 61 20.7 28.7
##
## Confidence level used: 0.95
##
## $contrasts
## contrast estimate SE df t.ratio p.value
## AdLib - DR -7.765 3.00 61 -2.586 0.0571
## AdLib - DR.IGF1 -5.257 2.79 61 -1.884 0.2456
## AdLib - DR.IGF2 -6.841 2.79 61 -2.452 0.0781
## DR - DR.IGF1 2.508 3.04 61 0.825 0.8423
## DR - DR.IGF2 0.924 3.04 61 0.304 0.9901
## DR.IGF1 - DR.IGF2 -1.584 2.83 61 -0.560 0.9435
##
## P value adjustment: tukey method for comparing a family of 4 estimates
Manuscript interpretation: Final percent body-mass
loss did not differ among the three diet-restricted groups (p >
0.65), supporting the conclusion that the IGF2 rescue effect was not
explained by reduced energetic deficit.
ggplot(
final_weight_loss,
aes(
x = Treatment,
y = final_weight_loss,
fill = Treatment
)
) +
geom_violin(alpha = 0.3, trim = FALSE) +
geom_jitter(width = 0.1, alpha = 0.7, size = 2) +
stat_summary(
fun = mean,
geom = "point",
size = 4,
color = "black"
) +
stat_summary(
fun.data = mean_cl_normal,
geom = "errorbar",
width = 0.15,
color = "black"
) +
scale_fill_manual(values = treatment_colors) +
labs(
x = "Treatment",
y = "Final percent body-mass loss"
) +
theme_classic() +
theme(legend.position = "none")

11. Publication Figures
11.1 Figure 1: dietary restriction and the energetic trade-off
## 11.1 Figure 1: dietary restriction and energetic constraint
library(dplyr)
library(ggplot2)
library(lme4)
library(lmerTest)
library(emmeans)
library(patchwork)
# ============================================================
# PREPARE DATA
# ============================================================
figure1_weight_data <- diet_final_acclimation %>%
mutate(
Diet_display = case_when(
Treatment == "AdLib" ~ "High",
Treatment %in% c("DR", "DR.IGF1", "DR.IGF2") ~ "Low",
TRUE ~ NA_character_
),
Diet_display = factor(
Diet_display,
levels = c("High", "Low")
)
)
figure1_regeneration_data <- data %>%
mutate(
Diet_display = case_when(
Treatment == "AdLib" ~ "High",
Treatment %in% c("DR", "DR.IGF1", "DR.IGF2") ~ "Low",
TRUE ~ NA_character_
),
Diet_display = factor(
Diet_display,
levels = c("High", "Low")
)
)
# ============================================================
# PANEL A
# DIETARY RESTRICTION INCREASED BODY-MASS LOSS
# ============================================================
panel_1a <- ggplot(
figure1_weight_data,
aes(x = Diet_display, y = Perc_WL)
) +
geom_violin(
fill = "grey75",
color = "black",
trim = FALSE,
scale = "width",
alpha = 0.8
) +
geom_boxplot(
width = 0.12,
outlier.shape = NA,
fill = "white",
color = "black"
) +
geom_jitter(
width = 0.08,
size = 1.8,
shape = 21,
fill = "white",
color = "black",
alpha = 0.8
) +
labs(
title = "Dietary restriction increased weight loss",
x = "Diet",
y = "Percent body-mass loss"
) +
theme_classic(base_size = 12) +
theme(
plot.title = element_text(face = "bold"),
axis.title = element_text(face = "bold"),
axis.text = element_text(face = "bold")
)
# ============================================================
# PANEL B
# DIETARY RESTRICTION REDUCED REGENERATION
# ============================================================
panel_1b <- ggplot(
figure1_regeneration_data,
aes(
x = Week,
y = Perc.Regeneration,
shape = Diet_display,
linetype = Diet_display,
group = Diet_display
)
) +
stat_summary(
fun = mean,
geom = "line",
linewidth = 1.2,
color = "black"
) +
stat_summary(
fun = mean,
geom = "point",
size = 3,
color = "black"
) +
stat_summary(
fun.data = mean_se,
geom = "errorbar",
width = 0.15,
color = "black"
) +
scale_shape_manual(
values = c("High" = 16, "Low" = 17)
) +
scale_linetype_manual(
values = c("High" = "solid", "Low" = "dashed")
) +
labs(
title = "Dietary restriction reduced regeneration",
x = "Week",
y = "Percent regeneration",
shape = "Diet",
linetype = "Diet"
) +
theme_classic(base_size = 12) +
theme(
plot.title = element_text(face = "bold"),
axis.title = element_text(face = "bold"),
axis.text = element_text(face = "bold"),
legend.position = "bottom"
)
# ============================================================
# DATA FOR PANELS C AND D
# NO IGF TREATMENT
# ============================================================
tradeoff_no_igf <- data %>%
filter(
IGF_type == "No_IGF",
!is.na(Perc.WeightLoss),
!is.na(Perc.Regeneration)
)
# ============================================================
# PANEL C
# WEEK 6 RELATIONSHIP BETWEEN WEIGHT LOSS AND REGENERATION
# ============================================================
panel_1c_data <- tradeoff_no_igf %>%
filter(Week == 6)
panel_1c <- ggplot(
panel_1c_data,
aes(
x = Perc.WeightLoss,
y = Perc.Regeneration
)
) +
geom_point(
shape = 21,
fill = "white",
color = "black",
size = 3,
stroke = 0.8,
alpha = 0.9
) +
geom_smooth(
method = "lm",
formula = y ~ x,
se = TRUE,
color = "black",
fill = "grey75",
linewidth = 1.1
) +
labs(
title = "Weight loss constrains regeneration",
subtitle = "Vehicle indviduals at Week 6",
x = "Percent body-mass loss",
y = "Percent regeneration"
) +
theme_classic(base_size = 12) +
theme(
plot.title = element_text(
face = "bold",
size = 14
),
plot.subtitle = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold"
),
axis.text = element_text(
face = "bold"
)
)
# ============================================================
# MODEL FOR PANEL D
# CHANGE IN WEIGHT-LOSS/REGENERATION RELATIONSHIP OVER TIME
# ============================================================
model_tradeoff_no_igf <- lmerTest::lmer(
Perc.Regeneration ~
Week * Perc.WeightLoss +
(1 | Animal_ID),
data = tradeoff_no_igf
)
tradeoff_slopes <- emtrends(
model_tradeoff_no_igf,
~ Week,
var = "Perc.WeightLoss",
at = list(
Week = c(2, 4, 6, 8)
)
)
tradeoff_slopes_df <- as.data.frame(
summary(
tradeoff_slopes,
infer = TRUE
)
) %>%
mutate(
sig_zero = case_when(
p.value < 0.001 ~ "***",
p.value < 0.01 ~ "**",
p.value < 0.05 ~ "*",
p.value < 0.10 ~ "†",
TRUE ~ ""
)
)
# ============================================================
# PANEL D
# ENERGETIC CONSTRAINT STRENGTHENS OVER TIME
# ============================================================
# Estimate the slope of regeneration vs. weight loss
# at Weeks 2, 4, 6, and 8
tradeoff_slopes <- emtrends(
model_tradeoff_no_igf,
~ Week,
var = "Perc.WeightLoss",
at = list(
Week = c(2, 4, 6, 8)
)
)
# Convert to dataframe and add significance symbols
tradeoff_slopes_df <- as.data.frame(
summary(
tradeoff_slopes,
infer = TRUE
)
) %>%
mutate(
sig_zero = case_when(
p.value < 0.001 ~ "***",
p.value < 0.01 ~ "**",
p.value < 0.05 ~ "*",
p.value < 0.10 ~ "†",
TRUE ~ ""
),
# Position significance symbols below each confidence interval
sig_y = lower.CL - 0.04
)
# Make Panel D
panel_1d <- ggplot(
tradeoff_slopes_df,
aes(
x = Week,
y = Perc.WeightLoss.trend
)
) +
# Zero = no relationship between weight loss and regeneration
geom_hline(
yintercept = 0,
linetype = "dashed",
color = "black",
linewidth = 0.7
) +
# 95% confidence intervals
geom_errorbar(
aes(
ymin = lower.CL,
ymax = upper.CL
),
width = 0.18,
linewidth = 0.8,
color = "grey30"
) +
# Estimated slopes
geom_point(
size = 4.5,
color = "grey30"
) +
# Significance symbols
geom_text(
aes(
y = sig_y,
label = sig_zero
),
size = 5,
fontface = "bold",
color = "grey30"
) +
# X axis
scale_x_continuous(
breaks = c(2, 4, 6, 8)
) +
# Y axis extended downward so Week 8 significance
# symbols fit below the confidence interval
scale_y_continuous(
breaks = seq(-0.5, 0.1, by = 0.1),
limits = c(-0.50, 0.15),
labels = scales::number_format(
accuracy = 0.1
),
expand = expansion(
mult = c(0.02, 0.05)
)
) +
labs(
title = "Energetic constraint strengthened over time",
subtitle = "Change in regeneration per 1% increase in weight loss",
x = "Week",
y = "Slope of Regeneration\nvs. Weight Loss"
) +
theme_classic(
base_size = 12
) +
theme(
plot.title = element_text(
face = "bold",
size = 14
),
plot.subtitle = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold"
),
axis.text = element_text(
face = "bold"
),
axis.title.y = element_text(
margin = margin(r = 10)
)
)
panel_1d

# ============================================================
# COMBINE PANELS A-D
# ============================================================
figure_1 <-
(panel_1a + panel_1b) /
(panel_1c + panel_1d) +
plot_layout(
heights = c(1, 1)
) +
plot_annotation(
title = "Dietary Restriction Establishes an Energetic Constraint",
tag_levels = "A"
) &
theme(
plot.tag = element_text(
face = "bold",
size = 20
)
)
figure_1

# ============================================================
# SAVE FIGURE
# ============================================================
ggsave(
filename = "dietary_restriction_energetic_constraint_multiplot.png",
plot = figure_1,
width = 11,
height = 8,
dpi = 600
)
11.1.2 Popout box for Figure 1
# ============================================================
# PANEL C
# WEEK 6 MODEL-BASED POPOUT
# ============================================================
panel_1c_data <- tradeoff_no_igf %>%
filter(Week == 6)
# Prediction grid across observed Week 6 weight-loss values
panel_1c_predictions <- data.frame(
Week = 6,
Perc.WeightLoss = seq(
min(panel_1c_data$Perc.WeightLoss, na.rm = TRUE),
max(panel_1c_data$Perc.WeightLoss, na.rm = TRUE),
length.out = 100
)
)
# Population-level predictions from SAME model used in Panel D
panel_1c_predictions$Predicted_Regeneration <- predict(
model_tradeoff_no_igf,
newdata = panel_1c_predictions,
re.form = NA
)
panel_1c <- ggplot() +
# Individual observed animals
geom_point(
data = panel_1c_data,
aes(
x = Perc.WeightLoss,
y = Perc.Regeneration
),
shape = 21,
fill = "white",
color = "black",
size = 2.7,
stroke = 0.7,
alpha = 0.75
) +
# Model-predicted Week 6 relationship
geom_line(
data = panel_1c_predictions,
aes(
x = Perc.WeightLoss,
y = Predicted_Regeneration
),
color = "black",
linewidth = 1.3
) +
labs(
title = "Relationship at Week 6",
subtitle = "Model prediction with individual observations",
x = "Percent body-mass loss",
y = "Percent regeneration"
) +
theme_classic(base_size = 12) +
theme(
# Entire pop-out is grey90
plot.background = element_rect(
fill = "grey90",
color = NA
),
panel.background = element_rect(
fill = "grey90",
color = NA
),
plot.title = element_text(
face = "bold",
size = 14
),
plot.subtitle = element_text(
face = "bold",
size = 10
),
axis.title = element_text(
face = "bold"
),
axis.text = element_text(
face = "bold"
),
plot.margin = margin(
8, 8, 8, 8
)
)
panel_1c

ggsave(
filename = "Fig1_panelC_week6_popout.png",
plot = panel_1c,
width = 3.8,
height = 5,
units = "in",
dpi = 600,
bg = "white"
)
# ============================================================
# PANEL D
# ENERGETIC CONSTRAINT STRENGTHENS OVER TIME
# ============================================================
# Estimate the slope of regeneration vs. weight loss
# at Weeks 2, 4, 6, and 8
tradeoff_slopes <- emtrends(
model_tradeoff_no_igf,
~ Week,
var = "Perc.WeightLoss",
at = list(
Week = c(2, 4, 6, 8)
)
)
# Convert to dataframe and add significance symbols
tradeoff_slopes_df <- as.data.frame(
summary(
tradeoff_slopes,
infer = TRUE
)
) %>%
mutate(
sig_zero = case_when(
p.value < 0.001 ~ "***",
p.value < 0.01 ~ "**",
p.value < 0.05 ~ "*",
p.value < 0.10 ~ "†",
TRUE ~ ""
),
# Position significance symbols below each confidence interval
sig_y = lower.CL - 0.04
)
# Make Panel D
panel_1d <- ggplot(
tradeoff_slopes_df,
aes(
x = Week,
y = Perc.WeightLoss.trend
)
) +
# ----------------------------------------------------------
# Highlight Week 6
# ----------------------------------------------------------
annotate(
"rect",
xmin = 5.55,
xmax = 6.45,
ymin = -Inf,
ymax = Inf,
fill = "grey90",
color = NA
) +
# Zero = no relationship between weight loss and regeneration
geom_hline(
yintercept = 0,
linetype = "dashed",
color = "black",
linewidth = 0.7
) +
# 95% confidence intervals
geom_errorbar(
aes(
ymin = lower.CL,
ymax = upper.CL
),
width = 0.18,
linewidth = 0.8,
color = "grey30"
) +
# Estimated slopes
geom_point(
size = 4.5,
color = "grey30"
) +
# Significance symbols
geom_text(
aes(
y = sig_y,
label = sig_zero
),
size = 5,
fontface = "bold",
color = "grey30"
) +
# X axis
scale_x_continuous(
breaks = c(2, 4, 6, 8)
) +
# Y axis
scale_y_continuous(
breaks = seq(-0.5, 0.1, by = 0.1),
limits = c(-0.50, 0.15),
labels = scales::number_format(
accuracy = 0.1
),
expand = expansion(
mult = c(0.02, 0.05)
)
) +
labs(
title = "Energetic constraint strengthened over time",
subtitle = "Change in regeneration per 1% increase in weight loss",
x = "Week",
y = "Slope of Regeneration\nvs. Weight Loss"
) +
theme_classic(
base_size = 12
) +
theme(
plot.title = element_text(
face = "bold",
size = 14
),
plot.subtitle = element_text(
face = "bold",
size = 11
),
axis.title = element_text(
face = "bold"
),
axis.text = element_text(
face = "bold"
),
axis.title.y = element_text(
margin = margin(r = 10)
),
# Transparent plotting area
panel.background = element_rect(
fill = "transparent",
color = NA
),
# Transparent area surrounding plot
plot.background = element_rect(
fill = "transparent",
color = NA
)
)
panel_1d_tagged <- panel_1d +
labs(tag = "C") +
theme(
plot.tag = element_text(
face = "bold",
size = 18
),
plot.tag.position = c(0, 1)
)
panel_1d_tagged

ggsave(
filename = "Fig1_panelD_constraint_slopes.png",
plot = panel_1d_tagged,
width = 6,
height = 4,
units = "in",
dpi = 600,
bg = "transparent"
)
11.3 Figure 2A: week-specific rescue slopes
# Prepare plotting data
rescue_plot_data <- week_specific_slopes_df %>%
mutate(
significance = case_when(
IGF_type == "IGF2" & Week == 4 ~ "\u2020",
IGF_type == "IGF2" & Week == 6 ~ "**",
IGF_type == "IGF2" & Week == 8 ~ "***",
TRUE ~ ""
)
)
plot_rescue <- ggplot(
rescue_plot_data,
aes(
x = Week,
y = Perc.WeightLoss.trend,
color = IGF_type
)
) +
# Background shading
annotate(
"rect",
xmin = 5.55,
xmax = 6.45,
ymin = -Inf,
ymax = Inf,
fill = "grey90",
alpha = 0.7
) +
# Zero line
geom_hline(
yintercept = 0,
linetype = "dashed",
color = "black"
) +
# Confidence intervals
geom_errorbar(
aes(ymin = lower.CL, ymax = upper.CL),
width = 0.15,
position = position_dodge(width = 0.25),
linewidth = 0.8
) +
# Point estimates
geom_point(
size = 4,
position = position_dodge(width = 0.25)
) +
# Significance symbols
geom_text(
aes(
y = upper.CL + 0.05,
label = significance
),
position = position_dodge(width = 0.25),
size = 8,
fontface = "bold",
show.legend = FALSE
) +
scale_color_manual(
values = c(
"IGF1" = "#E87722",
"IGF2" = "#0C2340",
"No_IGF" = "grey40"
),
labels = c(
"IGF1" = "IGF1",
"IGF2" = "IGF2",
"No_IGF" = "None"
)
) +
labs(
title = "IGF2 alters the energetic constraint on regeneration",
subtitle = "Relationship between weight loss and regeneration across time",
x = "Week",
y = "Slope of Regeneration vs. Weight Loss"
) +
labs(
color = "IGF Type"
)+
theme_classic(base_size = 12) +
theme(
axis.title = element_text(face = "bold"),
axis.text = element_text(face = "bold"),
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(face = "bold", size = 10),
legend.position = "bottom",
legend.title = element_text(face = "bold")
) +
theme(
plot.background = element_rect(
fill = "transparent",
color = NA
),
panel.background = element_rect(
fill = "transparent",
color = NA
)
)
plot_rescue

ggsave(
filename = "IGF2_energetic_rescue_figure.png",
plot = plot_rescue,
width = 7,
height = 4,
dpi = 600,
bg="transparent"
)
# ============================================================
# WEEK 6 POPOUT
# Raw data + regression lines by supplementation
# ============================================================
week6_popout_data <- data %>%
filter(
Week == 6,
IGF_type %in% c("No_IGF", "IGF1", "IGF2"),
!is.na(Perc.WeightLoss),
!is.na(Perc.Regeneration)
) %>%
mutate(
Supplementation = case_when(
IGF_type == "No_IGF" ~ "None",
IGF_type == "IGF1" ~ "IGF1",
IGF_type == "IGF2" ~ "IGF2"
),
Supplementation = factor(
Supplementation,
levels = c("None", "IGF1", "IGF2")
)
)
week6_popout <- ggplot(
week6_popout_data,
aes(
x = Perc.WeightLoss,
y = Perc.Regeneration,
color = Supplementation
)
) +
# Individual animals
geom_point(
size = 2.5,
alpha = 0.65
) +
# Raw regression lines
geom_smooth(
method = "lm",
formula = y ~ x,
se = FALSE,
linewidth = 1.2
) +
# Match colors in main figure
scale_color_manual(
values = c(
"None" = "grey40",
"IGF1" = "#E66101",
"IGF2" = "#0B1F3A"
)
) +
labs(
title = "Week 6 Pop-Out:",
x = "Percent body-mass loss",
y = "Percent regeneration"
) +
theme_classic(base_size = 11) +
theme(
# Light gray background across entire pop-out
plot.background = element_rect(
fill = "grey90",
color = "grey90",
linewidth = 0.8
),
# Keep plotting area gray as well
panel.background = element_rect(
fill = "grey90",
color = NA
),
plot.title = element_text(
face = "bold",
size = 13,
hjust = 0.5,
margin = margin(b = 2)
),
plot.subtitle = element_text(
face = "plain",
size = 10.5,
hjust = 0.5,
margin = margin(b = 7)
),
axis.title = element_text(
face = "bold",
size = 10
),
axis.text = element_text(
size = 9
),
legend.position = "none",
# Gives the gray box some breathing room
plot.margin = margin(
t = 10,
r = 10,
b = 10,
l = 10
)
)
week6_popout

ggsave(
filename = "week6_popout.png",
plot = week6_popout,
width = 3,
height = 4,
units = "in",
dpi = 600,
bg = "grey90"
)
model_igf_split <- lmer(
Perc.Regeneration ~ Week * Perc.WeightLoss * IGF_type +
(1 | Animal_ID),
data = data
)
# ============================================================
# WEEK 6 MODEL-BASED POPOUT
# Individual observations + predictions from Panel B model
# ============================================================
week6_points <- data %>%
filter(
Week == 6,
IGF_type %in% c("No_IGF", "IGF1", "IGF2"),
!is.na(Perc.WeightLoss),
!is.na(Perc.Regeneration)
) %>%
mutate(
Supplementation = case_when(
IGF_type == "No_IGF" ~ "None",
IGF_type == "IGF1" ~ "IGF1",
IGF_type == "IGF2" ~ "IGF2"
),
Supplementation = factor(
Supplementation,
levels = c("None", "IGF1", "IGF2")
)
)
# Create weight-loss values spanning the observed range
prediction_grid <- expand.grid(
Week = 6,
Perc.WeightLoss = seq(
min(week6_points$Perc.WeightLoss, na.rm = TRUE),
max(week6_points$Perc.WeightLoss, na.rm = TRUE),
length.out = 100
),
IGF_type = c("No_IGF", "IGF1", "IGF2")
)
# Make population-level predictions from the SAME model as Panel B
prediction_grid$Predicted_Regeneration <- predict(
model_igf_split,
newdata = prediction_grid,
re.form = NA
)
prediction_grid <- prediction_grid %>%
mutate(
Supplementation = case_when(
IGF_type == "No_IGF" ~ "None",
IGF_type == "IGF1" ~ "IGF1",
IGF_type == "IGF2" ~ "IGF2"
),
Supplementation = factor(
Supplementation,
levels = c("None", "IGF1", "IGF2")
)
)
week6_popout <- ggplot() +
# Raw individual observations
geom_point(
data = week6_points,
aes(
x = Perc.WeightLoss,
y = Perc.Regeneration,
color = Supplementation
),
size = 2.3,
alpha = 0.55
) +
# MODEL-PREDICTED relationships
geom_line(
data = prediction_grid,
aes(
x = Perc.WeightLoss,
y = Predicted_Regeneration,
color = Supplementation
),
linewidth = 1.3
) +
scale_color_manual(
values = c(
"None" = "grey40",
"IGF1" = "#E66101",
"IGF2" = "#0B1F3A"
)
) +
labs(
title = "Week 6 Pop-out",
subtitle = "Model-Predicted Relationships",
x = "Percent Body-Mass Loss",
y = "Percent Regeneration"
) +
theme_classic(base_size = 11) +
theme(
plot.background = element_rect(
fill = "grey92",
color = NA
),
panel.background = element_rect(
fill = "grey92",
color = NA
),
plot.title = element_text(
face = "bold",
size = 11,
hjust = 0.5
),
axis.title = element_text(
face = "bold",
size = 9
),
axis.text = element_text(
size = 8
),
legend.position = "none",
plot.margin = margin(8, 8, 8, 8)
)
week6_popout

ggsave(
filename = "week6_popout.png",
plot = week6_popout,
width = 3,
height = 4,
units = "in",
dpi = 600,
bg = "grey90"
)
# ============================================================
# WEIGHT LOSS THROUGHOUT REGENERATION
# Individual trajectories + treatment means
# ============================================================
# ============================================================
# PRE-AUTOTOMY PERIOD
# Include ALL negative weeks from diet dataset
# ============================================================
pre_autotomy <- diet %>%
filter(
Week < 0,
!is.na(Perc_WL)
) %>%
dplyr::select(
Animal_ID,
Week,
Perc.WeightLoss = Perc_WL
) %>%
# Add IGF assignment from regeneration dataset
left_join(
data %>%
dplyr::select(Animal_ID, IGF_type) %>%
distinct(),
by = "Animal_ID"
)
# ============================================================
# REGENERATION PERIOD
# ============================================================
regen_weight <- data %>%
filter(
Week >= 0,
IGF_type %in% c("No_IGF", "IGF1", "IGF2"),
!is.na(Perc.WeightLoss)
) %>%
dplyr::select(
Animal_ID,
Week,
Perc.WeightLoss,
IGF_type
)
# ============================================================
# COMBINE PRE-AUTOTOMY + REGENERATION
# ============================================================
weight_trajectory_data <- bind_rows(
pre_autotomy,
regen_weight
) %>%
filter(
IGF_type %in% c("No_IGF", "IGF1", "IGF2")
) %>%
mutate(
Supplementation = case_when(
IGF_type == "No_IGF" ~ "None",
IGF_type == "IGF1" ~ "IGF1",
IGF_type == "IGF2" ~ "IGF2"
),
Supplementation = factor(
Supplementation,
levels = c("None", "IGF1", "IGF2")
)
)
body_mass_plot <- ggplot(
weight_trajectory_data,
aes(
x = Week,
y = Perc.WeightLoss,
color = Supplementation
)
) +
# Individual animal trajectories
geom_line(
aes(group = Animal_ID),
alpha = 0.12,
linewidth = 0.5
) +
# Treatment means
stat_summary(
aes(group = Supplementation),
fun = mean,
geom = "line",
linewidth = 1.2
) +
# Mean points
stat_summary(
aes(group = Supplementation),
fun = mean,
geom = "point",
size = 3
) +
# 0 = original body mass
geom_hline(
yintercept = 0,
linetype = "dashed",
linewidth = 0.7,
color = "grey40"
) +
scale_color_manual(
values = c(
"None" = "grey40",
"IGF1" = "#E66101",
"IGF2" = "#0B1F3A"
)
) +
scale_x_continuous(
breaks = c(-4, -2, -1, 2, 4, 6, 8),
labels = c("-4", "-2", "-1", "2", "4", "6", "8")
) +
coord_cartesian(
ylim = c(-30, 50)
)+
geom_vline(
xintercept = 0,
linetype = "dotted",
linewidth = 0.7,
color = "grey40"
) +
labs(
title = "Weight loss remains stable",
subtitle = "Individual trajectories and treatment means",
x = "Week",
y = "Percent Weight Loss",
color = "Supplementation"
) +
annotate(
"label",
x = 1.5,
y = 47,
label = "Autotomy",
fontface = "bold",
size = 5,
color = "#0B1F3A", # text color
fill = "white", # box fill
label.size = 0.7, # border thickness
label.padding = unit(0.25, "lines"),
hjust = 1
) +
theme_classic(base_size = 12) +
theme(
plot.title = element_text(
face = "bold",
size = 14
),
plot.subtitle = element_text(
size = 10.5,
margin = margin(b = 7)
),
axis.title = element_text(
face = "bold",
size = 11
),
axis.text = element_text(
size = 10
),
legend.position = "bottom",
legend.title = element_text(face = "bold"),
plot.margin = margin(
t = 8,
r = 8,
b = 8,
l = 8
)
)
body_mass_plot

ggsave(
filename = "Fig2_stableWL.png",
plot = body_mass_plot,
width = 6,
height = 4.5,
units = "in",
dpi = 600,
bg = "white"
)
#12. Initial Investment Modeling
# Extract energetic condition immediately before tail loss
initial_condition <- diet %>%
filter(Week == -1) %>%
dplyr::select(
Animal_ID,
Initial_WeightLoss = Perc_WL
) %>%
distinct()
summary(initial_condition$Initial_WeightLoss)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -17.028 1.857 6.059 6.101 11.211 27.965 7
nrow(initial_condition)
## [1] 76
regen_initial <- data %>%
filter(Week %in% c(2, 4, 6, 8)) %>%
left_join(initial_condition, by = "Animal_ID")
# Check the join
sum(is.na(regen_initial$Initial_WeightLoss))
## [1] 28
length(unique(regen_initial$Animal_ID))
## [1] 76
model_initial_condition <- lmer(
Perc.Regeneration ~ Week * Initial_WeightLoss +
(1 | Animal_ID),
data = regen_initial
)
summary(model_initial_condition)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Perc.Regeneration ~ Week * Initial_WeightLoss + (1 | Animal_ID)
## Data: regen_initial
##
## REML criterion at convergence: 1404.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -2.85976 -0.54156 0.06924 0.60861 2.75144
##
## Random effects:
## Groups Name Variance Std.Dev.
## Animal_ID (Intercept) 20.68 4.548
## Residual 28.17 5.308
## Number of obs: 214, groups: Animal_ID, 64
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) -6.39141 1.32520 190.40917 -4.823 2.89e-06 ***
## Week 4.68879 0.21895 161.85585 21.415 < 2e-16 ***
## Initial_WeightLoss 0.01689 0.15246 190.36370 0.111 0.912
## Week:Initial_WeightLoss -0.03805 0.02530 162.91730 -1.504 0.134
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) Week Int_WL
## Week -0.750
## Intl_WghtLs -0.627 0.465
## Wk:Intl_WgL 0.463 -0.612 -0.748
anova(model_initial_condition)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## Week 12919.6 12919.6 1 161.86 458.5876 <2e-16 ***
## Initial_WeightLoss 0.3 0.3 1 190.36 0.0123 0.9119
## Week:Initial_WeightLoss 63.7 63.7 1 162.92 2.2623 0.1345
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
initial_slopes <- emtrends(
model_initial_condition,
~ Week,
var = "Initial_WeightLoss",
at = list(Week = c(2, 4, 6, 8))
)
summary(initial_slopes, infer = TRUE)
## Week Initial_WeightLoss.trend SE df lower.CL upper.CL t.ratio p.value
## 2 -0.0592 0.119 112.4 -0.296 0.17738 -0.496 0.6210
## 4 -0.1353 0.102 62.9 -0.339 0.06846 -1.327 0.1893
## 6 -0.2114 0.108 74.9 -0.427 0.00377 -1.957 0.0540
## 8 -0.2875 0.134 141.7 -0.553 -0.02176 -2.139 0.0342
##
## Degrees-of-freedom method: kenward-roger
## Confidence level used: 0.95
The relationship between energetic condition and regeneration emerged
over time and differed among treatment groups. Although animals largely
maintained body mass during the regeneration period, vehicle-treated
individuals with greater body-mass loss exhibited progressively lower
cumulative regeneration, with this relationship becoming statistically
detectable by week 6 and strengthening through week 8. In contrast, this
relationship was altered by IGF2 treatment. Body-mass loss measured
immediately before tail loss did not independently predict subsequent
regeneration after accounting for original tail length, indicating that
the later relationship between energetic condition and regeneration was
not simply explained by differences in body condition at the onset of
regeneration.
13. After IGF injection/autotomy, did IGF2 animals change in mass
differently over time than IGF1 or Low Vehicle animals?
# ============================================================
# DOES IGF2 ALTER MASS FOLLOWING AUTOTOMY / INJECTION?
# Low-diet animals only
# ============================================================
library(dplyr)
library(lmerTest)
library(emmeans)
# Get each animal's mass immediately before autotomy/injection
pre_autotomy_mass <- diet %>%
filter(Week == -1) %>%
dplyr::select(
Animal_ID,
PreAutotomy_Mass = Mass
) %>%
distinct()
# Post-autotomy observations for the three low-diet groups
post_igf_mass <- data %>%
filter(
Treatment %in% c("DR", "DR.IGF1", "DR.IGF2"),
Week %in% c(2, 4, 6, 8),
!is.na(Mass)
) %>%
left_join(
pre_autotomy_mass,
by = "Animal_ID"
) %>%
mutate(
# Absolute change from immediately before autotomy
Mass_Change = Mass - PreAutotomy_Mass,
# Percent change from immediately before autotomy
Percent_Mass_Change =
((Mass - PreAutotomy_Mass) / PreAutotomy_Mass) * 100,
Supplementation = case_when(
Treatment == "DR" ~ "Vehicle",
Treatment == "DR.IGF1" ~ "IGF1",
Treatment == "DR.IGF2" ~ "IGF2"
),
Supplementation = factor(
Supplementation,
levels = c("Vehicle", "IGF1", "IGF2")
)
)
post_igf_mass %>%
group_by(Supplementation, Week) %>%
summarise(
n = n(),
mean_change = mean(Percent_Mass_Change, na.rm = TRUE),
sd_change = sd(Percent_Mass_Change, na.rm = TRUE),
.groups = "drop"
)
## # A tibble: 12 × 5
## Supplementation Week n mean_change sd_change
## <fct> <int> <int> <dbl> <dbl>
## 1 Vehicle 2 13 -10.3 4.90
## 2 Vehicle 4 13 -14.9 6.63
## 3 Vehicle 6 10 -16.9 8.90
## 4 Vehicle 8 7 -10.3 8.29
## 5 IGF1 2 16 -9.00 7.40
## 6 IGF1 4 14 -10.9 5.76
## 7 IGF1 6 12 -9.17 5.85
## 8 IGF1 8 11 -6.04 8.63
## 9 IGF2 2 17 -11.9 7.04
## 10 IGF2 4 17 -15.9 6.82
## 11 IGF2 6 16 -16.0 9.22
## 12 IGF2 8 11 -7.86 6.78
model_post_igf_mass <- lmer(
Percent_Mass_Change ~
Week * Supplementation +
(1 | Animal_ID),
data = post_igf_mass
)
summary(model_post_igf_mass)
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: Percent_Mass_Change ~ Week * Supplementation + (1 | Animal_ID)
## Data: post_igf_mass
##
## REML criterion at convergence: 1025.9
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -2.4911 -0.4713 -0.0123 0.5277 3.8203
##
## Random effects:
## Groups Name Variance Std.Dev.
## Animal_ID (Intercept) 29.63 5.444
## Residual 28.39 5.328
## Number of obs: 157, groups: Animal_ID, 46
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) -11.1939 2.4593 123.4563 -4.552 1.26e-05 ***
## Week -0.4673 0.4015 115.4443 -1.164 0.247
## SupplementationIGF1 0.2233 3.2914 122.5491 0.068 0.946
## SupplementationIGF2 -3.5735 3.2464 122.4341 -1.101 0.273
## Week:SupplementationIGF1 0.8454 0.5271 115.8798 1.604 0.112
## Week:SupplementationIGF2 0.7516 0.5175 113.9692 1.452 0.149
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) Week SpIGF1 SpIGF2 W:SIGF1
## Week -0.712
## SpplmntIGF1 -0.747 0.532
## SpplmntIGF2 -0.758 0.540 0.566
## Wk:SpplIGF1 0.543 -0.762 -0.705 -0.411
## Wk:SpplIGF2 0.553 -0.776 -0.413 -0.712 0.591
anova(
model_post_igf_mass,
type = 3
)
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## Week 2.808 2.808 1 114.73 0.0989 0.7537
## Supplementation 54.332 27.166 2 122.03 0.9570 0.3869
## Week:Supplementation 84.117 42.058 2 114.64 1.4816 0.2316
mass_slopes <- emtrends(
model_post_igf_mass,
~ Supplementation,
var = "Week"
)
mass_slopes
## Supplementation Week.trend SE df lower.CL upper.CL
## Vehicle -0.467 0.402 115 -1.264 0.330
## IGF1 0.378 0.342 116 -0.300 1.056
## IGF2 0.284 0.327 112 -0.363 0.932
##
## Degrees-of-freedom method: kenward-roger
## Confidence level used: 0.95
pairs(
mass_slopes,
adjust = "tukey"
)
## contrast estimate SE df t.ratio p.value
## Vehicle - IGF1 -0.8454 0.528 116 -1.601 0.2495
## Vehicle - IGF2 -0.7516 0.518 114 -1.450 0.3189
## IGF1 - IGF2 0.0937 0.473 114 0.198 0.9786
##
## Degrees-of-freedom method: kenward-roger
## P value adjustment: tukey method for comparing a family of 3 estimates
mass_slopes <- emtrends(
model_post_igf_mass,
~ Supplementation,
var = "Week"
)
mass_slopes
## Supplementation Week.trend SE df lower.CL upper.CL
## Vehicle -0.467 0.402 115 -1.264 0.330
## IGF1 0.378 0.342 116 -0.300 1.056
## IGF2 0.284 0.327 112 -0.363 0.932
##
## Degrees-of-freedom method: kenward-roger
## Confidence level used: 0.95
pairs(mass_slopes, adjust = "tukey")
## contrast estimate SE df t.ratio p.value
## Vehicle - IGF1 -0.8454 0.528 116 -1.601 0.2495
## Vehicle - IGF2 -0.7516 0.518 114 -1.450 0.3189
## IGF1 - IGF2 0.0937 0.473 114 0.198 0.9786
##
## Degrees-of-freedom method: kenward-roger
## P value adjustment: tukey method for comparing a family of 3 estimates
mass_slopes
## Supplementation Week.trend SE df lower.CL upper.CL
## Vehicle -0.467 0.402 115 -1.264 0.330
## IGF1 0.378 0.342 116 -0.300 1.056
## IGF2 0.284 0.327 112 -0.363 0.932
##
## Degrees-of-freedom method: kenward-roger
## Confidence level used: 0.95
test(mass_slopes)
## Supplementation Week.trend SE df t.ratio p.value
## Vehicle -0.467 0.402 115 -1.162 0.2478
## IGF1 0.378 0.342 116 1.105 0.2716
## IGF2 0.284 0.327 112 0.870 0.3862
##
## Degrees-of-freedom method: kenward-roger