Learn R Programming

socialmixr (version 0.7.0)

weigh: Weigh survey participants

Description

weigh() multiplies participant weights by values looked up from a target. The existing weight column is multiplied in place, so multiple calls compose; if no weight column is present, one is created with value 1.

weigh_by_dayofweek() and weigh_by_age() are thin convenience wrappers around the two most common recipes — the weekly weekday/weekend split and age post-stratification against a reference population. See the dedicated sections below for what they compute exactly.

Usage

weigh(survey, by, target = NULL, groups = NULL, ...)

weigh_by_dayofweek(survey)

weigh_by_age(survey, pop, ...)

Value

the survey object with updated participant weights

Arguments

survey

a survey() object

by

column name in the participant data to join on

target

see Target shapes accepted by weigh().

groups

a list of value sets mapping column values to groups (used with an unnamed numeric target vector); must be the same length as target.

...

ignored.

pop

a data frame with columns age (age-group labels) and population (used by weigh_by_age()).

Target shapes accepted by <code>weigh()</code>

  • target = NULL (the default) — multiply the numeric column by directly into weight. Useful when participants already carry a precomputed weight column.

  • a two-column data frame whose key column is named by — pure discrete join: multiply the value column into weight where the key matches. Unmatched values get NA (with a warning).

  • an unnamed numeric vector together with groups — each element of target is the total weight assigned across participants matching the corresponding entry in groups. The per-participant factor is target[g] / n_in_group.

  • a named numeric vector — same as above but names(target) are matched against values of the by column.

A data frame target that does not have a column named by but does have lower.age.limit and population triggers a deprecation warning and falls back to the old hidden age post-stratification path; use weigh_by_age() instead.

<code>weigh_by_dayofweek()</code>

Rescales weights so that weekday participants together carry a total weight of 5 and weekend participants a total weight of 2 — the weekly 5/2 split that corrects for the typical over-representation of weekdays in diary surveys. Concretely, each weekday participant gets 5 / n_weekday and each weekend participant 2 / n_weekend; participants with NA day-of-week get the neutral average 7 / N. The dayofweek column is taken to use 0 = Sunday through 6 = Saturday (the POLYMOD convention).

Equivalent to: weigh(survey, "dayofweek", target = c(5, 2), groups = list(1:5, c(0, 6)))

<code>weigh_by_age()</code>

Convenience wrapper for age post-stratification. Participants are binned into the reference population's own age bands (whatever resolution pop is supplied at) and, for each band \(b\), the weight becomes

$$w_b = \frac{P_b / P}{N_b / N},$$

where \(P_b\) is the target population in band \(b\), \(P\) the total, and \(N_b\), \(N\) the corresponding sample counts. No interpolation is performed, so the weighting resolution is that of the supplied reference population.

survey must already have been processed by assign_age_groups() so that a part_age column is available for the join.

Examples

Run this code
data(polymod)
uk <- polymod[country == "United Kingdom"] |>
  assign_age_groups(age_limits = c(0, 5, 15))

# --- target = NULL ---
# Multiply an existing numeric column directly into the weight:
uk |> weigh("hh_size")

# --- data-frame target (discrete join) ---
# The key column of `target` must match `by`. Each participant
# has its weight multiplied by the matching value column.
age_target <- data.frame(
  age.group = c("[0,5)", "[5,15)", "[15,Inf)"),
  p = c(0.06, 0.12, 0.82)
)
uk |> weigh("age.group", target = age_target)

# Same idea, joining on `country` to pool participants across studies
# by a target population share:
country_target <- data.frame(
  country = c("United Kingdom", "Germany", "Italy"),
  p = c(0.3, 0.4, 0.3)
)
polymod |>
  assign_age_groups(age_limits = c(0, 5, 15)) |>
  weigh("country", target = country_target)

# --- unnamed vector + groups (total-weight semantics) ---
# Each `target[g]` is the *total* weight assigned to participants in
# `groups[[g]]`. Here weekdays together carry weight 5, weekend days
# together carry weight 2:
uk |> weigh("dayofweek", target = c(5, 2), groups = list(1:5, c(0, 6)))

# The same is available as the convenience:
uk |> weigh_by_dayofweek()

# --- named vector ---
# `names(target)` are matched against `by` values; each value is the
# total weight for participants with that key.
uk$participants[, agecat := ifelse(part_age < 18, "child", "adult")]
uk |> weigh("agecat", target = c(child = 0.25, adult = 0.75))

# --- age post-stratification ---
uk_pop <- data.frame(
  age = limits_to_age_groups(c(0, 5, 15, 65), notation = "brackets"),
  population = c(3500000, 6000000, 40000000, 10000000)
)
uk |> weigh_by_age(uk_pop)

Run the code above in your browser using DataLab