chore(growth): add documentation and examples
All checks were successful
continuous-integration/drone/pr Build is passing
All checks were successful
continuous-integration/drone/pr Build is passing
This commit is contained in:
parent
bb79aa2f3a
commit
a8466f0c1d
@ -1,18 +1,39 @@
|
|||||||
defmodule Growth.Calc.Centile do
|
defmodule Growth.Calc.Centile do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
measures =
|
Calculate percentile for a given measurement and the fitted values of Box-Cox by age/height:
|
||||||
[
|
|
||||||
[30, -1.7862, 16.9392, 0.1107],
|
* power
|
||||||
[14, -1.3592, 20.4951, 0.12579],
|
* median
|
||||||
[19, -1.6318, 16.049, 0.10038]
|
* coefficientof variation
|
||||||
]
|
|
||||||
Enum.map(measures, &apply(Growth.Calc.Centile, :compute, &1))
|
This calculation is described in the [instructions provided by the World Health Organization](https://cdn.who.int/media/docs/default-source/child-growth/growth-reference-5-19-years/computation.pdf).
|
||||||
|
|
||||||
|
## Examples:
|
||||||
|
|
||||||
|
iex> measures =
|
||||||
|
...> [
|
||||||
|
...> [30, -1.7862, 16.9392, 0.1107],
|
||||||
|
...> [14, -1.3592, 20.4951, 0.12579],
|
||||||
|
...> [19, -1.6318, 16.049, 0.10038]
|
||||||
|
...> ]
|
||||||
|
iex> Enum.map(measures, &apply(Growth.Calc.Centile, :compute, &1))
|
||||||
|
[:na, :na, 19.0]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias Growth.Calc.ZScore
|
alias Growth.Calc.ZScore
|
||||||
|
|
||||||
# TODO: (jpd) add documentation and typespecs
|
@spec compute(number(), number(), number(), number()) :: number()
|
||||||
|
@doc """
|
||||||
|
Compute the centile for a given measurement (`y`) and the Box-Cox values: power (`l`), median (`m`), and
|
||||||
|
coefficient of variation (`s`).
|
||||||
|
|
||||||
|
## Examples:
|
||||||
|
|
||||||
|
iex> Growth.Calc.Centile.compute(19, -1.6318, 16.049, 0.10038)
|
||||||
|
19.0
|
||||||
|
|
||||||
|
"""
|
||||||
def compute(y, l, m, s) do
|
def compute(y, l, m, s) do
|
||||||
zscore = ZScore.raw(y, l, m, s)
|
zscore = ZScore.raw(y, l, m, s)
|
||||||
|
|
||||||
|
@ -1,26 +1,70 @@
|
|||||||
defmodule Growth.Calc.ZScore do
|
defmodule Growth.Calc.ZScore do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
measures =
|
Calculate z-score for a given measurement and the fitted values of Box-Cox by age/height:
|
||||||
[
|
|
||||||
[30, -1.7862, 16.9392, 0.1107],
|
* power
|
||||||
[14, -1.3592, 20.4951, 0.12579],
|
* median
|
||||||
[19, -1.6318, 16.049, 0.10038]
|
* coefficientof variation
|
||||||
]
|
|
||||||
Enum.map(measures, &apply(Growth.Calc.ZScore, :compute, &1))
|
This calculation is described in the [instructions provided by the World Health Organization](https://cdn.who.int/media/docs/default-source/child-growth/growth-reference-5-19-years/computation.pdf).
|
||||||
|
|
||||||
|
## Examples:
|
||||||
|
|
||||||
|
iex> measures =
|
||||||
|
...> [
|
||||||
|
...> [30, -1.7862, 16.9392, 0.1107],
|
||||||
|
...> [14, -1.3592, 20.4951, 0.12579],
|
||||||
|
...> [19, -1.6318, 16.049, 0.10038]
|
||||||
|
...> ]
|
||||||
|
iex> Enum.map(measures, &apply(Growth.Calc.ZScore, :compute, &1))
|
||||||
|
[3.35390255606726, -3.7985108865993493, 1.4698319520484722]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: (jpd) add documentation and typespecs
|
@spec compute(number(), number(), number(), number()) :: number()
|
||||||
|
@doc """
|
||||||
|
Compute the adjusted z-score for a given measurement (`y`) and the Box-Cox values: power (`l`), median (`m`), and
|
||||||
|
coefficient of variation (`s`).
|
||||||
|
|
||||||
|
## Examples:
|
||||||
|
|
||||||
|
iex> Growth.Calc.ZScore.compute(30, -1.7862, 16.9392, 0.1107)
|
||||||
|
3.35390255606726
|
||||||
|
iex> Growth.Calc.ZScore.compute(14, -1.3592, 20.4951, 0.12579)
|
||||||
|
-3.7985108865993493
|
||||||
|
iex> Growth.Calc.ZScore.compute(19, -1.6318, 16.049, 0.10038)
|
||||||
|
1.4698319520484722
|
||||||
|
|
||||||
|
"""
|
||||||
def compute(y, l, m, s) do
|
def compute(y, l, m, s) do
|
||||||
y
|
y
|
||||||
|> raw(l, m, s)
|
|> raw(l, m, s)
|
||||||
|> adjust(y, l, m, s)
|
|> adjust(y, l, m, s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec raw(number(), number(), number(), number()) :: number()
|
||||||
|
@doc """
|
||||||
|
Compute the raw z-score for a given measurement (`y`) and the Box-Cox values, power (`l`), median (`m`), and
|
||||||
|
coefficient of variation (`s`).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> Growth.Calc.ZScore.raw(30, -1.7862, 16.9392, 0.1107)
|
||||||
|
3.2353902101095855
|
||||||
|
iex> Growth.Calc.ZScore.raw(14, -1.3592, 20.4951, 0.12579)
|
||||||
|
-3.969714730727475
|
||||||
|
iex> Growth.Calc.ZScore.compute(19, -1.6318, 16.049, 0.10038)
|
||||||
|
1.4698319520484722
|
||||||
|
|
||||||
|
"""
|
||||||
def raw(y, l, m, s) do
|
def raw(y, l, m, s) do
|
||||||
(:math.pow(y / m, l) - 1) / (s * l)
|
(:math.pow(y / m, l) - 1) / (s * l)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec adjust(number(), number(), number(), number(), number()) :: number()
|
||||||
|
@doc """
|
||||||
|
Adjust the raw z-score considering that extreme values, beyond -3 and 3 standard deviation, must be handled differently.
|
||||||
|
"""
|
||||||
def adjust(zscore, y, l, m, s) when zscore > 3 do
|
def adjust(zscore, y, l, m, s) when zscore > 3 do
|
||||||
[sd2, sd3, _, _] = cutoffs(l, m, s)
|
[sd2, sd3, _, _] = cutoffs(l, m, s)
|
||||||
sd_delta = sd3 - sd2
|
sd_delta = sd3 - sd2
|
||||||
@ -37,11 +81,23 @@ defmodule Growth.Calc.ZScore do
|
|||||||
zscore
|
zscore
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec cutoffs(number(), number(), number()) :: [number()]
|
||||||
|
@doc """
|
||||||
|
Calculate the standard deviations cutoffs (2, 3, -2, and -3) for a given set of fitted Box-Cox values: power (`l`),
|
||||||
|
median (`m`), and coefficient of variation (`s`).
|
||||||
|
|
||||||
|
These cutoffs are used to calculate the adjusted z-score.
|
||||||
|
"""
|
||||||
def cutoffs(l, m, s) do
|
def cutoffs(l, m, s) do
|
||||||
Enum.map([2, 3, -2, -3], &cutoff_for_standard_deviation(&1, l, m, s))
|
Enum.map([2, 3, -2, -3], &measure_at_standard_deviation(&1, l, m, s))
|
||||||
end
|
end
|
||||||
|
|
||||||
def cutoff_for_standard_deviation(sd, l, m, s) do
|
@spec measure_at_standard_deviation(integer(), number(), number(), number()) :: number()
|
||||||
|
@doc """
|
||||||
|
Calculate the measure value at a given standard deviation (`sd`), considering the fitted Box-Cox values: power (`l`),
|
||||||
|
median (`m`), and coefficient of variation (`s`).
|
||||||
|
"""
|
||||||
|
def measure_at_standard_deviation(sd, l, m, s) do
|
||||||
m * :math.pow(1 + l * s * sd, 1 / l)
|
m * :math.pow(1 + l * s * sd, 1 / l)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user