Skip to content

Commit

Permalink
Reformat, rework the documentation, and fix issues with data writing
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasThelen committed Apr 9, 2022
1 parent d2aa1f0 commit 2336af1
Show file tree
Hide file tree
Showing 34 changed files with 1,447 additions and 1,210 deletions.
14 changes: 7 additions & 7 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ Remotes:
edgararuiz/gregorian,
jimhester/lintr
Imports:
covr,
dplyr,
knitr,
uuid,
R6,
testthat,
tibble,
remotes,
gregorian,
readr
readr,
dplyr
Suggests:
lintr
lintr,
covr,
knitr,
testthat,
rmarkdown
VignetteBuilder: knitr
104 changes: 46 additions & 58 deletions R/Simulation.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,66 +9,54 @@
#' @section Methods:
#' \describe{
#' \item{\code{run_model()}}{Runs the simulation}
#' \item{\code{show_results(dependent_variable)}}{Displays the time dependant variables post-simulation}.
#' }
simulation <- R6::R6Class("simulation",
public = list(
start_date = NA,
end_date = NA,
villages = NA,
writer=NA,
public = list(
start_date = NA,
end_date = NA,
villages = NA,
writer = NA,

#' Creates a new Simulation instance
#'
#' @description Creates a new simulation object to control the experiment
#' @param start_date The date to start the simulation
#' @param end_date The date that the simulation should end
#' @param villages A list of villages that will be simulated
#' @param writer The data writer to be used with the villages
initialize = function(start_date,
end_date,
villages,
writer=data_writer$new()) {
self$villages <- villages
self$start_date <- gregorian::as_gregorian(start_date)
self$end_date <- gregorian::as_gregorian(end_date)
self$writer <- writer
},
#' Creates a new Simulation instance
#'
#' @description Creates a new simulation object to control the experiment
#' @param start_date The date to start the simulation
#' @param end_date The date that the simulation should end
#' @param villages A list of villages that will be simulated
#' @param writer The data writer to be used with the villages
initialize = function(start_date,
end_date,
villages,
writer = villager::data_writer$new()) {
self$villages <- villages
self$start_date <- gregorian::as_gregorian(start_date)
self$end_date <- gregorian::as_gregorian(end_date)
self$writer <- writer
},

#' Runs the simulation
#'
#' @return None
run_model = function() {
total_days <- gregorian::diff_days(self$start_date, self$end_date)
for (village in self$villages) {
village$set_initial_state(self$start_date)
}
# Loop over each village and run the user defined initial condition function
current_date <- gregorian::add_days(self$start_date, 1)
date_diff <- gregorian::diff_days(current_date, self$end_date)
total_days_passed <- 1
while (date_diff >= 0) {
# Iterate the villages a single time step
for(village in self$villages) {
village$propagate(current_date, total_days_passed)
self$writer$write(village$current_state, village$name)
total_days_passed <- total_days_passed + 1
}
# Add '1' to the current day
current_date <- gregorian::add_days(current_date, 1)
date_diff <- gregorian::diff_days(current_date, self$end_date)
}
},

#' Prints the plots of the data from each village in the simulator
#'
#' @details This should be done better; the plots look like garbage
#' @param dependent_variable The
#' @return None
show_results = function(dependent_variable = "population") {
for (village in self$villages) {
print(village$plot(dependent_variable))
}
}
)
#' Runs the simulation
#'
#' @return None
run_model = function() {
total_days <- gregorian::diff_days(self$start_date, self$end_date)
for (village in self$villages) {
village$set_initial_state(self$start_date)
}
# Loop over each village and run the user defined initial condition function
current_date <- gregorian::add_days(self$start_date, 1)
date_diff <- gregorian::diff_days(current_date, self$end_date)
total_days_passed <- 1
while (date_diff >= 0) {
# Iterate the villages a single time step
for (village in self$villages) {
village$propagate(current_date, total_days_passed)
self$writer$write(village$current_state, village$name)
total_days_passed <- total_days_passed + 1
}
# Add '1' to the current day
current_date <- gregorian::add_days(current_date, 1)
date_diff <- gregorian::diff_days(current_date, self$end_date)
}
}
)
)
122 changes: 71 additions & 51 deletions R/data_writer.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,85 @@
#' @title Data Writer
#' @docType class
#' @description A class responsible for the simulation data to disk.
#' @details This class can be subclasses to provide advanced data writing to other data sources. This should also be subclassed if the winik and resource
#' classes are subclasses, to write any addional fields to the data source.
#' @details This class can be subclasses to provide advanced data writing to other data sources. This should also
#' be subclassed if the winik and resource classes are subclasses, to write any addional fields to the data source.
#' @field results_directory The folder where the simulation resulst are written to
#' @field winik_filename The location where the winiks are written to
#' @field resource_filename The location where the resources are written to
#' @section Methods:
#' \describe{
#' \item{\code{write()}}{Writes the winik and resources to disk.}
#' }
data_writer <- R6::R6Class("data_writer",
public = list(results_directory=NULL,
winik_filename=NULL,
resource_filename=NULL,
data_writer <- R6::R6Class(
"data_writer",
public = list(
results_directory = NULL,
winik_filename = NULL,
resource_filename = NULL,

#' Create a new data writer.
#'
#' @description Creates a new data writer object that has optional paths for data files.
#' @param results_directory The directory where the results file is written to
#' @param winik_filename The name of the file for the winik data
#' @param resource_filename The name of the file for the resource data
#' @return A new winik object
initialize = function(results_directory='results', winik_filename='winiks.csv', resource_filename='resources.csv') {
self$results_directory <- results_directory
self$winik_filename <- winik_filename
self$resource_filename <- resource_filename
#' Create a new data writer.
#'
#' @description Creates a new data writer object that has optional paths for data files.
#' @param results_directory The directory where the results file is written to
#' @param winik_filename The name of the file for the winik data
#' @param resource_filename The name of the file for the resource data
#' @return A new winik object
initialize = function(results_directory = "results",
winik_filename = "winiks.csv",
resource_filename = "resources.csv") {
self$results_directory <- results_directory
self$winik_filename <- winik_filename
self$resource_filename <- resource_filename

# Check that the directory exists, delete it if it does
res_folder <- file.path(self$results_directory)
if (file.exists(res_folder)) {
unlink(res_folder, recursive = TRUE)
}
dir.create(res_folder, recursive = TRUE)
},
# Check that the directory exists, delete it if it does
res_folder <- file.path(self$results_directory)
if (file.exists(res_folder)) {
unlink(res_folder, recursive = TRUE)
}
dir.create(res_folder, recursive = TRUE)
},

#' Writes a village's state to disk.
#'
#' @description Takes a state an the name of a village and writes the winiks and resources to disk
#' @param state The village's village_state that's being written
#' @param village_name The name of the village. This is used to create the data directory
#' @return None
write = function(state, village_name) {
# Check that the village_name folder where the csv files are written to exists; create it if it doesn't
res_folder <- file.path(self$results_directory, village_name)
if (!file.exists(res_folder)) {
dir.create(res_folder, recursive = TRUE)
}
# Write the winiks to disk
winik_path <- file.path(res_folder, self$winik_filename)
if (!file.exists(winik_path)) {
file.create(winik_path, recursive = TRUE)
}
readr::write_csv(state$winik_states, winik_path, na="NA", append=TRUE)
#' Writes a village's state to disk.
#'
#' @description Takes a state an the name of a village and writes the winiks and resources to disk
#' @param state The village's village_state that's being written
#' @param village_name The name of the village. This is used to create the data directory
#' @return None
write = function(state, village_name) {
# Check that the village_name folder where the csv files are written to exists; create it if it doesn't
res_folder <- file.path(self$results_directory, village_name)
if (!file.exists(res_folder)) {
dir.create(res_folder, recursive = TRUE)
}
# Write the winiks to disk
winik_path <- file.path(res_folder, self$winik_filename)
append <- TRUE
col_names <- FALSE
if (!file.exists(winik_path)) {
file.create(winik_path, recursive = TRUE)
append <- FALSE
col_names <- TRUE
}
readr::write_csv(state$winik_states,
file = winik_path,
na = "NA",
append = append,
col_names = col_names)

# Write the resources
resources_path <- file.path(res_folder, self$resource_filename)
if (!file.exists(resources_path)) {
file.create(resources_path, recursive = TRUE)
}
readr::write_csv(state$resource_states, resources_path, na="NA", append=TRUE)
}
)
)
# Write the resources
append <- TRUE
col_names <- FALSE
resources_path <- file.path(res_folder, self$resource_filename)
if (!file.exists(resources_path)) {
file.create(resources_path, recursive = TRUE)
append <- FALSE
col_names <- TRUE
}
readr::write_csv(state$resource_states,
file = resources_path,
na = "NA",
append = append,
col_names = col_names)
}
)
)
2 changes: 1 addition & 1 deletion R/model_data.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
model_data <- R6::R6Class("model_data",
public = list(
#' @field events Any events that need to be tracked
events=NULL,
events = NULL,
#' @description Creates a new model_data object
#' @return A new model data object
initialize = function() {
Expand Down
46 changes: 22 additions & 24 deletions R/resource.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,30 @@
#' @section Methods:
#' \describe{
#' \item{\code{initialize()}}{Create a new resource}
#' \item{\code{as_tibble()}}{Represents the current state of the resource as a tibble}
#' \item{\code{as_table()}}{Represents the current state of the resource as a tibble}
#' }
resource <- R6::R6Class("resource",
cloneable = TRUE,
public = list(
name = NA,
quantity = NA,
cloneable = TRUE,
public = list(
name = NA,
quantity = NA,

#' Creates a new resource.
#'
#' @description Creates a new resource object
#' @param name The name of the resource
#' @param quantity The quantity present
initialize = function(name=NA, quantity=0) {
self$name <- name
self$quantity <- quantity
},
#' Creates a new resource.
#'
#' @description Creates a new resource object
#' @param name The name of the resource
#' @param quantity The quantity present
initialize = function(name = NA, quantity = 0) {
self$name <- name
self$quantity <- quantity
},

#' 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
))
}
)
#' 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))
}
)
)
Loading

0 comments on commit 2336af1

Please sign in to comment.