File: units.Rd

package info (click to toggle)
r-cran-units 0.8-1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,068 kB
  • sloc: xml: 2,437; cpp: 175; sh: 13; makefile: 2
file content (314 lines) | stat: -rw-r--r-- 11,653 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/conversion.R, R/make_units.R
\name{units}
\alias{units}
\alias{units<-.numeric}
\alias{units<-.units}
\alias{units<-.logical}
\alias{units.units}
\alias{units.symbolic_units}
\alias{set_units}
\alias{make_units}
\alias{as_units}
\alias{as_units.default}
\alias{as_units.units}
\alias{as_units.symbolic_units}
\alias{as_units.difftime}
\alias{as_units.character}
\alias{as_units.call}
\alias{as_units.expression}
\alias{as_units.name}
\alias{as_units.POSIXt}
\alias{as_units.Date}
\title{Handle measurement units}
\usage{
\method{units}{numeric}(x) <- value

\method{units}{units}(x) <- value

\method{units}{logical}(x) <- value

\method{units}{units}(x)

\method{units}{symbolic_units}(x)

set_units(x, value, ..., mode = units_options("set_units_mode"))

make_units(bare_expression, check_is_valid = TRUE)

as_units(x, ...)

\method{as_units}{default}(x, value = unitless, ...)

\method{as_units}{units}(x, value, ...)

\method{as_units}{symbolic_units}(x, value, ...)

\method{as_units}{difftime}(x, value, ...)

\method{as_units}{character}(x, check_is_valid = TRUE,
  implicit_exponents = NULL, force_single_symbol = FALSE, ...)

\method{as_units}{call}(x, check_is_valid = TRUE, ...)

\method{as_units}{expression}(x, check_is_valid = TRUE, ...)

\method{as_units}{name}(x, check_is_valid = TRUE, ...)

\method{as_units}{POSIXt}(x, value, ...)

\method{as_units}{Date}(x, value, ...)
}
\arguments{
\item{x}{numeric vector, or object of class \code{units}.}

\item{value}{object of class \code{units} or \code{symbolic_units}, or in the
case of \code{set_units} expression with symbols (see examples).}

\item{...}{passed on to other methods.}

\item{mode}{if \code{"symbols"} (the default), then unit is constructed from
the expression supplied. Otherwise, if\code{mode = "standard"},
standard evaluation is used for the supplied value This argument can be set
via a global option \code{units_options(set_units_mode = "standard")}}

\item{bare_expression}{a bare R expression describing units. Must be valid R
syntax (reserved R syntax words like \code{in} must be backticked)}

\item{check_is_valid}{throw an error if all the unit symbols are not either
recognized by udunits2 via \code{ud_is_parseable()}, or a custom
user defined via \code{install_unit()}. If \code{FALSE}, no check
for validity is performed.}

\item{implicit_exponents}{If the unit string is in product power form (e.g.
\code{"km m-2 s-1"}). Defaults to \code{NULL}, in which case a guess is made
based on the supplied string. Set to \code{TRUE} or \code{FALSE} if the guess is
incorrect.}

\item{force_single_symbol}{Whether to perform no string parsing and force
treatment of the string as a single symbol.}
}
\value{
An object of class \code{units}.

The \code{units} method retrieves the units attribute, which is of
class \code{symbolic_units}.
}
\description{
A number of functions are provided for handling unit objects.
\itemize{
    \item \code{`units<-`} and \code{units} are the basic functions to set
    and retrieve units.
    \item \code{as_units}, a generic with methods for a
    character string and for quoted language. Note, direct usage of this function
    by users is typically not necessary, as coercion via \code{as_units} is
    automatically done with \code{`units<-`} and \code{set_units}.
    \item \code{make_units}, constructs units from bare expressions.
    \code{make_units(m/s)} is equivalent to \code{as_units(quote(m/s))}.
    \item \code{set_units}, a pipe-friendly version of \code{`units<-`}. By
    default it operates with bare expressions, but this
    behavior can be disabled by a specifying \code{mode = "standard"} or setting
    \code{units_options(set_units_mode = "standard")}.
    If \code{value} is missing or set to \code{1}, the object becomes unitless.
}
}
\details{
If \code{value} is of class \code{units} and has a value unequal to 1, this
value is ignored unless \code{units_options("simplifiy")} is \code{TRUE}. If
\code{simplify} is \code{TRUE}, \code{x} is multiplied by this value.
}
\note{
By default, unit names are automatically substituted with unit names
  (e.g., kilogram --> kg). To turn off this behavior, set
  \code{units_options(auto_convert_names_to_symbols = FALSE)}
}
\section{Character strings}{


  Generally speaking, there are 3 types of unit strings are accepted in
  \code{as_units} (and by extension, \code{`units<-`}).

  The first, and likely most common, is a "standard" format unit
  specification where the relationship between unit symbols or names is
  specified explicitly with arithmetic symbols for division \code{/},
  multiplication \code{*} and power exponents \code{^}, or other mathematical
  functions like \code{log()}. In this case, the string is parsed as an R
  expression via \code{parse(text = )} after backticking all unit symbols and
  names, and then passed on to \code{as_units.call()}. A heuristic is used to
  perform backticking, such that any continuous set of characters
  uninterrupted by one of \code{()\\*^-} are backticked (unless the character
  sequence consists solely of numbers \code{0-9}), with some care to not
  double up on pre-existing backticks. This heuristic appears to be quite
  robust, and works for units would otherwise not be valid R syntax. For
  example, percent (\code{"\%"}), feet (\code{"'"}), inches (\code{"in"}),
  and Tesla (\code{"T"}) are all backticked and parsed correctly.

  Nevertheless, for certain complex unit expressions, this backticking heuristic
  may give incorrect results.  If the string supplied fails to parse as an R
  expression, then the string is treated as a single symbolic unit and
  \code{symbolic_unit(chr)} is used as a fallback with a warning. In that
  case, automatic unit simplification may not work properly when performing
  operations on unit objects, but unit conversion and other Math operations
  should still give correct results so long as the unit string supplied
  returns \code{TRUE} for \code{ud_is_parsable()}.

  The second type of unit string accepted is one with implicit exponents. In
  this format, \code{/}, \code{*}, and \code{^}, may not be present in the
  string, and unit symbol or names must be separated by a space. Each unit
  symbol may optionally be followed by a single number, specifying the power.
  For example \code{"m2 s-2"} is equivalent to \code{"(m^2)*(s^-2)"}.

  It must be noted that prepended numbers are supported too, but their
  interpretation slightly varies depending on whether they are separated from
  the unit string or not. E.g., \code{"1000 m"} is interpreted as magnitude
  and unit, but \code{"1000m"} is interpreted as a prefixed unit, and it is
  equivalent to \code{"km"} to all effects.

  The third type of unit string format accepted is the special case of
  udunits time duration with a reference origin, for example \code{"hours
  since 1970-01-01 00:00:00"}. Note, that the handling of time and calendar
  operations via the udunits library is subtly different from the way R
  handles date and time operations. This functionality is mostly exported for
  users that work with udunits time data, e.g., with NetCDF files. Users are
  otherwise encouraged to use \code{R}'s date and time functionality provided
  by \code{Date} and \code{POSIXt} classes.
}

\section{Expressions}{


  In \code{as_units()}, each of the symbols in the unit expression is treated
  individually, such that each symbol must be recognized by the udunits
  database (checked by \code{ud_is_parseable()}, \emph{or} be a custom,
  user-defined unit symbol that was defined by \code{install_unit()}. To
  see which symbols and names are currently recognized by the udunits
  database, see \code{valid_udunits()}.
}

\examples{
x = 1:3
class(x)
units(x) <- as_units("m/s")
class(x)
y = 2:5
a <- set_units(1:3, m/s)
units(a) <- make_units(km/h)
a
# convert to a mixed_units object:
units(a) = c("m/s", "km/h", "km/h")
a
# The easiest way to assign units to a numeric vector is like this:
x <- y <- 1:4
units(x) <- "m/s"  # meters / second

# Alternatively, the easiest pipe-friendly way to set units:
if(requireNamespace("magrittr", quietly = TRUE)) {
  library(magrittr)
  y \%>\% set_units(m/s)
}

# these are different ways of creating the same unit:
# meters per second squared, i.e, acceleration
x1 <- make_units(m/s^2)
x2 <- as_units(quote(m/s^2))
x2 <- as_units("m/s^2")
x3 <- as_units("m s-2") # in product power form, i.e., implicit exponents = T
x4 <- set_units(1,  m/s^2) # by default, mode = "symbols"
x5 <- set_units(1, "m/s^2",   mode = "standard")
x6 <- set_units(1, x1,        mode = "standard")
x7 <- set_units(1, units(x1), mode = "standard")
x8 <- as_units("m") / as_units("s")^2

all_identical <- function(...) {
  l <- list(...)
  for(i in seq_along(l)[-1])
    if(!identical(l[[1]], l[[i]]))
      return(FALSE)
  TRUE
}
all_identical(x1, x2, x3, x4, x5, x6, x7, x8)

# Note, direct usage of these unit creation functions is typically not
# necessary, since coercion is automatically done via as_units(). Again,
# these are all equivalent ways to generate the same result.

x1 <- x2 <- x3 <- x4 <- x5 <- x6 <- x7 <- x8 <- 1:4
units(x1) <- "m/s^2"
units(x2) <- "m s-2"
units(x3) <- quote(m/s^2)
units(x4) <- make_units(m/s^2)
units(x5) <- as_units(quote(m/s^2))
x6 <- set_units(x6, m/s^2)
x7 <- set_units(x7, "m/s^2", mode = "standard")
x8 <- set_units(x8, units(x1), mode = "standard")

all_identical(x1, x2, x3, x4, x5, x6, x7, x8)


# Both unit names or symbols can be used. By default, unit names are
# automatically converted to unit symbols.
make_units(degree_C)
make_units(kilogram)
make_units(ohm)

## Arithmetic operations and units
# conversion between unit objects that were defined as symbols and names will
# work correctly, although unit simplification in printing may not always occur.
x <- 500 * make_units(micrograms/liter)
y <- set_units(200, ug/l)
x + y
x * y # numeric result is correct, but units not simplified completely

# note, plural form of unit name accepted too ('liters' vs 'liter'), and
# denominator simplification can be performed correctly
x * set_units(5, liters)

# unit conversion works too
set_units(x, grams/gallon)

## Creating custom, user defined units
# For example, a microbiologist might work with counts of bacterial cells
# make_units(cells/ml) # by default, throws an ERROR
# First define the unit, then the newly defined unit is accepted.
install_unit("cells")
make_units(cells/ml)

# Note that install_unit() adds support for defining relationships between
# the newly created symbols or names and existing units.

## set_units()
# set_units is a pipe friendly version of `units<-`.
if(requireNamespace("magrittr", quietly = TRUE)) {
  library(magrittr)
  1:5 \%>\% set_units(N/m^2)
  # first sets to m, then converts to km
  1:5 \%>\% set_units(m) \%>\% set_units(km)
}

# set_units has two modes of operation. By default, it operates with
# bare symbols to define the units.
set_units(1:5, m/s)

# use `mode = "standard"` to use the value of supplied argument, rather than
# the bare symbols of the expression. In this mode, set_units() can be
# thought of as a simple alias for `units<-` that is pipe friendly.
set_units(1:5, "m/s", mode = "standard")
set_units(1:5, make_units(m/s), mode = "standard")

# the mode of set_units() can be controlled via a global option
# units_options(set_units_mode = "standard")

# To remove units use
units(x) <- NULL
# or
set_units(x, NULL)
# or
drop_units(y)
s = Sys.time()
d  = s - (s+1)
as_units(d)

}
\seealso{
\code{\link{install_unit}}, \code{\link{valid_udunits}}
}