Skip to contents

Scope

Compute sweat chloride, sodium/potassium ratio, sweat lactate, and sweat rate (L/m²/h) from sweat assays and anthropometrics. Includes mapping validation, NA policies, optional extreme screening/capping on inputs, and safe handling of zero/invalid denominators.

When to use this

  • You have sweat chloride, sodium, potassium, lactate, and anthropometrics (weight before/after, duration, body surface area) and want to derive sweat rate and ratios.
  • You want explicit NA handling, optional extreme-value capping, and consolidated zero-denominator warnings.

What you need (inputs & options)

Argument Purpose / Options Notes
data Data frame/tibble with sweat and anthropometric measures Columns mapped via col_map
col_map Named list mapping required inputs sweat_chloride, sweat_Na, sweat_K, sweat_lactate, weight_before, weight_after, duration, body_surface_area
na_action Missing-data policy for required inputs “keep” (default), “omit”, “error”
na_warn_prop Proportion threshold for high-missingness diagnostics Default 0.2 (shown in debug/verbose)
verbose Emit progress and completion summaries Default FALSE

Required columns (col_map): sweat_chloride, sweat_Na, sweat_K, sweat_lactate (mmol/L), weight_before, weight_after (kg), duration (h), body_surface_area (m²).

Units: No conversion is performed. Supply all values in the expected units above.

Handling and expectations

  • Validation & coercion: mapped columns must exist; non-numeric inputs are coerced with warnings if NAs are introduced; non-finite become NA.
  • Missingness: keep propagates NA; omit drops rows with any required NA; error aborts if required inputs contain NA.
  • High-missing diagnostics: controlled by na_warn_prop; shown when verbose (or debug) is enabled.
  • Safe division: all ratios use a helper that sets NA for zero/invalid denominators and emits a consolidated warning.
  • Sweat rate: (weight_beforeweight_after)/duration/body_surface_area(\text{weight_before} - \text{weight_after}) / \text{duration} / \text{body_surface_area} (1 kg ≈ 1 L water).
  • Empty result: if na_action = "omit" drops all rows, returns a zero-row tibble with expected columns.

Outputs

  • Returns a tibble (rows follow na_action) with: sweat_chloride, Na_K_ratio, sweat_lactate, sweat_rate.
  • NA arises from missing/invalid inputs, zero/invalid denominators, or dropped rows under omit.

Worked example 1: Standard usage, keep NAs

library(HealthMarkers)
library(tibble)

df <- tibble::tibble(
  sweat_chloride = c(45, 60, NA),
  sweat_Na = c(55, 70, 60),
  sweat_K = c(5, 4, 0),
  sweat_lactate = c(4.8, 5.2, 6.0),
  weight_before = c(70.0, 80.0, 75.0),
  weight_after = c(69.5, 79.2, 74.8),
  duration = c(1.0, 1.5, 0.5),
  body_surface_area = c(1.9, 2.1, 2.0)
)

sweat_markers(
  data = df,
  col_map = list(
    sweat_chloride = "sweat_chloride",
    sweat_Na = "sweat_Na",
    sweat_K = "sweat_K",
    sweat_lactate = "sweat_lactate",
    weight_before = "weight_before",
    weight_after = "weight_after",
    duration = "duration",
    body_surface_area = "body_surface_area"
  ),
  na_action = "keep",
  verbose = TRUE
)
#> # A tibble: 3 × 4
#>   sweat_chloride Na_K_ratio sweat_lactate sweat_rate
#>            <dbl>      <dbl>         <dbl>      <dbl>
#> 1             45       11             4.8      0.263
#> 2             60       17.5           5.2      0.254
#> 3             NA       NA             6        0.200

Interpretation: Returns all outputs; NA propagates where inputs are missing or denominators are zero (e.g., sweat_K = 0).

Worked example 2: Pre-filter extremes, drop incomplete

df2 <- tibble::tibble(
  cl = c(180, 250),       # extreme chloride; pre-filter
  na = c(60, 10),
  k = c(4, 0.5),
  lac = c(6, 60),         # extreme lactate; pre-filter
  w_before = c(75, 90),
  w_after = c(74.2, 89.0),
  dur = c(1, 0.2),
  bsa = c(2.0, 1.8)
)

# Pre-filter implausible values before calling
df2$cl[df2$cl > 200] <- NA
df2$lac[df2$lac > 50] <- NA

sweat_markers(
  data = df2,
  col_map = list(
    sweat_chloride = "cl",
    sweat_Na = "na",
    sweat_K = "k",
    sweat_lactate = "lac",
    weight_before = "w_before",
    weight_after = "w_after",
    duration = "dur",
    body_surface_area = "bsa"
  ),
  na_action = "omit",
  verbose = TRUE
)
#> # A tibble: 1 × 4
#>   sweat_chloride Na_K_ratio sweat_lactate sweat_rate
#>            <dbl>      <dbl>         <dbl>      <dbl>
#> 1            180         15             6      0.400

Interpretation: Implausible values are set to NA before calling; incomplete rows are then dropped.

Troubleshooting & common pitfalls

  • Units: all values must be in the expected units; convert upstream if needed.
  • Missing columns: ensure every required col_map key is mapped to an existing column.
  • Zero/invalid denominators: produce NA outputs and a warning; check for sweat_K = 0, duration = 0, or BSA = 0.
  • All NA outputs: usually due to missing/invalid inputs, zero denominators, or aggressive na_action = "omit".

Verbose diagnostics

old_opt <- options(healthmarkers.verbose = "inform")
sweat_markers(
  data = tibble::tibble(
    sweat_chloride    = 45,
    sweat_Na          = 55,
    sweat_K           = 5,
    sweat_lactate     = 4.8,
    weight_before     = 70,
    weight_after      = 69.5,
    duration          = 1.0,
    body_surface_area = 1.9
  ),
  col_map = list(
    sweat_chloride    = "sweat_chloride",
    sweat_Na          = "sweat_Na",
    sweat_K           = "sweat_K",
    sweat_lactate     = "sweat_lactate",
    weight_before     = "weight_before",
    weight_after      = "weight_after",
    duration          = "duration",
    body_surface_area = "body_surface_area"
  ),
  verbose = TRUE
)
#> sweat_markers(): reading input 'data' — 1 rows × 8 variables
#> sweat_markers(): col_map (8 columns — 8 specified)
#>   sweat_chloride    ->  'sweat_chloride'
#>   sweat_Na          ->  'sweat_Na'
#>   sweat_K           ->  'sweat_K'
#>   sweat_lactate     ->  'sweat_lactate'
#>   weight_before     ->  'weight_before'
#>   weight_after      ->  'weight_after'
#>   duration          ->  'duration'
#>   body_surface_area ->  'body_surface_area'
#> sweat_markers(): computing markers:
#>   sweat_chloride [sweat_chloride]
#>   Na_K_ratio [sweat_Na, sweat_K]
#>   sweat_lactate [sweat_lactate]
#>   sweat_rate [weight_before, weight_after, duration, body_surface_area]
#> sweat_markers(): results: sweat_chloride 1/1, Na_K_ratio 1/1, sweat_lactate 1/1, sweat_rate 1/1
#> # A tibble: 1 × 4
#>   sweat_chloride Na_K_ratio sweat_lactate sweat_rate
#>            <dbl>      <dbl>         <dbl>      <dbl>
#> 1             45         11           4.8      0.263
options(old_opt)

Column recognition

Run hm_col_report(your_data) to check which analyte columns are auto-detected before building your col_map. See the Multi-Biobank Compatibility article for recognised synonyms across major biobanks.

hm_col_report(your_data)

Tips for best results

  • Choose na_action = "omit" for modeling datasets that require complete cases; use keep for exploratory review.
  • Review warnings for zero denominators; these often indicate data entry or assay issues.

Validation notes

  • Na_K_ratio = sweat_Na / sweat_K; sweat_rate = (weight_before - weight_after) / duration / body_surface_area (1 kg ≈ 1 L).
  • All divisions are safe: zero/invalid denominators yield NA and a warning.

See also

  • Function docs: ?sweat_markers
  • Related vignettes: health_markers, metabolic_markers, urine_markers