import _ from 'lodash'; import { compute_zscore_adjusted, flag_zscore } from './z-score-helper'; import { lookupGrowthStandards, round } from './utils'; // ' Weight-for-length zscore indicator // ' // ' @param weight numeric // ' @param length_measure numeric // ' @param length_unit character // ' @param age_in_days integer, the age in days. // ' @param age_in_months numeric, the age in months. // ' @param sex integer, the sex where 1 is male and 2 is female // ' @param flag_threshold numeric, a length 1 threshold. // ' If the absolute value of the z-score is greater than // ' this parameter, the z-score gets flagged in the resulting data frame. // ' @param growthstandards data.frame, the growstandards // ' table for the weight-for-age indicator. // ' Do not change unless you know what you are doing. // ' @include z-score-helper.R // ' @noRd type weight_for_lenhei = { weight?: number, lenhei?: number, lenhei_unit?: string, age_in_days?: number, age_in_months?: number, sex: 1 | 2, oedema?: string | undefined flag_threshold?: number, growthstandards_wfl?: string, growthstandards_wfh?: string, } export default function anthro_zscore_weight_for_lenhei({ weight, lenhei, lenhei_unit, age_in_days, age_in_months, sex, oedema, flag_threshold = 5, growthstandards_wfl = 'wflanthro', growthstandards_wfh = 'wfhanthro', }: weight_for_lenhei): ReturnType { // we use the input parameter to lookup the relevant // values from the growth standards // then we have everything to compute the zscores // clean weight/lenhei if (!weight || weight < 0.9 || weight > 58.0) { console.warn('weight is missing or below 0.9 or above 58.0, weight_for_lenhei undefined'); return flag_zscore(flag_threshold, 'wfl', undefined, false); } if (!lenhei || lenhei < 38.0 || lenhei > 150.0) { console.warn('lenhei is missing or below 38.0 or above 150.0, weight_for_lenhei undefined'); return flag_zscore(flag_threshold, 'wfl', undefined, false); } // we also need to interpolate lenhei under certain coniditions const low_lenhei = Math.floor(lenhei * 10) / 10; const upp_lenhei = Math.floor(lenhei * 10 + 1) / 10; const diff_lenhei = (lenhei - low_lenhei) / 0.1; const use_l_lenhei_unit = ((age_in_days && age_in_days < 731) || (!age_in_days && lenhei_unit && lenhei_unit == 'l') || (!age_in_days && !lenhei_unit && lenhei && lenhei < 87)); const use_h_lenhei_unit = ((age_in_days && age_in_days >= 731) || (!age_in_days && lenhei_unit && lenhei_unit == 'h') || (!age_in_days && !lenhei_unit && lenhei && lenhei >= 87)); // lookup the appropriate standards using relevant values let standardUpperValues; let standardLowerValues; if (use_l_lenhei_unit) { standardLowerValues = lookupGrowthStandards([low_lenhei, sex], ['length', 'sex'], growthstandards_wfl); standardUpperValues = lookupGrowthStandards([upp_lenhei, sex], ['length', 'sex'], growthstandards_wfl); } else if (use_h_lenhei_unit) { standardLowerValues = lookupGrowthStandards([low_lenhei, sex], ['height', 'sex'], growthstandards_wfh); standardUpperValues = lookupGrowthStandards([upp_lenhei, sex], ['height', 'sex'], growthstandards_wfh); } else { console.warn('do not know whether to use l or h for lenhei measurement'); return flag_zscore(flag_threshold, 'wfl', undefined, false); } const y = weight; let m, l, s; if(standardUpperValues && standardLowerValues) { m = diff_lenhei > 0 ? standardLowerValues.m + diff_lenhei * (standardUpperValues.m - standardLowerValues.m) : standardLowerValues.m; l = diff_lenhei > 0 ? standardLowerValues.l + diff_lenhei * (standardUpperValues.l - standardLowerValues.l) : standardLowerValues.l; s = diff_lenhei > 0 ? standardLowerValues.s + diff_lenhei * (standardUpperValues.s - standardLowerValues.s) : standardLowerValues.s; } const zscoreComp = compute_zscore_adjusted(y, m, l, s); const zscore = round(zscoreComp); let valid_zscore; if (use_l_lenhei_unit) { valid_zscore = lenhei && lenhei >= 45 && lenhei <= 110; } else if (use_h_lenhei_unit) { valid_zscore = lenhei && lenhei >= 65 && lenhei <= 120; } else { console.warn('do not know whether to use l or h for validation'); return flag_zscore(flag_threshold, 'wfl', undefined, false); } valid_zscore = !!valid_zscore && !(oedema && oedema.includes('y')); valid_zscore = !!valid_zscore && (!age_in_days || (age_in_days <= 1856)); valid_zscore = age_in_months ? !!valid_zscore && age_in_months < 60 : valid_zscore; return flag_zscore(flag_threshold, 'wfl', zscore, valid_zscore); }