knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) # avoid check where vignette filename must equal the vignette title options(rmarkdown.html_vignette.check_title = FALSE)
pkg = 'flowdiagramr' #so we can easily switch names library(pkg, character.only = TRUE)
In this vignette, we discuss a few additional topics that might be of interest to some, but likely not all users.
The developers of r pkg
have also been developing an R package called modelbuilder which allows users to graphically build and analyze compartmental simulation models. In fact, r pkg
started as a function inside modelbuilder to draw diagrams of user-built models. At some point, we decided to make r pkg
a stand-alone package. But it still works with and is used by modelbuilder. If you use modelbuilder and want to use r pkg
to generate a diagram for that model outside the auto-generated one shown inside modelbuilder, here are the steps.
Once you built a model with modelbuilder, you can save it as an Rds
file. This file contains a single object, the user-created model specified as a list object. Since modelbuilder models and r pkg
models are slightly different, we provide a convenience function that converts one format into the other.
This is a very simple process, and is done with the function convert_from_modelbuilder
. This function takes as input the modelbuilder object and produces a list that conforms to the r pkg
model specification. The following examples illustrate this.
Assume you built a basic SIR model with modelbuilder and saved it as an R
object inside an .Rds
file.
First, we load the file and assign it to some variable.
mbmodel <- readRDS('SIR_model.Rds')
Next, we convert the object.
mymodel <- convert_from_modelbuilder(mbmodel)
If you print the content, you can see it has the required model_list
with the variables
and flows
objects.
You can now use this model_list
object when you call prepare_diagram()
.
print(mymodel)
You can now proceed with the usual steps.
diagram_list <- prepare_diagram(model_list = mymodel) sir_diagram <- make_diagram(diagram_list) plot(sir_diagram)
Just to show one more example, this is a model from the modelbuilder example library called Complex ID control
. It is a model that includes a good number of details and allows exploration of different intervention strategies. If you are not too familiar with compartmental models yet, just consider it as an example that illustrates the work flow. You can find some more details about the model in the modelbuilder package, or even more details in another of our packages, DSAIDE, which is targeted toward learning about such infectious disease models.
First, we load the model, then convert it and print it.
mbmodel <- readRDS('Complex_ID_Control.Rds') mymodel <- convert_from_modelbuilder(mbmodel) print(mymodel)
As promised, this is a much more complex model. We don't expect the default diagram for this model to look great, but let's give it a try.
diagram_list <- prepare_diagram(mymodel) my_diagram <- make_diagram(diagram_list) plot(my_diagram)
The diagram is not ideal. But you now know how to make it better, once you have done the model conversion, you can use the usual approaches.
As an example, let's specify the layout for the variables/nodes. We can use the existing model_settings
object stored in mymodel
and can add varlocations
.
The rationale of how to place the variables is determined by the meaning of each of them and what makes logical sense. I'm not discussing this here, if you want to learn more about the model, see the Complex Control Scenarios app inside DSAIDE.
varlocations = matrix(data = c("","E","","", "", "", "A", "R", "S", "P", "", "", "", "", "I", "D", "", "Sv", "Iv", ""), nrow = 5, byrow = TRUE) model_settings = list(varlocations = varlocations)
diagram_list <- prepare_diagram(mymodel, model_settings) my_diagram <- make_diagram(diagram_list) plot(my_diagram)
This is better, but of course still not quite good enough. Fortunately, you have learned how to use r pkg
to fairly easily turn this into a publication-quality diagram r emoji::emoji("smile")
.
It is quite likely that the diagram you get back from make_diagram
contains a good bit of white space. This is often a problem when trying to use the figure in publications.
As example, consider the above diagram. If we write it into a file, then load the file and show it, it looks like this.
ggplot2::ggsave("sirdiag.png",sir_diagram)
knitr::include_graphics('sirdiag.png')
As you can see, the saved image file contains a lot of unwanted white space. There are different options you can use to change the white space. Here are some we are aware of.
One approach is to play with the margins of the gpplot object returned from make_diagram
until things look ok.
Here is an example:
#shrink top and bottom margins diag_new <- sir_diagram + ggplot2::theme(plot.margin = ggplot2::unit(c(-7,0,-7,0), "in"))
ggplot2::ggsave("sirdiag_new.png",diag_new)
knitr::include_graphics('sirdiag_new.png')
This looks better. You will likely have to fiddle a bit with the margin settings until you get it cropped the way you want.
magick
packageThe magick
package allows for automated trimming of a file.
This means you first need to save your diagram into a file, then load, trim and resave.
Here is an example
library(magick) fig <- magick::image_read("sirdiag.png") fig2 <- magick::image_trim(fig) magick::image_write(fig2,'sirdiag2.png')
knitr::include_graphics('sirdiag2.png')
The disadvantages of this approach is that you need to use another R package and that the cropping is very tight. The advantages are that the magick
package can do a lot more, so there might be some additional useful tweaks possible that you can apply to your figure to get it exactly the way you want.
By now, you are familiar with the main functions of r pkg
, namely prepare_diagram()
, update_diagram()
, make_diagram()
and write_diagram()
, as well as the add_flow()
function. The package contains additional helper functions. Those are generally not very useful by themselves and do work behind the scenes. However, a few might be occasionally useful, therefore we describe them briefly.
check_model_list()
- This function does what its name implies. It takes a model list, consisting of the variables
and flows
entry and checks if everything seems to make sense. If everything is fine, nothing is returned. Otherwise, a hopefully somewhat informative error message is provided.
check_model_settings()
- This function also does what its name implies r emoji::emoji('grin')
. It checks that the optional model_settings
list one can supply to prepare_diagram()
is correct.
check_dataframes()
- this function takes the diagram list one gets after running prepare_diagram()
and checks to make sure the variables
and flows
data frames are correct.
These checking functions are run behind the scenes as part of the the main functions. You will rarely need to call them directly, but we want to mention them just in case you find them useful.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.