Changelog
Source:NEWS.md
sdbuildR 2.2.0
Renamed several
plot.stockflow()arguments for clarity:minlenis nowflow_length,nodesepis nowspacing,padis nowmargin,dependency_colis nowcolor_dependency, andlabel_colis nowfont_color. The old names are no longer recognised.Fixed time animations for variables that start with non-finite values, such as
NaNfrom a0/0ratio at initialization. These plots now build without plotly trace-length warnings.Time animations can now be tuned with
control_optionsinplot.simulate_stockflow(),plot.ensemble_stockflow(), andplot.verify_stockflow(). Useduration,frame_ms,transition_ms, ormax_framesto control speed and smoothness.plot.stockflow(show_eqn = TRUE)now labels equations by variable type:Initial value =for stocks,Rate =for flows,Value =for constants, andEquation =for auxiliaries. Hover tooltips use the same wording.install_julia_env()now reinstalls the Julia environment from a clean sdbuildR user data directory.Informational messages are now controlled consistently with
quietinensemble(),simulate(),use_julia(), andinstall_julia_env().ensemble(verbose = )is deprecated.Breaking:
plot.stockflow()now usescolorsinstead ofstock_colandflow_col.colorsaccepts a single colour, a list keyed by variable type, or a named vector keyed by variable name. Constants and auxiliaries can now be coloured as well.Dependency arrows in
plot.stockflow()now default to open arrow heads. Use the newarrowhead_dependencyargument to choose a different shape.Plots and diagrams can now use Fontsource webfonts by passing a Fontsource id such as
"eb-garamond"or"source-serif-4"tofont_family. System fonts, such as"Times New Roman", still work as before. Breaking: the default plot font changed from"Times New Roman"to"stix-two-text"; setoptions(sdbuildR.font_family = "Times New Roman")to restore the old default.Breaking:
sim_settings()now usessave_by,save_times, andsave_lengthfor output times. These replace the removedsave_atandsave_narguments.
sdbuildR 2.1.0
The plotting
line_widthandalphaarguments now accept a richer grammar. Inplot.ensemble_stockflow()they style three layers independently: the central-tendency line (central), the uncertainty band (spread), and the individual trajectories (sims). Pass a single value (applied everywhere), a named per-variable vector (names are variable labels, likecolors), or a list keyed by layer (e.g.line_width = list(central = 3, spread = 0, sims = 1)), optionally with per-variable vectors inside each layer.colorslikewise accepts a partial named vector now: name only the variables you want to recolour and the palette fills the rest. Breaking: thecentral_line_widthargument is removed; useline_width = list(central = ...)instead. The ensemble defaults changed toline_width = list(central = 3, spread = 0, sims = 1)andalpha = list(central = 1, spread = 0.3, sims = 0.3)(the trajectory width is thinner and the band is drawn without a border by default).Improved the placement of condition sliders/dropdowns (
condition_display = "slider"/"dropdown") inplot.ensemble_stockflow()andplot.verify_stockflow(). Plots with condition controls now have a fixed height, sized to the number of stacked controls. The gap between stacked controls can be tuned viacontrol_options = list(spacing = ...)(now in pixels;NULLkeeps the automatic default).Fixed
condition_display = "dropdown": selecting a condition from the dropdown(s) did not update the plot when several condition parameters were varied, because the handler waited for a relayout event that plotly.js never emits for dropdown buttons. The handler now reacts to the button-click event.ensemble()chooses which summary statistics to compute viacentralandspread, mirroring the vocabulary ofplot.ensemble_stockflow().centralis one or more of"mean","median", or"none";spreadis one or more of"quantile"(quantile columns at the probabilities given byquantiles),"sd","range"(returned asmin/maxcolumns), or"none". Unlike inplot(), here they are the set of statistics to compute (each becomes a column), not a preference order. Amissing_countcolumn is now always returned.central,spread, andquantilescan also be set on the model viasim_settings(); passing them toensemble()overrides the model’s settings for that call. Breaking: this replaces the short-livedsummary_statsargument; quantile columns are namedquant1,quant2, … (in the order ofquantiles; the probabilities are stored in the object’squantilesfield). Both accept lenient spellings (e.g."Medians","SDs","min-max").plot.ensemble_stockflow()gainscentralandspreadarguments, each a preference vector.central("mean","median","none") picks the central line andspread("quantile","sd","range","none") picks the uncertainty band; the first option whose statistics are present in the summary is used.centralreplaces the previouscentral_tendencyargument. Both accept lenient spellings (e.g."Medians","SDs").Fixed a bug where
simulate()withlanguage = "julia"ignored theseedset viasim_settings(), so models with random elements were not reproducible. Seeded Julia simulations are now reproducible, matching the R backend and the existing behaviour ofensemble().The
plot()methods forsimulate_stockflow,ensemble_stockflow, andverify_stockflowresults gain aline_widthargument controlling the width of the plotted trajectories. It accepts either a single value applied to all variables, or a vector with one value per variable (mirroringcolors). Defaults to2.In
plot.ensemble_stockflow(), thecentral_tendency_widthargument has been renamed tocentral_line_widthand now also accepts a vector with one value per variable (likeline_width), in addition to a single value.The
as.data.frame()methods forsimulate_stockflow,ensemble_stockflow, andverify_stockflowresults can now subset their output by variable withvarsand by variable type withtype, matchingas.data.frame.stockflow()andplot(). For consistency, the selection argument is now calledvarseverywhere (in bothas.data.frame()andplot());nameremains reserved for the model-editing functions (update(),stock(),flow(), …). Thenameargument ofas.data.frame.stockflow()has been renamed tovars.plot.stockflow()gains three layout-control arguments.directionsets the overall flow direction ("LR","TB","RL", or"BT"; default"LR").alignlines variables up across the flow direction (one or more groups, placed on the same Graphviz rank).ordersequences variables along the flow direction as a soft hint via invisible edges, so it nudges the layout without overriding the real flows. All three accept any variable (not only stocks).The sdbuildR Julia environment is now stored in a persistent user directory (via
tools::R_user_dir()) instead of inside the installed package. It now survives reinstalling or updating sdbuildR, so you no longer have to rebuild it after every package update, and installation works on read-only or system-wide library locations. You are prompted to rebuild it withinstall_julia_env()only when its dependencies actually change.use_julia()andsimulate()now detect when the sdbuildR Julia environment was built with a different version of Julia than the one currently running (for example after reinstalling or updating Julia) and prompt you to rebuild it withinstall_julia_env(), instead of failing.install_julia_env()now reports clearly when setup is interrupted (for example by cancelling the 10-25 minute install), prompting you to run it again.plot.stockflow()now uses defaultminlen = 1instead ofminlen = 2to create shorter flow edges.plot.stockflow()gains ashow_eqnargument (defaultTRUE). Each variable’s equation is shown on a new line beneath its label, in a smaller font and the same colour as the label, wrapped towrap_width. Setshow_eqn = FALSEto hide the equations.plot.stockflow()gains ashow_tooltipargument (defaultTRUE) to control whether equations are shown as tooltips on hover.plot.stockflow()gains alabel_colargument to set the colour of variable labels (and of the equation text whenshow_eqn = TRUE).plot()for simulation, ensemble, and verify results gains ananimationargument. Useanimation = "time"to cumulatively reveal trajectories over time with a play button and time slider. For ensemble and verify plots, time animation is supported for a single condition (one panel).-
plot.ensemble_stockflow()andplot.verify_stockflow()gain acondition_displayargument. In addition to the default"subplots", use"slider"or"dropdown"to show one condition/test at a time and select it interactively. These controls now (a) draw only one condition’s traces and swap the data client-side, so they stay fast even for ensembles with many conditions; (b) label each condition with its parameter values; and- for a crossed ensemble (
cross = TRUE) with two or more parameters, show one control per parameter instead of a single condition selector. The interactive controls are self-contained and require no running R session, so they work in static HTML (e.g. pkgdown articles and Quarto slides).
- for a crossed ensemble (
sdbuildR 2.0.0
CRAN release: 2026-06-16
Breaking changes
stockflow()is now the constructor for stock-and-flow models. Code that usedxmile()or the development-onlysdbuildR()constructor should callstockflow()instead.update()now replaces the oldbuild()workflow for general model edits. For clearer model-building code, usestock(),flow(),constant(),aux()/auxiliary(),lookup(), andcustom_func().stockflowis now the primary model class. Code that checked forsdbuildR_xmileorsdbuildRshould check forstockflowinstead.simulate()now returnssimulate_stockflowobjects,ensemble()returnsensemble_stockflowobjects,verify()returnsverify_stockflowobjects,summary()returnssummary_stockflowobjects, andcompare_models()returnscompare_stockflowobjects.sim_settings()now replacessim_specs(), andmeta()now replacesheader().summary()now runs model diagnostics. Code that useddebugger()should callsummary()instead.dependencies()now replacesfind_dependencies().export_model(format = "sdbuildR")now replacesget_build_code().sim_methods()now replacessolvers().custom_func()now replacesmacro()for user-defined model functions.import_insightmaker()now replacesinsightmaker_to_sfm(), andurl_to_insightmaker()now replacesurl_to_IM().ensemble()now usesconditionsinstead ofrange. To retain individual simulations, usesave_sims = TRUEinstead ofreturn_sims = TRUE.plot()methods now useshow_constantsinstead ofadd_constants. For ensemble plots, usewhich,sim,condition, andlabel_subplotsinstead oftype,i,j, andj_labels.use_julia(nthreads = )now controls Julia threading. Code that useduse_threads()should set the thread count withuse_julia()instead.Units are no longer supported. This means that unit-specific helpers from 1.x, including
u(),convert_u(),drop_u(),model_units(),unit_prefixes(),get_units(),get_regex_units(), andget_regex_time_units(), are no longer available.
New features
stockflow()creates an empty model or loads a built-in template using a case-insensitivetemplatename.stock(),flow(),constant(),aux()/auxiliary(),lookup(), andcustom_func()provide typed model-building helpers aroundupdate().update()now supports bare variable names and R expressions inname,type,eqn,to,from, andsource. Strings and programmatic injection with!!remain supported.change_name(),change_type(), anddiscard()provide focused helpers for renaming, changing, and removing model variables.sim_settings()gains flexible output controls withsave_at,save_n,vars, andsave_sims.simulate()accepts temporary simulation-setting overrides through..., using the same arguments assim_settings().ensemble()can run ensembles in R and Julia, vary stocks and constants withconditions, and retain individual simulations withsave_sims = TRUE.unit_test(),unit_tests(), andverify()add model-level unit tests for expected simulation behavior, including tests under alternativeconditions.compare_models()compares model structure, equations, and simulation settings across twostockflowmodels.import_desolve()converts deSolve-style ODE models intostockflowmodels.import_insightmaker()imports Insight Maker models from public URLs,.InsightMakerfiles, and ModelJSON.jsonfiles.export_model()exports models as sdbuildR reconstruction code, standalone deSolve scripts, or Psychomodels JSON records.
Improvements and fixes
as.data.frame()methods now support thestockflow,simulate_stockflow,ensemble_stockflow, andverify_stockflowclasses.dependencies()can now filter dependencies by variable name and type.export_plot()now supports the current plot classes and additional graph export options.simulate()and Julia code generation now use a faster AST-based R-to-Julia equation translator. Namespaced calls such asbase::sum()translate correctly, and unsupported constructs fall back to the previous translator.simulate(), compilation, andsummary()now use a content-hashed assembly cache. Repeated calls on unchanged models can skip reassembly, and editing one equation only retranslates that equation.simulate()now keeps Julia stock derivative positions aligned with the state vector when stocks are added, removed, renamed, or created by changing a variable’s type.summary()and code generation now use an internal structural validator to catch inconsistent model layouts before simulation.simulate()now removes temporary CSV files created by single Julia simulations.textutilsis now a required dependency.
sdbuildR 1.0.6
Fixed error in finding Julia installation
Simulations in Julia are now ensured to stop at exact simulation times, which removes unexpected results created by numerical errors in the solver (using tstops argument in solve())
sdbuildR 1.0.3
Removed automatic installation of Julia packages and instead wrote a separate function for this: install_julia_env(). install_julia_env() is called in .onLoad() ONLY if the custom environmental variable AUTO_INSTALL_JULIA_ENV is “true” and NOT_CRAN is “true”. This is to ensure GitHub workflows have the Julia environment instantiated, but this will not affect users, as they do not have AUTO_INSTALL_JULIA_ENV.
Added vignette for formalizing Job Demands-Resources (JDR) Theory
Improved documentation