R/body_fat.R

Defines functions calculate_lean_mass calculate_fat_mass calculate_bai calculate_bfp calculate_bfp_cunbae calculate_bfp_ymca calculate_bfp_strongur calculate_bfp_woolcott calculate_bfp_bmi calculate_bfp_navy

Documented in calculate_bai calculate_bfp calculate_bfp_bmi calculate_bfp_cunbae calculate_bfp_navy calculate_bfp_strongur calculate_bfp_woolcott calculate_bfp_ymca calculate_fat_mass calculate_lean_mass

#' @title Body fat percentage equations
#'
#' @description
#' \lifecycle{maturing}
#'
#' Calculates the one rep maximum. Possible equations are:
#'
#' - US navy
#' - BMI
#' - Woolcott
#' - Strongur
#' - YMCA
#'
#' @details
#' For more information on the strongur equation, go to:
#' \url{https://www.reddit.com/r/weightroom/comments/53g44q/if_you_bench_and_squat_heres_a_quick_and_easy_way/}
#'
#' @name bfp_formulas
#'
#' @param weight weight in kg
#' @param height height in centimeters
#' @param age age in year, Default: NULL
#' @param sex one of `male` or `female`
#' @param waist waist circumference, Default: NULL
#' @param neck neck circumference, Default: NULL
#' @param hip hip circumference, Default: NULL
#' @param bench bench press 1RM, Default: NULL
#' @param squat squat 1RM, Default: NULL
#'
#' @return Body fat percentage
#'
#' @aliases NULL
NULL

#' @rdname bfp_formulas
calculate_bfp_navy <- function(height, sex, waist, neck, hip) {
  checkmate::assert_number(height, lower = 0)
  check_sex(sex)
  checkmate::assert_number(waist, lower = 0)
  checkmate::assert_number(neck, lower = 0)
  if (sex == "male") {
    bfp <-
      (495 / (1.0324 - (0.19077 * log10(waist - neck)) +
                (0.15456 * log10(height)))) - 450
  } else {
    checkmate::assert_number(hip, lower = 0)
    bfp <-
      (495 / (1.29579 - (0.35004 * log10(waist + hip - neck)) + (0.22100 * log10(height)))) - 450
  }
  return(bfp)
}

#' @rdname bfp_formulas
calculate_bfp_bmi <- function(weight, height, age, sex) {
  checkmate::assert_number(weight, lower = 0)
  checkmate::assert_number(height, lower = 0)
  checkmate::assert_number(age, lower = 0)
  check_sex(sex)
  bmi <- calculate_bmi(weight, height)
  bfp <- 1.20 * bmi + 0.23 * age - 5.4
  bfp <- ifelse(sex == "male", bfp - 10.8, bfp)
  return(bfp)
}

#' @rdname bfp_formulas
calculate_bfp_woolcott <- function(weight, height, sex, waist) {
  checkmate::assert_number(weight, lower = 0)
  checkmate::assert_number(height, lower = 0)
  check_sex(sex)
  checkmate::assert_number(waist, lower = 0)
  # Fix assigning sex to 1 or 0 based on sex
  sex <- ifelse(sex == "female", 1, 0)
  bfp <-
    100 * ((64 - (20 * (height / waist)) + (12 * sex)) / weight)
  return(bfp)
}

#' @rdname bfp_formulas
calculate_bfp_strongur <-
  function(weight, height, sex, squat, bench) {
    checkmate::assert_number(weight, lower = 0)
    checkmate::assert_number(height, lower = 0)
    check_sex(sex)
    checkmate::assert_number(squat, lower = 0)
    checkmate::assert_number(bench, lower = 0)
    bfp <-
      62.1 -
      0.0691 * bench -
      0.0301 * squat +
      0.458 * weight -
      40.6 * (height / 100)
    if (sex == "female") {
      bfp <- bfp + 5.48
    }
    return(bfp)
  }

#' @rdname bfp_formulas
calculate_bfp_ymca <- function(weight, sex, waist) {
  checkmate::assert_number(weight, lower = 0)
  weight <- weight * 2.2 # kg to lbs
  check_sex(sex)
  checkmate::assert_number(waist, lower = 0)
  waist <- waist / 2.54 # cm to inch
  ifelse(sex == "male",
         bfp <-
           ((-98.42 + (4.15 * waist) - (0.082 * weight)) / weight) * 100,
         bfp <-
           ((-76.76 + (4.15 * waist) - (0.082 * weight)) / weight) * 100)
  return(bfp)
}

#' @rdname bfp_formulas
calculate_bfp_cunbae <- function(weight, height, sex, age) {
  # https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3263863/
  checkmate::assert_number(weight, lower = 0)
  checkmate::assert_number(height, lower = 0)
  check_sex(sex)
  checkmate::assert_number(age, lower = 0)
  bmi <- calculate_bmi(weight, height)
  sex <- ifelse(sex == "male", 0, 1)
  bfp <- -44.988 +
    (0.503 * age) +
    (10.689 * sex) +
    (3.172 * bmi) -
    (0.026 * bmi ** 2) +
    (0.181 * bmi * sex) -
    (0.02 * bmi * age) -
    (0.005 * bmi**2 * sex) +
    (0.00021 * bmi ** 2 * age)
  return(bfp)
}

#' @title Calculate body fat percentage
#'
#' @description
#' \lifecycle{maturing}
#'
#' This function calculates body fat percentage using several equations. These
#' functions use different arguments. Note that the `us-navy` function is meant
#' to estimate body fat percentage for people aged 20 to 40. Keep in mind that
#' these calculations are estimates.
#'
#' @param weight weight in kg
#' @param height height in centimeters
#' @param age age in year, Default: NULL
#' @param sex one of `male` or `female`
#' @param waist waist circumference, Default: NULL
#' @param neck neck circumference, Default: NULL
#' @param hip hip circumference, Default: NULL
#' @param bench bench press 1RM, Default: NULL
#' @param squat squat 1RM, Default: NULL
#' @param equation equation, Default: 'us-navy'
#'
#' @return Body fat percentage
#'
#' @details Measure the neck just below height of larynx. For men, measuring the
#'   circumference of waist should be around navel for men, at level of smallest
#'   width for women. For women: measure the hip at largest horizontal width
#'   level. The calculation is based on the following equation:
#'   \deqn{BFP_{us-navy|male} = \frac{495}{1.0324 - (0.19077 \times log10(waist
#'   - neck)) + (0.15456 \times log10(height))} - 450}
#'   \deqn{BFP_{us-navy|female} = \frac{495}{1.29579 - (0.35004 \times log10(
#'   waist + hip - neck)) + (0.22100 \times log10(height))} - 450}
#'   \deqn{BFP_{bmi|male} = 1.20 \times bmi + 0.23 \times age - 10.8 - 5.4}
#'   \deqn{BFP_{bmi|male} = 1.20 \times bmi + 0.23 \times age - 5.4}
#'
#' @examples
#' # us-navy based
#' calculate_bfp(
#'   height = 180, sex = "male", waist = 80, neck = 35, equation =
#'     "us-navy"
#' )
#'
#' # BMI based
#' calculate_bfp(
#'   weight = 80, height = 170, age = 30, sex = "male", equation =
#'     "bmi"
#' )
#'
#' # Woolcott
#' calculate_bfp(
#'   weight = 80, height = 170, sex = "male", waist = 80, equation
#'   = "woolcott"
#' )
#'
#' # Strongur
#' calculate_bfp(
#'   weight = 80, height = 170, sex = "male", squat = 100, bench = 75, equation
#'   = "strongur"
#' )
#'
#' # YMCA
#' calculate_bfp(
#'   weight = 80, sex = "male", waist = 80, equation = "ymca"
#' )
#' @rdname calculate_bfp
#' @export
#' @importFrom checkmate assert_choice assert_number
calculate_bfp <-
  function(weight,
           height,
           age = NULL,
           sex,
           waist = NULL,
           neck = NULL,
           hip = NULL,
           bench = NULL,
           squat = NULL,
           equation = "us-navy") {
    equation_choices <- c("us-navy",
                          "cunbae",
                          "bmi",
                          "woolcott",
                          "strongur",
                          "ymca")
    #TODO(MJABOER): add formulas for all equations
    checkmate::assert_choice(equation, equation_choices)
    bfp <- switch(
      equation,
      "us-navy" = calculate_bfp_navy(
        height = height,
        sex = sex,
        waist = waist,
        neck = neck,
        hip = hip
      ),
      "cunbae" = calculate_bfp_cunbae(
        weight = weight,
        height = height,
        sex = sex,
        age = age
      ),
      "bmi" = calculate_bfp_bmi(
        weight = weight,
        height = height,
        age = age,
        sex = sex
      ),
      "woolcott" = calculate_bfp_woolcott(
        weight = weight,
        height = height,
        sex = sex,
        waist = waist
      ),
      "strongur" = calculate_bfp_strongur(
        weight = weight,
        height = height,
        sex = sex,
        squat = squat,
        bench = bench
      ),
      "ymca" = calculate_bfp_ymca(
        weight = weight,
        sex = sex,
        waist = waist
      )
    )
    return(bfp)
  }

#' @title Calculate Body Adiposity Index
#'
#' @description
#' \lifecycle{maturing}
#'
#' The body adiposity index (BAI) is a method of estimating the amount of body
#' fat in humans.
#'
#' @param height height in centimeters
#' @param hip hip circumference in centimeters
#'
#' @return Body adiposity index
#'
#' @details Bergman, R. N., Stefanovski, D. , Buchanan, T. A., Sumner, A. E.,
#'   Reynolds, J. C., Sebring, N. G., Xiang, A. H. and Watanabe, R. M. (2011), A
#'   Better Index of Body Adiposity. Obesity, 19: 1083-1089.
#'   doi:10.1038/oby.2011.38
#'
#' @examples
#' calculate_bai(180, 90)
#' @rdname calculate_bai
#' @export
#' @importFrom checkmate assert_number
calculate_bai <- function(height, hip) {
  checkmate::assert_number(height, lower = 0)
  checkmate::assert_number(hip, lower = 0)
  bfp <- (hip / ((height / 100) ** 1.5)) - 18
  return(bfp)
}

#' @title Calculate fat mass
#'
#' @description
#' \lifecycle{maturing}
#'
#' Calculates fat mass in kg.
#'
#' @param weight weight in kg.
#' @param bfp body fat percentage
#'
#' @return Fat mass (kg)
#'
#' @details Woolcott: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6054651/
#'
#' @examples
#' calculate_fat_mass(weight = 80, bfp = 15)
#' @rdname calculate_fat_mass
#' @export
#' @importFrom checkmate assert_number
calculate_fat_mass <-
  function(weight = NULL,
           bfp = NULL) {
    checkmate::assert_number(weight, lower = 0)
    checkmate::assert_number(bfp, lower = 0, upper = 100)
    fm <- (bfp * 0.01) * weight
    return(fm)
  }

#' @title Calculates lean mass
#'
#' @description
#' \lifecycle{maturing}
#'
#' Calculates lean mass in kg.
#'
#' @param weight weight in kg.
#' @param fm fat mass in kg
#'
#' @return Lean mass (kg)
#'
#' @details DETAILS
#'
#' @examples
#' calculate_lean_mass(weight = 80, fm = 15)
#' @rdname calculate_lean_mass
#' @export
#' @importFrom checkmate assert_number
calculate_lean_mass <- function(weight, fm = NULL) {
  checkmate::assert_number(weight, lower = 0)
  checkmate::assert_number(fm, lower = 0, upper = weight)
  lm <- weight - fm
  return(lm)
}
MarijnJABoer/befitteR documentation built on April 24, 2020, 5:43 a.m.