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 previous vignette we used make_agents() to create
a synthetic population of individual agents from aggregate count
data.
These agents often contain only a small number of variables. For example, a population may contain age-group and gender information but lack additional attributes required for simulation modelling.
The ReplicaAdder class can be used to enrich synthetic
agents using contingency tables derived from external data sources.
Examples include:
education;
employment status;
occupation;
health status; and
income category.
This vignette demonstrates how to assign an education attribute while
preserving known relationships between age, gender and education. The
replica tools demonstrated here collectively represent an R
implementation of the demographic attribute-assignment stage of the
workflow described by de Mooij et al. (2024) for spatial synthetic
population generation.
Workflow
The workflow demonstrated in this vignette can be summarised as:
Age-Gender Counts ↓ make_agents() ↓ Synthetic Agents ↓ ReplicaAdder ↓ Education Assignment ↓ Enriched Synthetic Population
Supply a seed synthetic population of individual agents
We begin with a basic synthetic population that lacks the target attribute.
For this example, we will create a basic seed population from an age group and gender contingency table using the approach demonstrated in the “Generating Synthetic Populations from Aggregated Data” vignette.
age_gender <- data.frame(
age_group = c(
"18-64",
"18-64",
"65+",
"65+"
),
gender = c(
"Male",
"Female",
"Male",
"Female"
),
count = c(
10,
10,
10,
10
)
)
age_gender## age_group gender count
## 1 18-64 Male 10
## 2 18-64 Female 10
## 3 65+ Male 10
## 4 65+ Female 10
We can now generate the basic seed population of synthetic agents:
population <- make_agents(age_gender)The generated seed population now contains one row per synthetic agent.
head(population)## agent_id age_group gender
## <char> <char> <char>
## 1: Agent_01 18-64 Male
## 2: Agent_02 18-64 Male
## 3: Agent_03 18-64 Male
## 4: Agent_04 18-64 Male
## 5: Agent_05 18-64 Male
## 6: Agent_06 18-64 Male
We can verify that the generated population preserves the source distribution.
synthetic_population_to_contingency(population,
columns = c("age_group", "gender"))## age_group gender count
## 1 18-64 Male 10
## 2 18-64 Female 10
## 3 65+ Male 10
## 4 65+ Female 10
The population contains age and gender information but no education attribute.
Our goal is to assign education values while preserving known demographic relationships.
Supply a contingency table
The reference distribution is supplied as a contingency table. In real use, we would source contingency tables from high quality data sources (e.g., census data) representative of our regions of interest. In this example, we will generate an illustrative contingency table using hypothetical values.
contingency <- data.frame(
age_group = c(
"18-64", "18-64",
"18-64", "18-64",
"65+", "65+",
"65+", "65+"
),
gender = c(
"Male", "Male",
"Female", "Female",
"Male", "Male",
"Female", "Female"
),
education = c(
"Degree", "School",
"Degree", "School",
"Degree", "School",
"Degree", "School"
),
count = c(
60, 40,
55, 45,
30, 70,
25, 75
)
)The contingency table defines the expected education distribution within each age-group and gender combination.
For example:
18-64 Male Degree = 60% School = 40%
65+ Female Degree = 25% School = 75%
Create a ReplicaAdder
The assignment workflow is controlled using a
ReplicaAdder.
adder <- ReplicaAdder(
synth_pop = population,
contingency = contingency,
target_attribute = "education",
group_by = c(
"age_group",
"gender"
)
)The object contains:
the synthetic population;
a reference contingency table;
the target attribute to be assigned; and
the conditioning variables used during assignment.
Handle missing groups
Real-world contingency tables often do not contain every combination of characteristics found in a synthetic population. For example, a synthetic population may contain demographic groups that do not appear in the source data.
replica supports several strategies for handling missing
groups. The selected strategy is stored in the
missing_group_strategy slot.
adder@missing_group_strategy## [1] "borrow"
In the above example, the strategy is “borrow” (which is selected by default) that borrows information from nearby groups.
Other options are “overall” which uses the overall distribution of the target attribute and “error” which stops execution when a required group is missing. The most appropriate choice depends on the intended application and the completeness of the source data.
Run attribute assignment
The synthetic agents can now be enriched with an education attribute.
The assignment is performed using:
adder <- enhance(adder)The workflow:
resolves missing contingency groups;
calculates group-specific proportions;
converts proportions into agent assignments;
assigns attribute values; and
validates the resulting distribution.
The updated synthetic population is stored in
adder@synth_pop.
Inspect the enriched population
The synthetic population now contains the assigned
education attribute.
head(adder@synth_pop)## agent_id age_group gender education
## <char> <char> <char> <char>
## 1: Agent_01 18-64 Male Degree
## 2: Agent_02 18-64 Male Degree
## 3: Agent_03 18-64 Male Degree
## 4: Agent_04 18-64 Male Degree
## 5: Agent_05 18-64 Male Degree
## 6: Agent_06 18-64 Male School
We can examine the distribution of education values.
synthetic_population_to_contingency(adder@synth_pop,
columns = "education")## education count
## 1 Degree 17
## 2 School 23
The population has been enriched while preserving the demographic relationships specified in the reference contingency table.
We can also reconstruct the resulting contingency table:
synthetic_population_to_contingency(
adder@synth_pop,
columns = c("age_group", "gender","education"))## age_group gender education count
## 1 18-64 Male Degree 6
## 2 18-64 Male School 4
## 3 18-64 Female School 4
## 4 18-64 Female Degree 6
## 5 65+ Male School 7
## 6 65+ Male Degree 3
## 7 65+ Female Degree 2
## 8 65+ Female School 8
The assigned education values approximately reproduce the proportions defined in the reference contingency table.
Key takeaways
In this vignette we:
created a synthetic population;
defined a reference contingency table;
configured a
ReplicaAdder;assigned a new attribute using
enhance();explored strategies for handling missing groups;
added marginal distributions; and
verified the resulting synthetic population.
These tools provide a flexible framework for enriching synthetic populations using aggregate demographic data.
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
