library(villager)
library(leaflet)
#> Warning: package 'leaflet' was built under R version 4.0.5
To create agents (winiks) that have more properties than the ones provided by villager, subclass the winik
class into a new R6 class. Once sub-classed, additional properties can be added to the winik which can be used in the subsequent model. The new winik class can be tied to individual villages. This gives flexibility to model populations differently when running under the same simulation.
To add new members to the winik class,
initialize
functionas_table
functionTo give a complete example of the sublclassing process, consider an extended agent. In this case the agent has an additional property, gps_coordinates
, that’s a named list of latitude and longitude coordinates: [lat=1234, long=1234]. Each coordinate gets updated by the model each day by a random number.
To start the base class off, the original class was copied to save time with the member variable definitions.
R6::R6Class("winik",
gps_winik <-inherit = villager::winik,
public = list(
age = NULL,
alive = NULL,
children = NULL,
father_id = NULL,
first_name = NULL,
gender = NULL,
health = NULL,
identifier = NULL,
last_name = NULL,
mother_id = NULL,
partner = NULL,
profession = NULL,
latitude = NULL,
longitude = NULL,
initialize = function(identifier = NA,
first_name = NA,
last_name = NA,
age = 0,
mother_id = NA,
father_id = NA,
partner = NA,
children = vector(mode = "character"),
gender = NA,
profession = NA,
alive = TRUE,
health = 100,
latitude = 0,
longitude = 0) {
$initialize(identifier,
super
first_name,
last_name,
age,
mother_id,
father_id,
partner,
children,
gender,
profession,
alive,
health)$latitude <- latitude
self$longitude <- longitude
self
},
as_table = function() {
data.frame(
winik_table <-age = self$age,
alive = self$alive,
father_id = self$father_id,
first_name = self$first_name,
gender = self$gender,
health = self$health,
identifier = self$identifier,
last_name = self$last_name,
mother_id = self$mother_id,
partner = self$partner,
profession = self$profession,
latitude = self$latitude,
longitude = self$longitude
)return(winik_table)
}
) )
We’ll create the initial population of one Agent in the initial_condition
function, which gets run before the model starts. The initial starting location is in Los Angeles, Ca. Note that the new gps_winik
class is used to instantiate the agent rather than the library provided winik
class.
function(current_state, model_data, winik_mgr, resource_mgr) {
initial_condition <-# Create the initial villagers
gps_winik$new(first_name="Lewis", last_name="Taylor", age=9125, latitude=33.8785486, longitude=-118.0434921)
test_agent <-$add_winik(test_agent)
winik_mgr }
Each day, the model picks a number between 0.0000001 and 0.0000003 and increments gps_coordinate
on the winik.
function(current_state, previous_state, model_data, winik_mgr, resource_mgr) {
test_model <-# Loop over all the winiks (just one at the moment)
for (winik in winik_mgr$get_living_winiks()) {
# Generate new coordinates
winik$latitude + runif(1, 0.01, 0.03)
latitude <- winik$longitude + runif(1, 0.01, 0.03)
longitude <-$latitude <- latitude
winik$longitude <- longitude
winik
} }
Finally, we’ll create and run a simulation with a duration of 10 days.
village$new("Test_Village", initial_condition, test_model, gps_winik)
los_angeles <- simulation$new(10, list(los_angeles))
simulator <-$run_model() simulator
# Load in data
readr::read_csv("results/Test_Village/winiks.csv")
agent_data <-#>
#> ── Column specification ────────────────────────────────────────────────────────
#> cols(
#> age = col_double(),
#> alive = col_logical(),
#> father_id = col_logical(),
#> first_name = col_character(),
#> gender = col_logical(),
#> health = col_double(),
#> identifier = col_character(),
#> last_name = col_character(),
#> mother_id = col_logical(),
#> partner = col_logical(),
#> profession = col_logical(),
#> latitude = col_double(),
#> longitude = col_double(),
#> step = col_double()
#> )
# Grab just the location data
data.frame(latitude = agent_data$latitude, longitude = agent_data$longitude)
agent_location <-
# create a map
::leaflet() %>%
leaflet leaflet::addTiles() %>% # Add default OpenStreetMap map tiles
leaflet::addMarkers (data = agent_location) # Add agent locations