Last updated: 2025-12-18
Checks: 5 2
Knit directory: SkinOptics/
This reproducible R Markdown analysis was created with workflowr (version 1.7.1). The Checks tab describes the reproducibility checks that were applied when the results were created. The Past versions tab lists the development history.
The R Markdown file has unstaged changes. To know which version of
the R Markdown file created these results, you’ll want to first commit
it to the Git repo. If you’re still working on the analysis, you can
ignore this warning. When you’re finished, you can run
wflow_publish to commit the R Markdown file and build the
HTML.
Great job! The global environment was empty. Objects defined in the global environment can affect the analysis in your R Markdown file in unknown ways. For reproduciblity it’s best to always run the code in an empty environment.
The command set.seed(20251211) was run prior to running
the code in the R Markdown file. Setting a seed ensures that any results
that rely on randomness, e.g. subsampling or permutations, are
reproducible.
Great job! Recording the operating system, R version, and package versions is critical for reproducibility.
To ensure reproducibility of the results, delete the cache directory
JID_SkinOptics_cache and re-run the analysis. To have
workflowr automatically delete the cache directory prior to building the
file, set delete_cache = TRUE when running
wflow_build() or wflow_publish().
Great job! Using relative paths to the files within your workflowr project makes it easier to run your code on other machines.
Great! You are using Git for version control. Tracking code development and connecting the code version to the results is critical for reproducibility.
The results in this page were generated with repository version 777c6d5. See the Past versions tab to see a history of the changes made to the R Markdown and HTML files.
Note that you need to be careful to ensure that all relevant files for
the analysis have been committed to Git prior to generating the results
(you can use wflow_publish or
wflow_git_commit). workflowr only checks the R Markdown
file, but you know if there are other scripts or data files that it
depends on. Below is the status of the Git repository when the results
were generated:
Ignored files:
Ignored: .DS_Store
Ignored: analysis/skin-map_cache/
Ignored: data/worldclim/
Untracked files:
Untracked: output/delta_comparison_log.pdf
Untracked: output/face_ei_face_mi_comparison.pdf
Untracked: output/mi_distribution.png
Untracked: output/palm_ei_face_mi_comparison.pdf
Untracked: output/peak_valley_distribution_comparison.pdf
Untracked: output/peak_valley_distribution_composite.pdf
Untracked: output/predicted_lines_peakvalley_delta.pdf
Untracked: output/predicted_lines_reflectance_delta.pdf
Unstaged changes:
Modified: analysis/JID_SkinOptics.Rmd
Deleted: output/README.md
Modified: output/absorbance_derivative_face.pdf
Modified: output/absorbance_derivative_palm.pdf
Modified: output/absorbance_derivative_palm_face.pdf
Deleted: output/absorbance_mi_sd.pdf
Modified: output/absorbance_mi_sd_log.pdf
Modified: output/composite_reflectance_derivatives.pdf
Deleted: output/ei_mi_correlation.pdf
Modified: output/ei_sd_mi_correlation.pdf
Deleted: output/face_ei_face_mi_correlation.pdf
Deleted: output/face_ei_face_mi_log.pdf
Deleted: output/facepalm_ei_mi_correlation.pdf
Modified: output/heatmap.pdf
Modified: output/mi_distribution.pdf
Deleted: output/palm_ei_face_mi_correlation.pdf
Deleted: output/palm_ei_face_mi_log.pdf
Modified: output/palm_ei_face_mi_sd_correlation.pdf
Deleted: output/peak_valley_delta_vs_mi.pdf
Modified: output/peak_valley_delta_vs_mi_log.pdf
Deleted: output/peak_valley_scatter.pdf
Modified: output/peak_valley_value_distribution.pdf
Deleted: output/peak_valley_value_vs_mi.pdf
Modified: output/peak_valley_value_vs_mi_log.pdf
Modified: output/peak_valley_wavelength_distribution.pdf
Deleted: output/peak_valley_wavelength_vs_mi.pdf
Modified: output/peak_valley_wavelength_vs_mi_log.pdf
Modified: output/reflectance_delta_vs_mi.pdf
Modified: output/reflectance_delta_vs_mi_log.pdf
Modified: output/reflectance_derivative_face.pdf
Modified: output/reflectance_derivative_palm.pdf
Modified: output/reflectance_derivative_palm_face.pdf
Deleted: output/reflectance_derivative_palmface.pdf
Modified: output/reflectance_face.pdf
Deleted: output/reflectance_mi_sd.pdf
Modified: output/reflectance_mi_sd_log.pdf
Deleted: output/reflectance_mi_sd_regression.pdf
Modified: output/reflectance_palm.pdf
Modified: output/reflectance_palm_face.pdf
Note that any generated files, e.g. HTML, png, CSS, etc., are not included in this status report because it is ok for generated content to have uncommitted changes.
These are the previous versions of the repository in which changes were
made to the R Markdown (analysis/JID_SkinOptics.Rmd) and
HTML (docs/JID_SkinOptics.html) files. If you’ve configured
a remote Git repository (see ?wflow_git_remote), click on
the hyperlinks in the table below to view the files as they were in that
past version.
| File | Version | Author | Date | Message |
|---|---|---|---|---|
| Rmd | 777c6d5 | tinalasisi | 2025-12-18 | Fixed stats |
| html | 777c6d5 | tinalasisi | 2025-12-18 | Fixed stats |
| Rmd | 243e344 | tinalasisi | 2025-12-18 | Fixed the regressions |
| html | 243e344 | tinalasisi | 2025-12-18 | Fixed the regressions |
| Rmd | c4b2199 | tinalasisi | 2025-12-18 | Added statistical tests to log-relationships |
| html | c4b2199 | tinalasisi | 2025-12-18 | Added statistical tests to log-relationships |
| Rmd | 40b4375 | tinalasisi | 2025-12-18 | updates to tests |
| html | 40b4375 | tinalasisi | 2025-12-18 | updates to tests |
| Rmd | 90b5102 | tinalasisi | 2025-12-18 | Revise Skin Optics analysis: improved deduplication, plotting, and reproducibility |
| html | 90b5102 | tinalasisi | 2025-12-18 | Revise Skin Optics analysis: improved deduplication, plotting, and reproducibility |
| html | 9956d2d | Junhui He | 2025-12-17 | Build site. |
| Rmd | a6f7dc4 | Junhui He | 2025-12-17 | update JID_SkinOptics.Rmd |
| html | 32c3e8f | Junhui He | 2025-12-11 | Rebuild site to apply navbar layout |
| html | b2cbe44 | Junhui He | 2025-12-11 | Build site. |
| Rmd | df71367 | Junhui He | 2025-12-11 | modify face site |
| html | d98f12d | Junhui He | 2025-12-11 | Build site. |
| Rmd | 2fc3d03 | Junhui He | 2025-12-11 | add correlation analysis |
| html | 81580b5 | Junhui He | 2025-12-11 | build workflowr |
| Rmd | e11deee | Junhui He | 2025-12-11 | calculate EI |
| html | e11deee | Junhui He | 2025-12-11 | calculate EI |
| Rmd | 53d4f9c | Junhui He | 2025-12-11 | create SkinOptics |
| html | 53d4f9c | Junhui He | 2025-12-11 | create SkinOptics |
Melanin index (MI) is calculated from skin reflectance at 680 nm, where \(R_{680}\) is the measured reflectance percentage (0-100):
Erythema index (EI) is calculated as: \[EI = 100 \times \log_{10}\left(\frac{R_{680}}{(R_{550} + R_{560})/2}\right)\] where \(R_{550}\), \(R_{560}\), and \(R_{680}\) are the reflectance percentages at 550 nm, 560 nm, and 680 nm, respectively.
EI variability is measured by the standard deviation of EIs within a sliding window of MI values. The window size is set to 20 MI units, and the step size is 1 MI unit.
FACE site refers to Forehead or Cheek, while PALM site refers to the palm of the hand.
Representative FACE MI:
First derivatives of skin spectra are estimated using local polynomial regression with bandwidth selected by the dpill function, scaled by a factor of 0.7.
Eumelanin class are defined based on melanin index ranges as follows:
The pdf files generated in this analysis are saved in the “output” directory.
Face readings before deduplication: 4603
Unique individuals with face readings: 2102
Face readings after deduplication: 2102
Palm readings before deduplication: 776
Unique individuals with palm readings: 776
Palm readings after deduplication: 776
Final data summary:
Face: n = 2101 | Unique individuals: 2101
Palm: n = 776 | Unique individuals: 776
Combined: n = 2877


| Eumelanin class | Number of subjects |
|---|---|
| Low | 77 |
| Intermediate low | 1800 |
| Intermediate | 191 |
| Intermediate high | 30 |
| High | 3 |
| Eumelanin class | Number of subjects |
|---|---|
| Low | 127 |
| Intermediate low | 621 |
| Intermediate | 27 |
| Intermediate high | 1 |







A log-log regression tests for a power-law relationship between derivative variability and melanin content. The slope in log-log space represents the exponent of this power-law relationship.
=== Log-log regression: log(sd_ref) ~ log(mi) - FACE ===
Call:
lm(formula = log(sd_ref) ~ log(mi), data = sd_face)
Residuals:
Min 1Q Median 3Q Max
-0.80045 -0.14091 0.00135 0.13879 0.78775
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.35968 0.06520 36.19 <2e-16 ***
log(mi) -1.32148 0.01813 -72.89 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.2134 on 2099 degrees of freedom
Multiple R-squared: 0.7168, Adjusted R-squared: 0.7166
F-statistic: 5312 on 1 and 2099 DF, p-value: < 2.2e-16
=== Log-log regression: log(sd_ref) ~ log(mi) - PALM ===
Call:
lm(formula = log(sd_ref) ~ log(mi), data = sd_palm)
Residuals:
Min 1Q Median 3Q Max
-0.81944 -0.10556 0.01225 0.13604 0.49637
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.46811 0.10826 13.56 <2e-16 ***
log(mi) -0.99743 0.03117 -32.00 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1958 on 774 degrees of freedom
Multiple R-squared: 0.5695, Adjusted R-squared: 0.569
F-statistic: 1024 on 1 and 774 DF, p-value: < 2.2e-16

For each individual spectrum, we identify the peak (maximum) and valley (minimum) of the first derivative within the 500-650 nm wavelength range. This range captures the hemoglobin absorption features.
Face derivative peak/valley summary (500-650 nm):
Peak wavelength - Mean: 593.4 SD: 8.8
Valley wavelength - Mean: 530.1 SD: 11.2
Palm derivative peak/valley summary (500-650 nm):
Peak wavelength - Mean: 591.2 SD: 3.2
Valley wavelength - Mean: 529.8 SD: 1.6
This analysis compares derivative valley and peak wavelengths and values between forehead/cheek and palm using t-tests to determine if differences are statistically significant.
The differences in peak and valley wavelengths and values between face
and palm sites are not statistically significant.
Log-log regression tests whether the amplitude of derivative peak and valley values follow a power-law relationship with melanin content. Note that valley values are negative, so we use absolute values for the log transformation.
=== Log-log: log(peak_value) ~ log(mi) - FACE ===
Call:
lm(formula = log(peak_value) ~ log(mi), data = peak_face_pos)
Residuals:
Min 1Q Median 3Q Max
-0.56211 -0.10731 0.00531 0.10700 0.64675
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 4.16190 0.04877 85.33 <2e-16 ***
log(mi) -1.44831 0.01356 -106.78 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1597 on 2099 degrees of freedom
Multiple R-squared: 0.8445, Adjusted R-squared: 0.8445
F-statistic: 1.14e+04 on 1 and 2099 DF, p-value: < 2.2e-16
=== Log-log: log(peak_value) ~ log(mi) - PALM ===
Call:
lm(formula = log(peak_value) ~ log(mi), data = peak_palm_pos)
Residuals:
Min 1Q Median 3Q Max
-0.67116 -0.09900 0.00523 0.11279 0.45887
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.26390 0.09073 24.95 <2e-16 ***
log(mi) -0.87565 0.02612 -33.52 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1641 on 774 degrees of freedom
Multiple R-squared: 0.5921, Adjusted R-squared: 0.5916
F-statistic: 1124 on 1 and 774 DF, p-value: < 2.2e-16
=== Log-log: log(|valley_value|) ~ log(mi) - FACE ===
Call:
lm(formula = log(abs(valley_value)) ~ log(mi), data = valley_face_neg)
Residuals:
Min 1Q Median 3Q Max
-6.9436 -0.4587 0.2040 0.7062 2.0568
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.9428 0.6474 10.72 <2e-16 ***
log(mi) -3.0538 0.1871 -16.32 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 1.036 on 1072 degrees of freedom
Multiple R-squared: 0.199, Adjusted R-squared: 0.1982
F-statistic: 266.3 on 1 and 1072 DF, p-value: < 2.2e-16
=== Log-log: log(|valley_value|) ~ log(mi) - PALM ===
Call:
lm(formula = log(abs(valley_value)) ~ log(mi), data = valley_palm_neg)
Residuals:
Min 1Q Median 3Q Max
-5.1830 -0.1340 0.1721 0.3944 0.9343
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.1397 0.4242 0.329 0.742
log(mi) -0.7549 0.1230 -6.139 1.36e-09 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.6842 on 730 degrees of freedom
Multiple R-squared: 0.04909, Adjusted R-squared: 0.04779
F-statistic: 37.69 on 1 and 730 DF, p-value: 1.362e-09

The delta represents the amplitude of the hemoglobin absorption feature in the derivative spectrum - the difference between the peak and valley values.
Delta (peak - valley) summary:
Face:
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.04004 0.27772 0.37771 0.39182 0.49500 0.93954
Palm:
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.1015 0.4844 0.5746 0.5692 0.6605 0.9887
=== FACE: Delta (peak - valley) vs Melanin Index ===
Call:
lm(formula = delta ~ mi, data = face_peak_valley)
Residuals:
Min 1Q Median 3Q Max
-0.27745 -0.07247 -0.01447 0.05338 0.47412
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.8172622 0.0081496 100.28 <2e-16 ***
mi -0.0113627 0.0002086 -54.48 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1069 on 2099 degrees of freedom
Multiple R-squared: 0.5858, Adjusted R-squared: 0.5856
F-statistic: 2968 on 1 and 2099 DF, p-value: < 2.2e-16
=== PALM: Delta (peak - valley) vs Melanin Index ===
Call:
lm(formula = delta ~ mi, data = palm_peak_valley)
Residuals:
Min 1Q Median 3Q Max
-0.282128 -0.069668 -0.003611 0.075198 0.314928
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.0186942 0.0161829 62.95 <2e-16 ***
mi -0.0136839 0.0004794 -28.54 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1038 on 774 degrees of freedom
Multiple R-squared: 0.5128, Adjusted R-squared: 0.5122
F-statistic: 814.6 on 1 and 774 DF, p-value: < 2.2e-16
The delta (peak minus valley) represents the amplitude of the hemoglobin absorption feature in the first derivative. Log-log regression tests whether this amplitude follows a power-law relationship with melanin content.
=== Log-log regression: log(delta) ~ log(mi) - FACE ===
Call:
lm(formula = log(delta) ~ log(mi), data = delta_face)
Residuals:
Min 1Q Median 3Q Max
-0.89324 -0.15612 0.00565 0.15903 0.79202
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.20782 0.07044 73.93 <2e-16 ***
log(mi) -1.74330 0.01959 -89.00 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.2306 on 2099 degrees of freedom
Multiple R-squared: 0.7905, Adjusted R-squared: 0.7904
F-statistic: 7921 on 1 and 2099 DF, p-value: < 2.2e-16
=== Log-log regression: log(delta) ~ log(mi) - PALM ===
Call:
lm(formula = log(delta) ~ log(mi), data = delta_palm)
Residuals:
Min 1Q Median 3Q Max
-0.94014 -0.11438 0.02426 0.15211 0.53171
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.8407 0.1233 23.04 <2e-16 ***
log(mi) -0.9945 0.0355 -28.02 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.223 on 774 degrees of freedom
Multiple R-squared: 0.5035, Adjusted R-squared: 0.5029
F-statistic: 784.9 on 1 and 774 DF, p-value: < 2.2e-16
This log-log regression tests for a power-law relationship between absorbance derivative variability and melanin content.
=== Log-log regression: log(sd_abs) ~ log(mi) - FACE ===
Call:
lm(formula = log(sd_abs) ~ log(mi), data = sd_face)
Residuals:
Min 1Q Median 3Q Max
-0.85684 -0.18033 -0.01627 0.13516 1.14607
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -4.23656 0.08862 -47.81 <2e-16 ***
log(mi) -0.61138 0.02464 -24.81 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.2901 on 2099 degrees of freedom
Multiple R-squared: 0.2267, Adjusted R-squared: 0.2264
F-statistic: 615.5 on 1 and 2099 DF, p-value: < 2.2e-16
=== Log-log regression: log(sd_abs) ~ log(mi) - PALM ===
Call:
lm(formula = log(sd_abs) ~ log(mi), data = sd_palm)
Residuals:
Min 1Q Median 3Q Max
-1.13969 -0.11919 0.00882 0.14246 0.72193
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -5.12360 0.11652 -43.974 <2e-16 ***
log(mi) -0.28220 0.03355 -8.412 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.2107 on 774 degrees of freedom
Multiple R-squared: 0.08377, Adjusted R-squared: 0.08259
F-statistic: 70.77 on 1 and 774 DF, p-value: < 2.2e-16

The erythema index is based on the ratio of reflectance at 680 nm to the average reflectance at 550-560 nm (approximating 555 nm). Here we examine the raw reflectance difference (delta) between these wavelengths as a function of melanin index.
=== Delta (R680 - R555_approx) summary ===
# A tibble: 2 × 7
site mean_delta sd_delta min_delta max_delta mean_R680 mean_R555
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Forehead/Cheek 21.9 4.72 4.42 37.2 43.4 21.5
2 Palm 21.1 4.04 8.42 33.9 47.6 26.6
Log-log regression tests whether the reflectance difference between 680 nm and ~555 nm follows a power-law relationship with melanin content. Note: only positive delta values can be log-transformed.
Face: 2101 of 2101 have positive delta
Palm: 776 of 776 have positive delta
=== Log-log regression: log(ref_delta) ~ log(mi) - FACE ===
Call:
lm(formula = log(ref_delta) ~ log(mi), data = delta_face_pos)
Residuals:
Min 1Q Median 3Q Max
-0.72504 -0.07492 0.01592 0.09346 0.36331
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.97324 0.04102 145.62 <2e-16 ***
log(mi) -0.81198 0.01141 -71.18 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1343 on 2099 degrees of freedom
Multiple R-squared: 0.7071, Adjusted R-squared: 0.7069
F-statistic: 5067 on 1 and 2099 DF, p-value: < 2.2e-16
=== Log-log regression: log(ref_delta) ~ log(mi) - PALM ===
Call:
lm(formula = log(ref_delta) ~ log(mi), data = delta_palm_pos)
Residuals:
Min 1Q Median 3Q Max
-0.40429 -0.09321 0.00782 0.09911 0.40584
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.11102 0.07690 66.46 <2e-16 ***
log(mi) -0.60078 0.02214 -27.13 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1391 on 774 degrees of freedom
Multiple R-squared: 0.4875, Adjusted R-squared: 0.4868
F-statistic: 736.2 on 1 and 774 DF, p-value: < 2.2e-16

| Version | Author | Date |
|---|---|---|
| 777c6d5 | tinalasisi | 2025-12-18 |
We use mixed-effects models to test whether the relationship between melanin index and delta values differs by body site, accounting for repeated measures within individuals.
We tested whether anatomical site (forehead/cheek vs palm) modifies the log–log relationship between melanin index (MI) and (i) peak–valley derivative delta and (ii) reflectance delta (R680–R555), using linear mixed-effects models with a random intercept for subject. For each outcome, we compared a main-effects model (log_delta ~ log_mi + bodysite) to an interaction model (log_delta ~ log_mi * bodysite). A significant likelihood ratio test (LRT) indicates site-specific scaling (different slopes).
=== Peak-Valley Delta: Testing body site effect ===
Peak–valley derivative Δ: LRT comparing interaction vs main-effects model: χ²(1) = 285.11, p < 2.2e-16
=== Reflectance Delta (R680-R555): Testing body site effect ===
Reflectance Δ (R680–R555): LRT comparing interaction vs main-effects model: χ²(1) = 90.22, p < 2.2e-16
Anatomical site significantly modified the MI–Δ relationship for both peak–valley derivative Δ and reflectance Δ (LRT comparing interaction vs main-effects models; see output above), indicating site-specific scaling rather than a simple constant offset.


Comparing linear and log-log regressions to test which model better fits the relationship between face erythema index and face melanin content.
=== Linear regression: face_ei ~ face_mi ===
Call:
lm(formula = ei ~ mi, data = face_spectrum)
Residuals:
Min 1Q Median 3Q Max
-15.5732 -3.6643 -0.1162 3.5673 22.7126
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 25.08333 0.40679 61.66 <2e-16 ***
mi 0.16625 0.01041 15.97 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 5.337 on 2099 degrees of freedom
Multiple R-squared: 0.1083, Adjusted R-squared: 0.1079
F-statistic: 255 on 1 and 2099 DF, p-value: < 2.2e-16
=== Log-log regression: log(face_ei) ~ log(face_mi) ===
Call:
lm(formula = log(ei) ~ log(mi), data = face_data_filtered)
Residuals:
Min 1Q Median 3Q Max
-0.68767 -0.10831 0.01047 0.12229 0.58094
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.54659 0.05325 47.82 <2e-16 ***
log(mi) 0.24548 0.01481 16.58 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1743 on 2099 degrees of freedom
Multiple R-squared: 0.1158, Adjusted R-squared: 0.1153
F-statistic: 274.8 on 1 and 2099 DF, p-value: < 2.2e-16

Comparing linear and log-log regressions to test which model better fits the relationship between palm erythema index and face melanin content. This cross-site comparison may reveal systemic hemoglobin patterns.
=== Linear regression: palm_ei ~ face_mi ===
Call:
lm(formula = ei ~ face_mi, data = palm_spectrum)
Residuals:
Min 1Q Median 3Q Max
-11.1036 -3.3381 -0.0785 2.9910 16.9668
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 18.59875 0.51007 36.46 <2e-16 ***
face_mi 0.19474 0.01283 15.18 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 4.689 on 774 degrees of freedom
Multiple R-squared: 0.2294, Adjusted R-squared: 0.2284
F-statistic: 230.5 on 1 and 774 DF, p-value: < 2.2e-16
=== Log-log regression: log(palm_ei) ~ log(face_mi) ===
Call:
lm(formula = log(ei) ~ log(face_mi), data = palm_data_filtered)
Residuals:
Min 1Q Median 3Q Max
-0.55226 -0.12605 0.01504 0.12895 0.50267
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.17983 0.08561 25.46 <2e-16 ***
log(face_mi) 0.29439 0.02384 12.35 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1854 on 774 degrees of freedom
Multiple R-squared: 0.1646, Adjusted R-squared: 0.1635
F-statistic: 152.5 on 1 and 774 DF, p-value: < 2.2e-16



R version 4.5.2 (2025-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Tahoe 26.1
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.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: America/Detroit
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggeffects_2.3.2 broom.mixed_0.2.9.6 lme4_1.1-37
[4] Matrix_1.7-4 ggstatsplot_0.13.3 ggpubr_0.6.0
[7] here_1.0.1 KernSmooth_2.23-26 openxlsx_4.2.8.1
[10] scales_1.4.0 lubridate_1.9.4 forcats_1.0.0
[13] stringr_1.5.1 dplyr_1.1.4 purrr_1.2.0
[16] readr_2.1.5 tidyr_1.3.1 tibble_3.2.1
[19] ggplot2_4.0.1 tidyverse_2.0.0 knitr_1.50
loaded via a namespace (and not attached):
[1] Rdpack_2.6.4 pbapply_1.7-4 gridExtra_2.3
[4] rematch2_2.1.2 rlang_1.1.6 magrittr_2.0.4
[7] git2r_0.36.2 furrr_0.3.1 compiler_4.5.2
[10] statsExpressions_1.7.1 mgcv_1.9-3 systemfonts_1.3.1
[13] vctrs_0.6.5 pkgconfig_2.0.3 fastmap_1.2.0
[16] backports_1.5.0 labeling_0.4.3 utf8_1.2.5
[19] effectsize_1.0.1 promises_1.3.3 rmarkdown_2.29
[22] tzdb_0.5.0 haven_2.5.5 nloptr_2.2.1
[25] ragg_1.4.0 MatrixModels_0.5-4 xfun_0.54
[28] cachem_1.1.0 jsonlite_2.0.0 later_1.4.2
[31] broom_1.0.8 parallel_4.5.2 R6_2.6.1
[34] bslib_0.9.0 stringi_1.8.7 RColorBrewer_1.1-3
[37] parallelly_1.45.0 car_3.1-3 boot_1.3-32
[40] jquerylib_0.1.4 Rcpp_1.1.0 parameters_0.28.3
[43] correlation_0.8.8 httpuv_1.6.16 splines_4.5.2
[46] timechange_0.3.0 tidyselect_1.2.1 dichromat_2.0-0.1
[49] abind_1.4-8 yaml_2.3.10 codetools_0.2-20
[52] listenv_0.9.1 lattice_0.22-7 withr_3.0.2
[55] bayestestR_0.17.0 S7_0.2.0 coda_0.19-4.1
[58] evaluate_1.0.3 future_1.58.0 RcppParallel_5.1.11-1
[61] zip_2.3.3 pillar_1.10.2 carData_3.0-5
[64] whisker_0.4.1 reformulas_0.4.1 insight_1.4.4
[67] generics_0.1.4 rprojroot_2.0.4 paletteer_1.6.0
[70] hms_1.1.3 rstantools_2.5.0 minqa_1.2.8
[73] globals_0.18.0 glue_1.8.0 tools_4.5.2
[76] ggsignif_0.6.4 mvtnorm_1.3-3 fs_1.6.6
[79] cowplot_1.1.3 grid_4.5.2 rbibutils_2.3
[82] datawizard_1.3.0 nlme_3.1-168 patchwork_1.3.2
[85] Formula_1.2-5 cli_3.6.5 textshaping_1.0.1
[88] workflowr_1.7.1 viridisLite_0.4.2 gtable_0.3.6
[91] rstatix_0.7.2 zeallot_0.2.0 sass_0.4.10
[94] digest_0.6.37 prismatic_1.1.2 ggrepel_0.9.6
[97] farver_2.1.2 htmltools_0.5.8.1 lifecycle_1.0.4
[100] BayesFactor_0.9.12-4.7 MASS_7.3-65