Note - the replica library is currently very experimental. It is still undergoing active development and testing. Function, class and method names, arguments and syntax may change without the use of deprecation conventions. This library should currently be used only for exploratory purposes.
Motivation
In the “Assigning Attributes Using Contingency Tables” vignette we
used ReplicaAdder to enrich a synthetic population with
additional demographic attributes.
At this stage each row of the synthetic population represents an individual agent.
Many simulation models, however, require agents to be organised into realistic household structures before analysis can proceed.
Examples include:
health-economic microsimulation models;
infectious disease models;
transport simulations; and
social and economic forecasting models.
The replica package provides tools for transforming an
agent-level synthetic population into synthetic households while
preserving geographic and demographic constraints. It does this by
providing an R implementation of an algorithm described by de Mooij et
al. (2024).
Household generation in replica is based on two core
classes:
ReplicaStructureReplicaGrouper
A ReplicaStructure describes a household structure that
should be generated, while a ReplicaGrouper applies one or
more household definitions to a synthetic population.
This vignette demonstrates the third stage of the
replica workflow: transforming individual synthetic agents
into synthetic households.
Workflow overview
The workflow demonstrated in this vignette can be summarised as:
Aggregate Counts ↓ make_agents() ↓ Synthetic Agents ↓ ReplicaAdder ↓ Enriched Population ↓ ReplicaGrouper + ReplicaStructure ↓ Synthetic Households
This vignette focuses on the household-generation stage.
Supply a synthetic population of individual agents
This vignette assumes that a synthetic population has already been created and enriched with demographic attributes.
In practice such a population would typically have been generated using the workflows described in the “Generating Synthetic Populations from Aggregated Data” and “Assigning Attributes Using Contingency Tables” vignettes.
For simplicity, this example uses a small illustrative population containing four adults living in the same neighbourhood.
pop <- data.table(
agent_id = c(
"A001",
"A002",
"A003",
"A004"
),
neighb_code = c(
"N1",
"N1",
"N1",
"N1"
),
age = c(
40,
35,
50,
45
),
gender = c(
"Male",
"Female",
"Male",
"Female"
),
household_position = c(
"Parent",
"Parent",
"Parent",
"Parent"
)
)
pop## agent_id neighb_code age gender household_position
## <char> <char> <num> <char> <char>
## 1: A001 N1 40 Male Parent
## 2: A002 N1 35 Female Parent
## 3: A003 N1 50 Male Parent
## 4: A004 N1 45 Female Parent
Household generation is driven by household positions.
These positions identify the household roles that agents may occupy and determine which agents are eligible for matching during household construction.
Potential examples include:
- Parent
- Child
- Grandparent
In this example all agents are classified as potential parents and are therefore eligible for adult household positions.
Create a household type
A household type specifies a household structure that we plan to generate. Here we create a simple couple household.
hh <- ReplicaStructure("CoupleHousehold")At this point we have only defined the household name. We now need to specify the household members that form this household type.
Define household membership
The renew() method defines the roles that must be filled when constructing a household. In this example, a couple household requires two adults.
hh <- renew(
hh,
household_position = "Parent",
position_identifier = "adult",
amount = 2,
backup_position_identifiers = character()
)This tells replica that:
agents with household position “Parent” are eligible;
these agents represent “adult” household members; and
exactly two adults are required per household.
Notice that two separate concepts are used:
household_positionposition_identifier
The household_position corresponds to values that appear
in the synthetic population.
The position_identifier defines broader household roles
used internally by the household-building algorithm.
For example, multiple population-specific household positions could
all be assigned the identifier "adult".
This separation makes it easier to adapt household generation rules to different source datasets.
The household definition is now complete.
Define demographic matching rules
The demographic characteristics assigned in the previous vignette can now be used when constructing households.
For example, household formation may depend on:
partner gender combinations;
partner age differences; and
child-parent age relationships.
These demographic relationships are controlled using matching distributions.
For simplicity, this illustrative example will generate Female - Male pairs in which the age gap between partners is within 5 years.
The above age distribution indicates that permissible partner age gaps range from five years younger to five years older.
In this example the four agents are expected to form two synthetic couple households:
- one household containing agents A001 and A002; and
- one household containing agents A003 and A004.
The exact assignment depends on the demographic matching rules specified above.
Create a household grouper
A ReplicaGrouper coordinates household generation across an entire synthetic population.
hg <- ReplicaGrouper(df_synth_pop = pop,
group_by = "neighb_code")The group_by argument determines the geographic or administrative boundaries within which household generation will occur.
In this example households are generated independently within each neighbourhood.
Restricting household generation to geographic areas helps preserve local population structure and ensures that agents are matched only with other agents from the same area.
This is particularly important when generating synthetic households for geographically explicit simulation models.
Register household types
A ReplicaGrouper may contain multiple household types.
For example, a realistic population might contain:
single-adult households;
couple households; and
family households.
Household types are registered using renew().
hg <- renew(hg,hh)The grouper now knows how to generate couple households.
Run household generation
Once household types have been registered, the complete household-generation workflow can be executed using enhance().
result <- enhance(hg)The enhance() method executes the complete
household-generation workflow.
For each grouping region (neighb_code in this example),
replica:
Identifies eligible household members.
Creates household structures using registered
ReplicaStructureobjects.Matches adults according to the configured gender and age distributions.
Creates synthetic households.
Assigns household identifiers.
Produces household-level summary tables.
The result is returned as a list containing both agent-level and household-level outputs.
Inspect output
The result now contains both agent-level and household-level outputs.
synthetic_population <- result$synthetic_population
synthetic_households <- result$synthetic_householdsThe household-generation workflow produces two complementary outputs.
synthetic_population contains one row per agent and
records the household assignment of each synthetic individual.
synthetic_households contains one row per household and
summarises the resulting household structures.
Together these outputs allow analyses to be performed at both the individual and household level.
Inspect household assignments
The agent-level output now contains household identifiers.
synthetic_population[,c("agent_id", "household_id")]## agent_id household_id
## <char> <char>
## 1: A001 SSH000001
## 2: A002 SSH000001
## 3: A003 SSH000002
## 4: A004 SSH000002
Agents sharing the same household identifier belong to the same synthetic household.
Inspect household-level summaries
The household summary table provides one row per household.
synthetic_households## household_id neighb_code hh_type hh_size
## 1 SSH000001 N1 CoupleHousehold 2
## 2 SSH000002 N1 CoupleHousehold 2
nrow(synthetic_households)## [1] 2
This value represents the number of synthetic households that were successfully generated.
Check integrity (brief version)
The household-generation workflow automatically performs validation checks during execution.
A simple post-generation check is:
## [1] FALSE
A value of FALSE indicates that all agents have been assigned to households.
A more comprehensive discussion of population validation is provided in the “Evaluating Synthetic Population Quality” vignette.
Create family households
The previous example generated households containing adults only. The same approach can be extended further to support more complex household structures involving grandparents, children or other household positions if suitable demographic data are available.
hh <- ReplicaStructure("FamilyHousehold")
hh <- renew(
hh,
household_position = "Parent",
position_identifier = "adult",
amount = 2,
backup_position_identifiers = character()
)
hh <- renew(
hh,
household_position = "Child",
position_identifier = "child",
amount = 2,
backup_position_identifiers = character()
)When child household members are present, replica
automatically:
forms sibling groups;
creates adult partner groups;
matches adults and children; and
creates complete family households.
No additional user intervention is required.
The resulting household structures are stored using separate adult, child and all components.
How the workflow fits together
The overall workflow can be summarised as:
Aggregate Counts ↓ make_agents() ↓ Synthetic Agents ↓ ReplicaAdder ↓ Enriched Population ↓ ReplicaStructure + ReplicaGrouper ↓ Synthetic Households ↓ Validation
Key takeaways
At this point the synthetic population contains both individual-level and household-level structures.
The resulting synthetic households can be used directly in simulation models or evaluated further using the validation tools described in the “Evaluating Synthetic Population Quality” vignette.
In this vignette we:
transformed synthetic agents into synthetic households;
defined household structures using
ReplicaStructure;specified household-member roles;
configured demographic matching rules;
generated households using
ReplicaGrouper;examined both agent-level and household-level outputs; and
created both couple and family household structures.
References
de Mooij J, Sonnenschein T, Pellegrino M, Dastani M, Ettema D, Logan B and Verstegen JA (2024).
GenSynthPop: generating a spatially explicit synthetic population of individuals and households from aggregated data.
Autonomous Agents and Multi-Agent Systems. https://link.springer.com/article/10.1007/s10458-024-09680-7
