<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/simmer-3-8-0/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://www.enchufa2.es/archives/simmer-3-8-0.html"> R – Enchufa2</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>The 3.8.0 release of <a rel="nofollow" href="http://r-simmer.org/" target="_blank">simmer</a>, the Discrete-Event Simulator for R, hit CRAN almost a week ago, and Windows binaries are already available. This version includes two highly requested new features that justify this second consecutive minor release.</p>
<div>
<h3>Attachment of precomputed data</h3>
<p>Until v3.7.0, the <em>generator</em> was the only means to attach data to trajectories, and it was primarily intended for dynamic generation of arrivals:</p>
<pre><code><span>library</span>(simmer)
set.seed(<span>42</span>)

hello_sayer &lt;- trajectory() %>%
  log_(<span>&quot;hello!&quot;</span>)

simmer() %>%
  add_generator(<span>&quot;dummy&quot;</span>, hello_sayer, <span>function</span>() rexp(<span>1</span>, <span>1</span>)) %>%
  run(until=<span>2</span>)</code></pre>
<pre><code>## 0.198337: dummy0: hello!
## 0.859232: dummy1: hello!
## 1.14272: dummy2: hello!
## 1.18091: dummy3: hello!
## 1.65409: dummy4: hello!</code></pre>
<pre><code>## simmer environment: anonymous | now: 2 | next: 3.11771876826972
## { Monitor: in memory }
## { Source: dummy | monitored: 1 | n_generated: 6 }</code></pre>
<p>Although it may be used to attach precomputed data too, especially using the <code>at()</code> adaptor:</p>
<pre><code>simmer() %>%
  add_generator(<span>&quot;dummy&quot;</span>, hello_sayer, at(seq(<span>0</span>, <span>10</span>, <span>0.5</span>))) %>%
  run(until=<span>2</span>)</code></pre>
<pre><code>## 0: dummy0: hello!
## 0.5: dummy1: hello!
## 1: dummy2: hello!
## 1.5: dummy3: hello!</code></pre>
<pre><code>## simmer environment: anonymous | now: 2 | next: 2
## { Monitor: in memory }
## { Source: dummy | monitored: 1 | n_generated: 21 }</code></pre>
<p>Now, let’s say that we want to attach some empirical data, and our observations not only include arrival times, but also priorities and some attributes (e.g., measured service times), as in <a rel="nofollow" href="https://stackoverflow.com/questions/44865924/using-simmer-to-build-a-specific-model" target="_blank">this question</a> on StackOverflow:</p>
<pre><code>myData &lt;- data.frame(
  time = c(<span>1</span>:<span>10</span>,<span>1</span>:<span>5</span>), 
  priority = <span>1</span>:<span>3</span>, 
  duration = rnorm(<span>15</span>, <span>50</span>, <span>5</span>)) %>%
  dplyr::arrange(time)</code></pre>
<p>This is indeed possible using generators, but it requires some trickery; more specifically, the clever usage of a <em>consumer</em> function as follows:</p>
<pre><code>consume &lt;- <span>function</span>(x, prio=<span>FALSE</span>) {
  i &lt;- <span>0</span>
  <span>function</span>() {
    i &lt;- i + <span>1</span>
    <span>if</span> (prio) c(x[[i]], x[[i]], <span>FALSE</span>)
    <span>else</span> x[[i]]
  }
}

activityTraj &lt;- trajectory() %>%
  seize(<span>&quot;worker&quot;</span>) %>%
  timeout_from_attribute(<span>&quot;duration&quot;</span>) %>%
  release(<span>&quot;worker&quot;</span>)

initialization &lt;- trajectory() %>%
  set_prioritization(consume(myData$priority, <span>TRUE</span>)) %>%
  set_attribute(<span>&quot;duration&quot;</span>, consume(myData$duration)) %>%
  join(activityTraj)

arrivals_gen &lt;- simmer() %>%
  add_resource(<span>&quot;worker&quot;</span>, <span>2</span>, preemptive=<span>TRUE</span>) %>%
  add_generator(<span>&quot;dummy_&quot;</span>, initialization, at(myData$time)) %>%
  run() %>%
  get_mon_arrivals()

<span># check the resulting duration times</span>
activity_time &lt;- arrivals_gen %>%
  tidyr::separate(name, c(<span>&quot;prefix&quot;</span>, <span>&quot;n&quot;</span>), convert=<span>TRUE</span>) %>%
  dplyr::arrange(n) %>%
  dplyr::pull(activity_time)

all(activity_time == myData$duration)</code></pre>
<pre><code>## [1] TRUE</code></pre>
<p>Since this v3.8.0, the new data source <code>add_dataframe</code> greatly simplifies this process:</p>
<pre><code>arrivals_df &lt;- simmer() %>%
  add_resource(<span>&quot;worker&quot;</span>, <span>2</span>, preemptive=<span>TRUE</span>) %>%
  add_dataframe(<span>&quot;dummy_&quot;</span>, activityTraj, myData, time=<span>&quot;absolute&quot;</span>) %>%
  run() %>%
  get_mon_arrivals()

identical(arrivals_gen, arrivals_df)</code></pre>
<pre><code>## [1] TRUE</code></pre>
</div>
<div>
<h3>On-disk monitoring</h3>
<p>As some users noted (see <a rel="nofollow" href="https://groups.google.com/d/msg/simmer-devel/A4M7uP0Lmgw/f_0wkctKBQAJ" target="_blank">1</a>, <a rel="nofollow" href="https://groups.google.com/d/msg/simmer-devel/sO1OlQTpoXw/VL4-_iTBAQAJ" target="_blank">2</a>), the default in-memory monitoring capabilities can turn problematic for very long simulations. To address this issue, the <code>simmer()</code> constructor gains a new argument, <code>mon</code>, to provide different types of monitors. Monitoring is still performed in-memory by default, but as of v3.8.0, it can be offloaded to disk through <code>monitor_delim()</code> and <code>monitor_csv()</code>, which produce flat delimited files.</p>
<pre><code>mon &lt;- monitor_csv()
mon</code></pre>
<pre><code>## simmer monitor: to disk (delimited files)
## { arrivals: /tmp/RtmpAlQH2g/file6933ce99281_arrivals.csv }
## { releases: /tmp/RtmpAlQH2g/file6933ce99281_releases.csv }
## { attributes: /tmp/RtmpAlQH2g/file6933ce99281_attributes.csv }
## { resources: /tmp/RtmpAlQH2g/file6933ce99281_resources.csv }</code></pre>
<pre><code>env &lt;- simmer(mon=mon) %>%
  add_generator(<span>&quot;dummy&quot;</span>, hello_sayer, <span>function</span>() rexp(<span>1</span>, <span>1</span>)) %>%
  run(until=<span>2</span>)</code></pre>
<pre><code>## 0.26309: dummy0: hello!
## 0.982183: dummy1: hello!</code></pre>
<pre><code>env</code></pre>
<pre><code>## simmer environment: anonymous | now: 2 | next: 2.29067480322535
## { Monitor: to disk (delimited files) }
##   { arrivals: /tmp/RtmpAlQH2g/file6933ce99281_arrivals.csv }
##   { releases: /tmp/RtmpAlQH2g/file6933ce99281_releases.csv }
##   { attributes: /tmp/RtmpAlQH2g/file6933ce99281_attributes.csv }
##   { resources: /tmp/RtmpAlQH2g/file6933ce99281_resources.csv }
## { Source: dummy | monitored: 1 | n_generated: 3 }</code></pre>
<pre><code>read.csv(mon$handlers[<span>&quot;arrivals&quot;</span>]) <span># direct access</span></code></pre>
<pre><code>##     name start_time  end_time activity_time finished
## 1 dummy0  0.2630904 0.2630904             0        1
## 2 dummy1  0.9821828 0.9821828             0        1</code></pre>
<pre><code>get_mon_arrivals(env)              <span># adds the &quot;replication&quot; column</span></code></pre>
<pre><code>##     name start_time  end_time activity_time finished replication
## 1 dummy0  0.2630904 0.2630904             0        1           1
## 2 dummy1  0.9821828 0.9821828             0        1           1</code></pre>
<p>See below for a comprehensive list of changes.</p>
</div>
<div>
<h3>New features:</h3>
<ul>
<li>New data source <code>add_dataframe</code> enables the attachment of precomputed data, in the form of a data frame, to a trajectory. It can be used instead of (or along with) <code>add_generator</code>. The most notable advantage over the latter is that <code>add_dataframe</code> is able to automatically set attributes and prioritisation values per arrival based on columns of the provided data frame (#140 closing #123).</li>
<li>New <code>set_source</code> activity deprecates <code>set_distribution()</code>. It works both for generators and data sources (275a09c, as part of #140).</li>
<li>New monitoring interface allows for disk offloading. The <code>simmer()</code> constructor gains a new argument <code>mon</code> to provide different types of monitors. By default, monitoring is performed in-memory, as usual. Additionally, monitoring can be offloaded to disk through <code>monitor_delim</code> and <code>monitor_csv</code>, which produce flat delimited files. But more importantly, the C++ interface has been refactorised to enable the development of new monitoring backends (#146 closing #119).</li>
</ul>
</div>
<div>
<h3>Minor changes and fixes:</h3>
<ul>
<li>Some documentation improvements (1e14ed7, 194ed05).</li>
<li>New default <code>until=Inf</code> for the <code>run</code> method (3e6aae9, as part of #140).</li>
<li><code>branch</code> and <code>clone</code> now accept lists of trajectories, in the same way as <code>join</code>, so that there is no need to use <code>do.call</code> (#142).</li>
<li>The argument <code>continue</code> (present in <code>seize</code> and <code>branch</code>) is recycled if only one value is provided but several sub-trajectories are defined (#143).</li>
<li>Fix process reset: sources are reset in strict order of creation (e7d909b).</li>
<li>Fix infinite timeouts (#144).</li>
</ul>
</div>
<p><em>Article originally published in Enchufa2.es: <a rel="nofollow" href="https://www.enchufa2.es/archives/simmer-3-8-0.html" target="_blank">simmer 3.8.0</a></em>.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.enchufa2.es/archives/simmer-3-8-0.html"> R – Enchufa2</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/NlQ-mLbPb_0" height="1"></a></div>