The demography module provides event functions for simulating the dynamics of evolving urban population and their households at an individual-based level. These events are responsible for household formation (marriage, cohabitation, leaving parental home), household dissolutions (separation, divorce, break up), household expansion (birth).
Note that, there are hard-coded rules that can be modified, such as the
age range in which females can bare a child. See constants.R
.
assign_reference()
with World$get()
.This version is only compatible with dymiumCore version 0.1.4.
household_formation
functions and new Entity$add()
.modules
options. Event scipts should only
export run
and REQUIRED_MODELS
.R packages: dymiumCore, data.table, modules, here, checkmate, R6.
Increase age of all Individual
agents by 1, which is equivalent to one
year.
If there are any attributes that should be updated depending on the age of agent then it can be implemented inside this event. For example, currently there are three rules that are active. These rules update marital status, education, and labour force status of the agent once it has reached some certain age thresholds. All agents aged 16 and above can be in a relationship (a marriage or a cohabitation) hence once they turn 16 their marital status will be changed from “not applicable” to “never married” which allows them to be considered when the marriage event and the cohabitation event are being simulated.
event_demography_age <- modules::use(here::here("modules/demography/age.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
create_toy_world()
#> [19:33:29] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_age <- modules::use(here::here("modules/demography/age.R"))
# summary of 'age' attribute before ageing
summary(world$entities$Individual$get_attr(x = "age"))
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> 0.00 22.00 40.00 38.78 55.00 90.00
world %>%
event_demography_age$run(.)
#> [19:33:30] INFO demography event_demography_age$run: Running Age
# summary of 'age' attribute after ageing
summary(world$entities$Individual$get_attr(x = "age"))
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> 1.00 23.00 41.00 39.78 56.00 91.00
The birth event adds newborns to the population by simulating the chance for fertile individual agents to give birth.
Newborns inherit some attributes from their mothers such as household id
and dwelling id. Their mother id and father id fields will be set at the
time of their birth and a new unique id will be assigned to them. If
your Individual
agents have more attributes than the basic ones in
toy_individuals
then you should modify the birth
event script to set
the default values for those extra attributes. See create_newborns()
inside the event script.
event_demography_birth <- modules::use(here::here("modules/demography/birth.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:3] "fertility" "birth_multiplicity" "birth_sex_ratio"
model <- list(fertility = list(yes = 0.05, no = 0.95),
birth_multiplicity = list("single" = 0.97, "twins" = 0.03),
birth_sex_ratio = list(male = 0.51, female = 0.49))
NULL
or it can be a named list which determines
the number of individual agents to under go the fertility event. For
example, if a list list(yes = 100)
it will garantee that there are
100 individual agents that will give birth.create_toy_world()
#> [19:33:30] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_birth <- modules::use(here::here("modules/demography/birth.R"))
# Total number of individuals before a run of the birth event
world$entities$Individual$n()
#> [1] 373
world %>%
event_demography_birth$run(., model = model)
#> [19:33:30] INFO demography event_demography_birth$run: Running Birth
#> Loading required namespace: testthat
#> [19:33:30] INFO demography event_demography_birth$run: There are 5 births from 5 birth givers.
# Total number of individuals after a run of the birth event
world$entities$Individual$n()
#> [1] 378
event_demography_death <- modules::use(here::here("modules/demography/death.R"))
event_demography_death
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr "death"
World
object.model <- list(death = list(yes = 0.1, no = 0.9))
NULL
or a named list.Removes dying individual agents from the individual database and also updates any affected attributes (such as marital status, household size) the agents that are related to the dying agents.
The marital status of those individual agents whom their partner has
died will be labelled as “widowed”. To retrive the data of all agents
that have been removed you through the death event use the
get_removed_data()
method.
create_toy_world()
#> [19:33:30] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_death <- modules::use(here::here("modules/demography/death.R"))
# Total number of individuals before a run of the death event
world$entities$Individual$n()
#> [1] 373
# Distribution of marital status before a run of the death event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 22 174 108 53 6
#> widowed
#> 10
world %>%
event_demography_death$run(., model = model)
#> [19:33:30] INFO demography event_demography_death$run: Running Death
#> [19:33:30] INFO demography event_demography_death$run: There are 47 deaths
# Total number of individuals after a run of the death event
world$entities$Individual$n()
#> [1] 326
# Distribution of marital status after a run of the death event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 20 132 90 48 5
#> widowed
#> 31
This event forms marriage relationships between cohabiting couples and any two opposite-sex individuals that are not in a relationship. After the marriage is formed, the newly wedded couple then decide whether to form a new household or to merge their households into one. When forming a new household, regardless of their household formation decision, any related individuals (i.e. dependent children) to both individuals will also follow to the new household.
As you can see there are four models that shall be supplied to determine
the likelihood in each stage of the marriage event. The first stage is
to marry cohabiting couples based on the likelihood produces by the
marriage_cohab_male
model. The second stage is to marry eligible,
single individual agents. The probabilities for the individual agents to
enter the marital market come from the Monte Carlo simulation result
performed using the marriage_no_cohab_male
and
marriage_no_cohab_female
models on the individual agents’ attributes.
Then all participating individual agents are paired based on a given
rule. The rule can be as simple as all agents prefer to match with an
agent that has the minimum age difference to theirs. See
StochasticMarriageMarket
and OptimalMarriageMarket
for the matching
strategies available in modules/demography/marriage.R
. Note that, if
there are more agents of one gender than other in the marital market
then the number of maximum matches will be equal to the number of
individual agents with the lesser number. Those who are not matched will
remain single after the event has ended. The current implementation
doesn’t include marriages between same-sex couples. After the matching
step, all newly formed couples will decide whether they will form a new
household (both agents leave their current households) or for the wife
and her related individuals to join her husband’s household. The current
implementation applies a very simple rule which is likely to be wrong
and should be replaced if there is a better assumption or model. The
current rule is that for all newly wedded couples if their male partner
aged more than the number given in husbandAgeRuleToCreateNewHousehold
they will create a new household.
TLDR;
event_demography_marriage <- modules::use(here::here("modules/demography/marriage.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:3] "marriage_cohab_male" "marriage_no_cohab_male" ...
model <- list(
marriage_cohab_male = list(yes = 0.1, no = 0.9),
marriage_no_cohab_male = list(yes = 0.1, no = 0.9),
marriage_no_cohab_female = list(yes = 0.1, no = 0.9)
)
create_toy_world()
#> [19:33:31] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_marriage <- modules::use(here::here("modules/demography/marriage.R"))
# Distribution of marital status before a run of the marriage event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 22 174 108 53 6
#> widowed
#> 10
world %>%
event_demography_marriage$run(., model = model)
#> [19:33:31] INFO demography event_demography_marriage$run: Running Marriage
#> [19:33:31] INFO demography event_demography_marriage$run: 4 males and 5 are entering the marriage market (ratio=0.8:1).
#> [19:33:31] INFO demography event_demography_marriage$run: There were 6 marriages occured (priorly cohabited: 2, did not cohabited: 4)
# Distribution of marital status before a run of the marriage event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 22 186 98 53 4
#> widowed
#> 10
Separation is the stage before a couple is officially divorced. In the Australian context, all married couples that would like to get divorced must register their separtion one year prior to becoming legally divorced. Hence, this event simulates that process.
Separation is the first step before couples can be officially divorced. This module assume that no couples will recoupled once they have decided to separate.
event_demography_separation <- modules::use(here::here("modules/demography/separation.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:4] "separate_male" "separate_child_custody" "separate_hhtype" ...
model <-
list(
separate_male = list(yes = 0.1, no = 0.9),
separate_child_custody = list(male = 0.2, female = 0.8),
separate_hhtype = list(lone = 0.5, group = 0.5),
separate_hf_random_join = list("1" = 0.4, "2" = 0.3, "3" = 0.2, "4" = 0.1)
)
create_toy_world()
#> [19:33:32] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_separation <- modules::use(here::here("modules/demography/separation.R"))
# Distribution of marital status before a run of the marriage event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 22 174 108 53 6
#> widowed
#> 10
world %>%
event_demography_separation$run(., model = model)
#> [19:33:32] INFO demography event_demography_separation$run: Running Separation
#> [19:33:32] INFO demography event_demography_separation$run: #seperating couples: 5
# Distribution of marital status before a run of the marriage event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 22 164 108 53 16
#> widowed
#> 10
When divorce is triggered for a separted individual, his/her ex-partner will also under go divorce if the marital status of his/her ex-partner is still ‘separated’.
event_demography_divorce <- modules::use(here::here("modules/demography/divorce.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:2] "divorce_male" "divorce_female"
model <- list(
divorce_male = list(yes = 0.5, no = 0.9),
divorce_female = list(yes = 0.5, no = 0.9)
)
create_toy_world()
#> [19:33:32] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_divorce <- modules::use(here::here("modules/demography/divorce.R"))
# Distribution of marital status before a run of the marriage event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 22 174 108 53 6
#> widowed
#> 10
world %>%
event_demography_divorce$run(., model = model)
#> [19:33:32] INFO demography event_demography_divorce$run: Running Divorce
#> [19:33:32] INFO demography event_demography_divorce$run: #individuals to divorce: 3
# Distribution of marital status before a run of the marriage event
table(world$entities$Individual$get_attr("marital_status"))
#>
#> divorced married never married not applicable separated
#> 25 174 108 53 3
#> widowed
#> 10
Form cohabitation relationships. Everything is the same with marriage in term of the steps.
event_demography_cohabit <- modules::use(here::here("modules/demography/cohabit.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:2] "cohabitation_male" "cohabitation_female"
model <- list(
cohabitation_male = list(yes = 0.1, no = 0.9),
cohabitation_female = list(yes = 0.1, no = 0.9)
)
create_toy_world()
#> [19:33:33] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_cohabit <- modules::use(here::here("modules/demography/cohabit.R"))
# people with partner before the cohabitation event
table(!is.na(world$entities$Individual$get_attr("partner_id")))
#>
#> FALSE TRUE
#> 177 196
world %>%
event_demography_cohabit$run(., model = model)
#> [19:33:33] INFO demography event_demography_cohabit$run: Running Cohabit
#> [19:33:33] INFO demography event_demography_cohabit$run: 2 males and 3 females enter the cohabitation market (ratio = 0.67:1).
#> [19:33:33] INFO demography event_demography_cohabit$run: 2 newly cohabited couples were formed.
# people with partner after running the cohabitation event
table(!is.na(world$entities$Individual$get_attr("partner_id")))
#>
#> FALSE TRUE
#> 173 200
Breakup ends cohabitation relationships.
event_demography_breakup <- modules::use(here::here("modules/demography/breakup.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:4] "breakup" "breakup_child_custody" "breakup_hhtype" ...
model <-
list(
breakup = list(yes = 0.1, no = 0.9),
breakup_child_custody = list(male = 0.2, female = 0.8),
breakup_hhtype = list(lone = 0.5, group = 0.5),
breakup_hf_random_join = list("1" = 0.4, "2" = 0.3, "3" = 0.2, "4" = 0.1)
)
create_toy_world()
#> [19:33:33] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_breakup <- modules::use(here::here("modules/demography/breakup.R"))
# Total number of individuals with partner before
table(is.na(world$entities$Individual$get_attr("partner_id")))
#>
#> FALSE TRUE
#> 196 177
world %>%
event_demography_breakup$run(., model = model)
#> [19:33:34] INFO demography event_demography_breakup$run: Running Breakup
#> [19:33:34] INFO demography event_demography_breakup$run: There are 2 couples who broke up
# Total number of individuals with partner after
table(is.na(world$entities$Individual$get_attr("partner_id")))
#>
#> FALSE TRUE
#> 192 181
This simulates young adults leaving their parental home.
This should not include the proportion of people whom leave home to get married or to live with their partner as it has been accounted for in the marriage event and the cohabitation event.
event_demography_leavehome <- modules::use(here::here("modules/demography/leavehome.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:4] "leavehome_male" "leavehome_female" "leavehome_hhtype" ...
list(1 = 0.5, 2
= 0.3, 3 = 0.1, 4 = 0.1)
there is a 50% chance that an
individual leaving their parental home will find a single
household to join and a 30% chance to join a two-person
household and so on.model <- list(leavehome_male = list(yes = 0.3, no = 0.7),
leavehome_female = list(yes = 0.2, no = 0.8),
leavehome_hhtype = list(lone = 0.2, group = 0.8),
leavehome_hf_random_join = list("1" = 0.5, "2" = 0.3, "3" = 0.1, "4" = 0.1))
NULL
or a named list.create_toy_world()
#> [19:33:34] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_leavehome <- modules::use(here::here("modules/demography/leavehome.R"))
# Total number of households before
world$entities$Household$n()
#> [1] 144
world %>%
event_demography_leavehome$run(., model = model)
#> [19:33:34] INFO demography event_demography_leavehome$run: Running Leavehome
#> [19:33:35] INFO demography event_demography_leavehome$run: There are 13 individuals leaving their parental homes.
# Total number of households after
world$entities$Household$n()
#> [1] 146
Add a migrant population to the main population.
The migrant population will be assigned new unique ids once it is added. Note that all migrants should have all the same attribute columns (as well as their types) as the main population it is being added to.
event_demography_migration <- modules::use(here::here("modules/demography/migration.R"))
#> run:
#> function(world, model = NULL, target = NULL, time_steps = NULL)
#>
#>
#> REQUIRED_MODELS:
#> chr [1:2] "migrant_individuals" "migrant_households"
model <- list(
migrant_individuals = dymiumCore::toy_individuals,
migrant_households = dymiumCore::toy_households
)
target = 100
create_toy_world()
#> [19:33:35] WARN dymiumCore .subset2(public_bind_env, "initialize"): Creating a `hhsize` column in `hh_data` as it is not provided.
event_demography_migration <- modules::use(here::here("modules/demography/migration.R"))
# Total number of households and individuals before
world$entities$Household$n()
#> [1] 144
world$entities$Individual$n()
#> [1] 373
world %>%
event_demography_migration$run(., model = model, target = target)
#> [19:33:35] INFO demography event_demography_migration$run: Running Migration
#> [19:33:35] INFO demography event_demography_migration$run: 100 migrant households are joining to the population.
#> [19:33:35] INFO demography event_demography_migration$run: There are 100 migrant households which made up of 271 individuals (avg. hhsize = 2.71)
#> [19:33:35] WARN dymiumCore Pop$add_population: Creating `hhsize` as it is not provided with `hh_data`.
# Total number of households and individuals after
world$entities$Household$n()
#> [1] 244
world$entities$Individual$n()
#> [1] 644
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.