knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = TRUE ) library(dymiumCore) # knitr::opts_knit$set(root.dir = normalizePath(rprojroot::find_rstudio_root_file()))
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"))
event_demography_age
create_toy_world() 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")) world %>% event_demography_age$run(.) # summary of 'age' attribute after ageing summary(world$entities$Individual$get_attr(x = "age"))
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"))
event_demography_birth
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() 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() world %>% event_demography_birth$run(., model = model) # Total number of individuals after a run of the birth event world$entities$Individual$n()
event_demography_death <- modules::use(here::here("modules/demography/death.R"))
event_demography_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() 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() # Distribution of marital status before a run of the death event table(world$entities$Individual$get_attr("marital_status")) world %>% event_demography_death$run(., model = model) # Total number of individuals after a run of the death event world$entities$Individual$n() # Distribution of marital status after a run of the death event table(world$entities$Individual$get_attr("marital_status"))
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"))
event_demography_marriage
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() 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")) world %>% event_demography_marriage$run(., model = model) # Distribution of marital status before a run of the marriage event table(world$entities$Individual$get_attr("marital_status"))
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"))
event_demography_separation
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() 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")) world %>% event_demography_separation$run(., model = model) # Distribution of marital status before a run of the marriage event table(world$entities$Individual$get_attr("marital_status"))
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"))
event_demography_divorce
model <- list( divorce_male = list(yes = 0.5, no = 0.9), divorce_female = list(yes = 0.5, no = 0.9) )
create_toy_world() 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")) world %>% event_demography_divorce$run(., model = model) # Distribution of marital status before a run of the marriage event table(world$entities$Individual$get_attr("marital_status"))
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"))
event_demography_cohabit
model <- list( cohabitation_male = list(yes = 0.1, no = 0.9), cohabitation_female = list(yes = 0.1, no = 0.9) )
create_toy_world() 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"))) world %>% event_demography_cohabit$run(., model = model) # people with partner after running the cohabitation event table(!is.na(world$entities$Individual$get_attr("partner_id")))
Breakup ends cohabitation relationships.
event_demography_breakup <- modules::use(here::here("modules/demography/breakup.R"))
event_demography_breakup
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() 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"))) world %>% event_demography_breakup$run(., model = model) # Total number of individuals with partner after table(is.na(world$entities$Individual$get_attr("partner_id")))
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"))
event_demography_leavehome
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() event_demography_leavehome <- modules::use(here::here("modules/demography/leavehome.R")) # Total number of households before world$entities$Household$n() world %>% event_demography_leavehome$run(., model = model) # Total number of households after world$entities$Household$n()
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"))
event_demography_migration
model <- list( migrant_individuals = dymiumCore::toy_individuals, migrant_households = dymiumCore::toy_households )
target = 100
create_toy_world() event_demography_migration <- modules::use(here::here("modules/demography/migration.R")) # Total number of households and individuals before world$entities$Household$n() world$entities$Individual$n() world %>% event_demography_migration$run(., model = model, target = target) # Total number of households and individuals after world$entities$Household$n() world$entities$Individual$n()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.