Skip to content

Commit ff6b8ae

Browse files
committed
update rendered vignette
1 parent 0b166d9 commit ff6b8ae

File tree

1 file changed

+25
-59
lines changed

1 file changed

+25
-59
lines changed

vignettes/measurement_units_in_R.html

+25-59
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ <h4 class="author">Edzer Pebesma, Thomas Mailund, and James Hiebert</h4>
282282
</ul>
283283
<div id="abstract" class="section level2">
284284
<h2>Abstract</h2>
285-
<p>We briefly review SI units, and discuss R packages that deal with measurement units, their compatibility and conversion. Built upon <a href="https://cran.r-project.org/package=udunits2">udunits2</a> and the UNIDATA udunits library, we introduce the package <a href="https://cran.r-project.org/package=units">units</a> that provides a class for maintaining unit metadata. When used in expression, it automatically converts units, and simplifies units of results when possible; in case of incompatible units, errors are raised. The class flexibly allows expansion beyond predefined units. Using <a href="https://cran.r-project.org/package=units">units</a> may eliminate a whole class of potential scientific programming mistakes. We discuss the potential and limitations of computing with explicit units.</p>
285+
<p>We briefly review SI units, and discuss R packages that deal with measurement units, their compatibility and conversion. Built upon the UNIDATA udunits library, we introduce the package <a href="https://cran.r-project.org/package=units">units</a> that provides a class for maintaining unit metadata. When used in expression, it automatically converts units, and simplifies units of results when possible; in case of incompatible units, errors are raised. The class flexibly allows expansion beyond predefined units. Using <a href="https://cran.r-project.org/package=units">units</a> may eliminate a whole class of potential scientific programming mistakes. We discuss the potential and limitations of computing with explicit units.</p>
286286
</div>
287287
<div id="introduction" class="section level2">
288288
<h2>Introduction</h2>
@@ -426,44 +426,13 @@ <h2>Related work in R</h2>
426426
## [1] 0.00064516 0.00129032 0.00193548 0.00258064 0.00322580</code></pre>
427427
<p>Both <a href="https://cran.r-project.org/package=measurements">measurements</a> and <a href="https://cran.r-project.org/package=NISTunits">NISTunits</a> are written entirely in R.</p>
428428
</div>
429-
<div id="unidatas-udunits-library-and-the-udunits2-r-package" class="section level2">
430-
<h2>UNIDATA’s udunits library and the <code>udunits2</code> R package</h2>
429+
<div id="unidatas-udunits-library" class="section level2">
430+
<h2>UNIDATA’s udunits library</h2>
431431
<p>Udunits, developed by UCAR/UNIDATA, advertises itself on <a href="https://www.unidata.ucar.edu/software/udunits/">its web page</a> as: “<em>The udunits package supports units of physical quantities. Its C library provides for arithmetic manipulation of units and for conversion of numeric values between compatible units. The package contains an extensive unit database, which is in XML format and user-extendable.</em>”</p>
432-
<p>The R package <a href="https://cran.r-project.org/package=udunits2">udunits2</a> <span class="citation">(<a href="#ref-udunits2" role="doc-biblioref">Hiebert 2015</a>)</span> provides a low-level R interface to the most important functions in the udunits2 C library.</p>
433-
<p>The functions provided by <a href="https://cran.r-project.org/package=udunits2">udunits2</a> are</p>
434-
<pre class="r"><code>library(udunits2)
435-
## udunits system database read
436-
ls(2)
437-
## [1] &quot;ud.are.convertible&quot; &quot;ud.convert&quot; &quot;ud.get.name&quot; &quot;ud.get.symbol&quot;
438-
## [5] &quot;ud.have.unit.system&quot; &quot;ud.is.parseable&quot; &quot;ud.set.encoding&quot;</code></pre>
439-
<p>Dropping the <code>ud</code> prefix, <code>is.parseable</code> verifies whether a unit is parseable</p>
440-
<pre class="r"><code>ud.is.parseable(&quot;m/s&quot;)
441-
## [1] TRUE
442-
ud.is.parseable(&quot;q&quot;)
443-
## [1] FALSE</code></pre>
444-
<p><code>are.convertible</code> specifies whether two units are convertible</p>
445-
<pre class="r"><code>ud.are.convertible(&quot;m/s&quot;, &quot;km/h&quot;)
446-
## [1] TRUE
447-
ud.are.convertible(&quot;m/s&quot;, &quot;s&quot;)
448-
## [1] FALSE</code></pre>
449-
<p><code>convert</code> converts units that are convertible, and throws an error otherwise</p>
450-
<pre class="r"><code>ud.convert(1:3, &quot;m/s&quot;, &quot;km/h&quot;)
451-
## [1] 3.6 7.2 10.8</code></pre>
452-
<p>and <code>get.name</code>, <code>get.symbol</code> and <code>set.encoding</code> get name, get symbol or modify encoding of the character unit arguments.</p>
453-
<pre class="r"><code>ud.get.name(&quot;kg&quot;)
454-
## [1] &quot;kilogram&quot;
455-
ud.get.symbol(&quot;kilogram&quot;)
456-
## [1] &quot;kg&quot;
457-
ud.set.encoding(&quot;utf8&quot;)
458-
## NULL</code></pre>
459-
<p>Unlike the <a href="https://cran.r-project.org/package=measurements">measurements</a> and <a href="https://cran.r-project.org/package=NISTunits">NISTunits</a>, <a href="https://cran.r-project.org/package=udunits2">udunits2</a> parses units as expressions, and bases its logic upon the convertibility of expressions, rather than the comparison of fixed strings:</p>
432+
<p>Unlike the <a href="https://cran.r-project.org/package=measurements">measurements</a> and <a href="https://cran.r-project.org/package=NISTunits">NISTunits</a>, the underlying udunits2 C library parses units as expressions, and bases its logic upon the convertibility of expressions, rather than the comparison of fixed strings:</p>
460433
<pre class="r"><code>m100_a = paste(rep(&quot;m&quot;, 100), collapse = &quot;*&quot;)
461434
dm100_b = &quot;dm^100&quot;
462-
ud.is.parseable(m100_a)
463-
## [1] TRUE
464-
ud.is.parseable(dm100_b)
465-
## [1] TRUE
466-
ud.are.convertible(m100_a, dm100_b)
435+
units::ud_are_convertible(m100_a, dm100_b)
467436
## [1] TRUE</code></pre>
468437
<p>This has the advantage that through complex computations, intermediate objects can have units that are arbitrarily complex, and that can potentially be simplified later on. It also means that the package practically supports an unlimited amount of derived units.</p>
469438
</div>
@@ -479,57 +448,57 @@ <h2>Handling data with units in R: the units package</h2>
479448
<pre class="r"><code>library(units)
480449
x = set_units(1:5, m/s)
481450
str(x)
482-
## Units: [m*s^-1] int [1:5] 1 2 3 4 5</code></pre>
451+
## Units: [m/s] int [1:5] 1 2 3 4 5</code></pre>
483452
<p>represents speed values in <code>m/s</code>. The units <code>m</code> and <code>s</code> are resolved from the udunits2 C library (but could be user-defined units).</p>
484453
<p>Units can be used in arbitrary R expressions like</p>
485454
<pre class="r"><code>set_units(1:3, m/s^2)
486-
## Units: [m*s^-2]
455+
## Units: [m/s^2]
487456
## [1] 1 2 3</code></pre>
488457
<p>Several manipulations with <code>units</code> objects will now be illustrated. Manipulations that do not involve unit conversion are for instance addition:</p>
489458
<pre class="r"><code>x = set_units(1:3, m/s)
490459
x + 2 * x
491-
## Units: [m*s^-1]
460+
## Units: [m/s]
492461
## [1] 3 6 9</code></pre>
493462
<p>Explicit unit conversion is done by assigning new units:</p>
494463
<pre class="r"><code>(x = set_units(x, cm/s))
495-
## Units: [cm*s^-1]
464+
## Units: [cm/s]
496465
## [1] 100 200 300
497466
as.numeric(x)
498467
## [1] 100 200 300</code></pre>
499468
<p>similar to the behaviour of <code>difftime</code> objects, this modifies the numeric values without modifying their meaning (what the numbers refer to).</p>
500469
<p>When mixing units in sums, comparisons or concatenation, units are automatically converted to those of the first argument:</p>
501470
<pre class="r"><code>y = set_units(1:3, km/h)
502471
x + y
503-
## Units: [cm*s^-1]
472+
## Units: [cm/s]
504473
## [1] 127.7778 255.5556 383.3333
505474
y + x
506-
## Units: [km*h^-1]
475+
## Units: [km/h]
507476
## [1] 4.6 9.2 13.8
508477
x == y
509478
## [1] FALSE FALSE FALSE
510479
c(y, x)
511-
## Units: [km*h^-1]
480+
## Units: [km/h]
512481
## [1] 1.0 2.0 3.0 3.6 7.2 10.8</code></pre>
513482
<p>where <code>c(y, x)</code> concatenates <code>y</code> and <code>x</code> after converting <code>x</code> to the units of <code>y</code>. Derived units are created where appropriate:</p>
514483
<pre class="r"><code>x * y
515-
## Units: [cm*km*h^-1*s^-1]
484+
## Units: [cm*km/h/s]
516485
## [1] 100 400 900
517486
x^3
518-
## Units: [cm^3*s^-3]
487+
## Units: [cm^3/s^3]
519488
## [1] 1.0e+06 8.0e+06 2.7e+07</code></pre>
520489
<p>and meaningful error messages appear when units are not compatible:</p>
521490
<pre class="r"><code>e = try(z &lt;- x + x * y)
522-
## Error : cannot convert cm*km*h^-1*s^-1 into cm*s^-1
491+
## Error : cannot convert cm*km/h/s into cm/s
523492
attr(e, &quot;condition&quot;)[[1]]
524-
## [1] &quot;cannot convert cm*km*h^-1*s^-1 into cm*s^-1&quot;</code></pre>
493+
## [1] &quot;cannot convert cm*km/h/s into cm/s&quot;</code></pre>
525494
<p>The full set of methods and method groups for <code>units</code> objects is shown by</p>
526495
<pre class="r"><code>methods(class = &quot;units&quot;)
527-
## [1] [ [[ [[&lt;- [&lt;- all.equal as_units as.data.frame
528-
## [8] as.Date as.list as.POSIXct boxplot c diff drop_units
529-
## [15] format hist log10 log2 Math mean median
530-
## [22] mixed_units Ops plot print quantile rep scale_type
531-
## [29] seq set_units str summary Summary unique units
532-
## [36] units&lt;- weighted.mean
496+
## [1] [ [[ [[&lt;- [&lt;- all.equal anyDuplicated as_units
497+
## [8] as.data.frame as.Date as.list as.POSIXct boxplot c diff
498+
## [15] drop_units duplicated format hist log10 log2 Math
499+
## [22] mean median mixed_units Ops plot print quantile
500+
## [29] rep seq set_units str summary Summary unique
501+
## [36] units units&lt;- weighted.mean
533502
## see &#39;?methods&#39; for accessing help and source code</code></pre>
534503
<p>where the method groups</p>
535504
<ul>
@@ -549,10 +518,10 @@ <h2>Handling data with units in R: the units package</h2>
549518
## 1e+100 [m]</code></pre>
550519
<p>Units are printed as simple R expressions, e.g.</p>
551520
<pre class="r"><code>set_units(1, m^5/s^4)
552-
## 1 [m^5*s^-4]</code></pre>
521+
## 1 [m^5/s^4]</code></pre>
553522
<p>Another way to print units commonly seen in Climate and Forecast Conventions is <code>m2 s-1</code> for m<span class="math inline">\(^2\)</span>/s. These are not R expressions, but they can be parsed by <code>as_units</code>, and created by <code>deparse_unit</code>:</p>
554523
<pre class="r"><code>as_units(&quot;m2 s-1&quot;)
555-
## 1 [m^2*s^-1]
524+
## 1 [m^2/s]
556525
deparse_unit(set_units(1, m^2*s^-1))
557526
## [1] &quot;m2 s-1&quot;</code></pre>
558527
<p>The <code>plot</code> and <code>hist</code> methods add units to default axis labels, an example is shown in the following figures. For <a href="https://cran.r-project.org/package=ggplot2">ggplot2</a> plots <span class="citation">(<a href="#ref-ggplot2" role="doc-biblioref">Wickham 2009</a>)</span>, automatic unit placement in default axis label is also provided; <code>demo(ggplot2)</code> gives an example.</p>
@@ -598,7 +567,7 @@ <h2>Discussion and conclusions</h2>
598567
<p>The <a href="https://cran.r-project.org/package=units">units</a> R package provides a new class, <code>units</code>, for numeric data with associated measurement units. Operations on objects of this class retain the unit metadata and provide automated dimensional analysis: dimensions are taken into consideration in computations and comparisons. Combining different units that are compatible triggers automatic unit conversion, derived units are automatically generated and simplified where possible, and meaningful error messages are given when a user tries to add objects with incompatible units. This verifies that computations are not only syntactically and numerically allowed, but also semantically, and in the case of physical units, physically allowed, which may support code verification and provenance tracking. Using this package may eliminate a whole class of potential scientific programming mistakes.</p>
599568
<p>Where the R packages <a href="https://cran.r-project.org/package=measurements">measurements</a> and <a href="https://cran.r-project.org/package=NISTunits">NISTunits</a> provide conversion between a fixed number of units, with the help of the udunits2 C library and unit database, R package <a href="https://cran.r-project.org/package=units">units</a> handles arbitrarily complex derived units. By treating units as expressions it can derive, convert and simplify units. In addition, beyond the SI units packaged, <a href="https://cran.r-project.org/package=units">units</a> handles user-defined units.</p>
600569
<p>Data in <code>units</code> vectors can be stored as columns in <code>data.frame</code> or <code>tbl_df</code> objects, and can be converted to and from <code>difftime</code>. When <code>units</code> objects have associated time and location information, they could be stored in spatial or spatio-temporal objects provided by <a href="https://cran.r-project.org/package=sp">sp</a> or <a href="https://cran.r-project.org/package=spacetime">spacetime</a> <span class="citation">(<a href="#ref-spacetime" role="doc-biblioref">Pebesma 2012</a>)</span> as these store attribute data in <code>data.frame</code> slots, but for instance not in <code>zoo</code> <span class="citation">(<a href="#ref-zoo" role="doc-biblioref">Zeileis and Grothendieck 2005</a>)</span> or <code>xts</code> <span class="citation">(<a href="#ref-xts" role="doc-biblioref">Ryan and Ulrich 2014</a>)</span> objects, as these latter two set the class attribute of a vector or matrix.</p>
601-
<p>Despite all standardization efforts, units may still be ambiguous, or subject to interpretation. For instance for the duration of one year <a href="https://cran.r-project.org/package=NISTunits">NISTunits</a> or <a href="https://cran.r-project.org/package=udunits2">udunits2</a> give us an answer that depends on whether we want a common, leap, Gregorian, Julian, tropical or siderial year (<span class="citation"><a href="#ref-lang" role="doc-biblioref">Lang</a> (<a href="#ref-lang" role="doc-biblioref">2006</a>)</span>, see also <code>demo(year)</code>). This illustrates that those who apply unit conversion should be aware of possible pitfalls. Support for calendars in udunits seems not as well developed as in R.</p>
570+
<p>Despite all standardization efforts, units may still be ambiguous, or subject to interpretation. For instance for the duration of one year <a href="https://cran.r-project.org/package=NISTunits">NISTunits</a> gives us an answer that depends on whether we want a common, leap, Gregorian, Julian, tropical or siderial year (<span class="citation"><a href="#ref-lang" role="doc-biblioref">Lang</a> (<a href="#ref-lang" role="doc-biblioref">2006</a>)</span>, see also <code>demo(year)</code>). This illustrates that those who apply unit conversion should be aware of possible pitfalls. Support for calendars in udunits seems not as well developed as in R.</p>
602571
<p>Future work includes extending packages that read external data from formats, databases or interfaces with support for measurement unit information into R, preserving the measurement unit information. Examples would be interfaces to HDF5 (e.g., <a href="https://cran.r-project.org/package=h5">h5</a>, <span class="citation"><a href="#ref-h5" role="doc-biblioref">Annau</a> (<a href="#ref-h5" role="doc-biblioref">2016</a>)</span>), <a href="https://cran.r-project.org/package=RNetCDF">RNetCDF</a> <span class="citation">(<a href="#ref-RNetCDF" role="doc-biblioref">Michna and Woods 2016</a>)</span> or <a href="https://cran.r-project.org/package=sos4R">sos4R</a> <span class="citation">(<a href="#ref-sos4R" role="doc-biblioref">Nüst, Stasch, and Pebesma 2011</a>)</span>. It would be nice to see units of measurements propagate into units of regression coefficient estimates.</p>
603572
</div>
604573
<div id="acknowledgements" class="section level1">
@@ -623,9 +592,6 @@ <h1 class="unnumbered">References</h1>
623592
<div id="ref-lubridate" class="csl-entry">
624593
Grolemund, Garrett, and Hadley Wickham. 2011. <span>“Dates and Times Made Easy with Lubridate.”</span> <em>Journal of Statistical Software</em> 40 (1): 1–25. <a href="https://doi.org/10.18637/jss.v040.i03">https://doi.org/10.18637/jss.v040.i03</a>.
625594
</div>
626-
<div id="ref-udunits2" class="csl-entry">
627-
Hiebert, James. 2015. <em>Udunits2: Udunits-2 Bindings for r</em>.
628-
</div>
629595
<div id="ref-iliffe" class="csl-entry">
630596
Iliffe, Jonathan, and Roger Lott. 2008. <em>Datums and Map Projections: For Remote Sensing, GIS and Surveying</em>. CRC Inc.
631597
</div>

0 commit comments

Comments
 (0)