Build the eight-category age and sex demographic group
Source:R/age_sex_group.R
eiod_age_sex_group.RdEvery cut-off in the Intake framework is scaled to one of eight age/sex groups, because average dietary energy requirement differs across them. This function builds that grouping variable, which all other `eiod_*` metric functions require.
Usage
eiod_age_sex_group(
age,
sex,
age_units = c("years", "months"),
male = NULL,
female = NULL
)Arguments
- age
Numeric vector of respondent ages.
- sex
Factor, character or numeric vector of respondent sex. See "Which type should `sex` be?" above.
- age_units
Either `"years"` (the default) or `"months"`.
- male, female
Optional. The value of `sex` that means male and female respectively. Required when `sex` is numeric; optional for factor and character input, where they override the automatic label matching. Supply both or neither.
Value
An integer vector of group codes 1 to 8, with `NA` where age or sex is missing. The result carries a `"labels"` attribute giving the group names, and can be turned into a labelled factor with `factor(x, 1:8, attr(x, "labels"))`.
The eight groups
| 1 | Male 0-1.9 yr |
| 2 | Male 2-4.9 yr |
| 3 | Male 5-9.9 yr |
| 4 | Male 10+ yr |
| 5 | Female 0-1.9 yr |
| 6 | Female 2-4.9 yr |
| 7 | Female 5-9.9 yr |
| 8 | Female 10+ yr |
Age boundaries are half-open
The paper prints the groups as "0-1.9", "2-4.9", "5-9.9" and "10+". These are read as half-open intervals: `age < 2`, `2 <= age < 5`, `5 <= age < 10`, `age >= 10`. A child aged 1.95 years therefore belongs in the first group. Testing `age <= 1.9` instead would leave everyone between 1.9 and 2.0 unassigned, and they would then drop out of every downstream metric without any error being raised.
Which type should `sex` be?
All three common types are accepted, but they are not equally safe.
A factor is the recommended input. Its levels carry the meaning, so the data is self-documenting and no separate codebook is needed; `table()` and model output print "male" and "female" rather than 1 and 2; and the function can resolve it without being told anything further.
Character works identically and is what `read.csv()` produces by default in R 4.0 and later. Converting it to a factor costs nothing and is worth doing.
Numeric requires `male` and `female` to be given explicitly. This is a deliberate refusal rather than a missing feature. Survey data uses 1/2 and 0/1 about equally often, and there is no way to tell them apart from the values alone: both are just two distinct numbers. If the function guessed and guessed wrong, every result would be silently inverted, with no error and nothing visibly odd in the output. Rather than carry that risk, numeric input errors until the codes are stated.
The recommended route for numeric data is to convert once, near the top of the analysis, with [eiod_as_sex_factor()]. After that every downstream call is unambiguous.
For factor and character input, these labels are recognised automatically, case-insensitively and ignoring surrounding spaces: `m`, `male`, `males`, `man`, `men`, `boy`, `boys`, and `f`, `female`, `females`, `woman`, `women`, `girl`, `girls`. Anything else raises an error listing the unrecognised values; they are never dropped silently, because that would quietly shrink the analysis sample.
Examples
# the recommended input: sex as a factor
eiod_age_sex_group(age = c(1.5, 3, 7, 40), sex = factor(c("male", "male",
"female", "female")))
#> [1] 1 2 7 8
#> attr(,"labels")
#> [1] "Male 0-1.9 yr" "Male 2-4.9 yr" "Male 5-9.9 yr" "Male 10+ yr"
#> [5] "Female 0-1.9 yr" "Female 2-4.9 yr" "Female 5-9.9 yr" "Female 10+ yr"
# character works the same way
eiod_age_sex_group(age = c(1.5, 40), sex = c("M", "F"))
#> [1] 1 8
#> attr(,"labels")
#> [1] "Male 0-1.9 yr" "Male 2-4.9 yr" "Male 5-9.9 yr" "Male 10+ yr"
#> [5] "Female 0-1.9 yr" "Female 2-4.9 yr" "Female 5-9.9 yr" "Female 10+ yr"
# numeric requires the codes to be stated
eiod_age_sex_group(age = c(1.5, 40), sex = c(1, 2), male = 1, female = 2)
#> [1] 1 8
#> attr(,"labels")
#> [1] "Male 0-1.9 yr" "Male 2-4.9 yr" "Male 5-9.9 yr" "Male 10+ yr"
#> [5] "Female 0-1.9 yr" "Female 2-4.9 yr" "Female 5-9.9 yr" "Female 10+ yr"
# age in months
eiod_age_sex_group(age = c(23, 24), sex = c("male", "male"),
age_units = "months")
#> [1] 1 2
#> attr(,"labels")
#> [1] "Male 0-1.9 yr" "Male 2-4.9 yr" "Male 5-9.9 yr" "Male 10+ yr"
#> [5] "Female 0-1.9 yr" "Female 2-4.9 yr" "Female 5-9.9 yr" "Female 10+ yr"