# extending-resources

    library(plotly)
    #> Loading required package: ggplot2
    #>
    #> Attaching package: 'plotly'
    #> The following object is masked from 'package:ggplot2':
    #>
    #>     last_plot
    #> The following object is masked from 'package:stats':
    #>
    #>     filter
    #> The following object is masked from 'package:graphics':
    #>
    #>     layout
    library(villager)

# Extending Resources

To create resources that have additional properties, subclass the `resource` class.

To add new members to the resource class,

1. Copy the resource class source definition
2. Create the new member variable
3. Add it as a parameter to the `initialize` function
4. Make an entry for it in the `as_table` function

## Resource with an expiration date

To demonstrate how to subclass and run a model with a custom resource class, consier an example of corn and rice resources that expire. To do this, a new variable is added to the resource class, `creation_date` which gets updated when the resource is created. When the model runs, the date at each time step is used to check against the creation date of each resource.

### Custom resource class

    resource_expiration <- R6::R6Class("resource",
      cloneable = TRUE,
      public = list(
        name = NA,
        quantity = NA,
        creation_date = NA,

        #' Creates a new resource.
        #'
        #' @description Creates a new resource object
        #' @param name The name of the resource
        #' @param quantity The quantity present
        #' @param creation_date The date that the resource was created
        initialize = function(name = NA, quantity = 0, creation_date=NA) {
          self$name <- name
          self$quantity <- quantity
          self$creation_date <- creation_date # New member variable to track the creation date
        },

        #' Returns a data.frame representation of the resource
        #'
        #' @return A data.frame of resources

        as_table = function() {
          return(data.frame(name = self$name, quantity = self$quantity))
        }
      )
    )

### Initial Condition

The initial condition is a village that has two resource types, corn and rice.

    initial_condition <- function(current_state, model_data, winik_mgr, resource_mgr) {
      for (i in 1:10) {
        name <- runif(1, 0.0, 100)
        new_winik <- winik$new(first_name <- name, last_name <- "Smith")
        winik_mgr$add_winik(new_winik)
      }
      # Create two new resources at the current date (The first day)
      corn <- resource_expiration$new("Corn", 10, current_state$step)
      rice <- resource_expiration$new("Rice", 20, current_state$step)
      resource_mgr$add_resource(corn)
      resource_mgr$add_resource(rice)
    }

### Model

The model checks the current date against the expiration dates on each resource. When the threshold limits are reached, the quantity is set to zero.

    # Create the model that, each day, checks to see whether or not any resource expire
    model <- function(current_state, previous_state, model_data, winik_mgr, resource_mgr) {
      # Loop over all of the resources and check if any expire
      for (resource in resource_mgr$get_resources()) {
        # Figure out how many days have passed
        days_passed <- current_state$step - resource$creation_date
        if (resource$name == "Corn") {
          if (days_passed > 10 && resource$quantity > 0) {
            print("Setting Corn quantity to 0")
            resource$quantity <- 0
          }
        } else if (resource$name == "Rice" && resource$quantity > 0) {
          if (days_passed > 20) {
            print("Setting Rice quantity to 0")
            resource$quantity <- 0
          }
        }
      }
    }

### Running

With the required model components complete, we can create a simulation that runs for 15 days. By the end of it, there should be no more corn left, and the rice stocks should still be full.

    # Create the village and simulation
    coastal_village <- village$new("Expiring_Resources", initial_condition, model, resource_class=)
    simulator <- simulation$new(16, villages = list(coastal_village))
    simulator$run_model()
    #> [1] "Setting Corn quantity to 0"

### Results

A timeseries of each resource type is plotted below. The rice resource has clearly not expired while the corn resource has after 10 days.

    # Load in data
    time_series_data <- readr::read_csv("results/Expiring_Resources/resources.csv")
    #>
    #> ── Column specification ────────────────────────────────────────────────────────
    #> cols(
    #>   name = col_character(),
    #>   quantity = col_double(),
    #>   step = col_double()
    #> )

    # Get unique dates
    unique_step<- sort(unique(time_series_data$step))

    # Get corn & rice quantities and dates
    corn_date_quantities <- dplyr::filter(time_series_data, name=="Corn")
    rice_date_quantities <- dplyr::filter(time_series_data, name=="Rice")

    # create data frame for sorted data
    reordered_time_series <- data.frame(step = unique_step, Corn = 0, Rice = 0)
    for (i in 1:nrow(reordered_time_series)){
      reordered_time_series[i,2] = corn_date_quantities[which(corn_date_quantities$step == reordered_time_series$step[i]),2]
      reordered_time_series[i,3] = rice_date_quantities[which(rice_date_quantities$step == reordered_time_series$step[i]),2]
    }

    # Plot graph
    plotly::plot_ly(reordered_time_series, x = ~step) %>%
      plotly::add_trace(y = ~Corn, name = 'Corn', type = 'scatter', mode = 'lines') %>%
      plotly::add_trace(y = ~Rice, name = 'Rice', type = 'scatter', mode = 'lines') %>%
      plotly::layout(title = 'Resource Counts', xaxis = list(title = 'Time Step'),
           yaxis = list(title = 'Quantity'), legend = list(title=list(text='Crop Type')))
    #> Warning: `arrange_()` is deprecated as of dplyr 0.7.0.
    #> Please use `arrange()` instead.
    #> See vignette('programming') for more help
    #> This warning is displayed once every 8 hours.
    #> Call `lifecycle::last_warnings()` to see where this warning was generated.