| Title: | Fast Continuous Wavelet Transform |
|---|---|
| Description: | Enables the usage of the fast continuous wavelet transform, originally implemented in the 'C++' library 'fCWT' by Lukas Arts. See Arts, P.A. and Van den Broek, E.L. (2022) <doi:10.1038/s43588-021-00183-z> for details. |
| Authors: | Lukas Schneiderbauer [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-0975-6803>), Lukas P. A. Arts [cph] (Author of the majority of the C++ code, indicated in the respective header files.), Egon L. van den Broek [cph] (Author of the majority of the C++ code, indicated in the respective header files.) |
| Maintainer: | Lukas Schneiderbauer <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.4.1.9000 |
| Built: | 2026-11-13 15:08:55 UTC |
| Source: | https://github.com/lschneiderbauer/fcwtr |
Selects a time range and/or a frequency range of a scalogram. The time offset and the frequency range of the result are adjusted accordingly.
## S3 method for class 'fcwtr_scalogram' x[i, j]## S3 method for class 'fcwtr_scalogram' x[i, j]
x |
An "fcwtr_scalogram" object resulting from |
i, j
|
Indices selecting time slices (rows, |
Another "fcwtr_scalogram" object that contains only part of the data.
fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), y_sample_freq = u(44100, "Hz"), n_freqs = 10 )[1:1000, 2:7]fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), y_sample_freq = u(44100, "Hz"), n_freqs = 10 )[1:1000, 2:7]
Internally, the scalogram resulting from fcwt() is represented by
a numeric matrix(). This method converts this matrix into a
tibble::tibble() in long format, with one row per matrix entry.
Note that this conversion has a significant run time cost.
## S3 method for class 'fcwtr_scalogram' as_tibble(x, ...)## S3 method for class 'fcwtr_scalogram' as_tibble(x, ...)
x |
An "fcwtr_scalogram" object resulting from |
... |
Additional arguments are ignored. |
This method is conceptually identical to as.data.frame(),
it simply returns a tibble::tibble() instead of a data.frame().
A tibble::tibble() object representing the scalogram data with four columns:
An integer index uniquely identifying time slices, starting at 0.
The time of the time slice in physical units, relative to the
beginning of the input signal (time slices that were cut off,
e.g. by subsetting, are taken into account).
The time unit (s, ms, us, or ns) is chosen depending on the
magnitude of the values, and can be converted with
units::set_units().
The frequency, in the units chosen by the user for the
freq_begin and freq_end arguments of fcwt().
The fCWT result for the particular time-frequency combination.
library(tibble) fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), n_freqs = 10 ) |> as_tibble()library(tibble) fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), n_freqs = 10 ) |> as_tibble()
Internally, the scalogram resulting from fcwt() is represented by
a numeric matrix(). This method converts this matrix into a
data.frame() in long format, with one row per matrix entry.
Note that this conversion has a significant run time cost.
## S3 method for class 'fcwtr_scalogram' as.data.frame(x, ...)## S3 method for class 'fcwtr_scalogram' as.data.frame(x, ...)
x |
An "fcwtr_scalogram" object resulting from |
... |
Additional arguments are ignored. |
A data.frame() object representing the scalogram data with four columns:
An integer index uniquely identifying time slices, starting at 0.
The time of the time slice in physical units, relative to the
beginning of the input signal (time slices that were cut off,
e.g. by subsetting, are taken into account).
The time unit (s, ms, us, or ns) is chosen depending on the
magnitude of the values, and can be converted with
units::set_units().
The frequency, in the units chosen by the user for the
freq_begin and freq_end arguments of fcwt().
The fCWT result for the particular time-frequency combination.
fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), n_freqs = 10 ) |> as.data.frame() |> head()fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), n_freqs = 10 ) |> as.data.frame() |> head()
Strips attributes and class from a scalogram object to retrieve a pure matrix.
## S3 method for class 'fcwtr_scalogram' as.matrix(x, ...)## S3 method for class 'fcwtr_scalogram' as.matrix(x, ...)
x |
An "fcwtr_scalogram" object resulting from |
... |
additional arguments to be passed to or from methods. |
A two dimensional numeric vector, inheriting the class "matrix".
options(max.print = 10) fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), n_freqs = 10 ) |> as.matrix()options(max.print = 10) fcwt( sin((1:5000) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), n_freqs = 10 ) |> as.matrix()
Create a ggplot object resembling a scalogram
## S3 method for class 'fcwtr_scalogram' autoplot( object, n = 1000, time_unit = NULL, freq_unit = "Hz", transf = identity, ... )## S3 method for class 'fcwtr_scalogram' autoplot( object, n = 1000, time_unit = NULL, freq_unit = "Hz", transf = identity, ... )
object |
A "fcwtr_scalogram" object resulting from |
n |
The plotting function reduces the time resolution by averaging
to generate a reasonable graphics format. |
time_unit |
A time unit that is used for the x-axis scale, e.g. |
freq_unit |
A frequency unit that is used for the y-axis scale.
Defaults to "Hz" - "Hertz".
See |
transf |
A function, taking a vector and returning a vector, that is used to transform the scalogram values before plotting. |
... |
Additional arguments are ignored. |
A ggplot object.
library(ggplot2) res <- fcwt( sin((1:4410) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10, sigma = 5 ) autoplot(res, time_unit = "ms")library(ggplot2) res <- fcwt( sin((1:4410) * 2 * pi * 440 / 44100), x_sample_freq = u(44100, "Hz"), freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10, sigma = 5 ) autoplot(res, time_unit = "ms")
This function checks if fCWTr was compiled with AVX instruction set support. AVX instructions need to be supported by the users' CPU in order for this to work.
avx_enabled()avx_enabled()
By default, most compiler setups do not make use of AVX to increase portability of the binary. If you are an R user that has a CPU supporting AVX and want to make use of it, you might need to manually enable compiler flags to let R know about it, and install the package from source (so that it gets compiled on your machine).
( TRUE | FALSE )
Returns TRUE if AVX support is enabled, FALSE otherwise.
avx_enabled()avx_enabled()
Drop units from a dimensionful quantity and retrieve a dimensionless number.
The dimensionless number is defined by the ratio of x and one unit u(1, unit).
du(x, unit = "1")du(x, unit = "1")
x |
A dimensionful numeric vector (S3 class "units"), e.g. generated with |
unit |
A character indicating the unit. See |
A dimensionless number defined by the ratio of x and one unit u(1, unit).
x <- u(1, "km") # retrieve a dimensionless number # from x in units of "meter" du(x, "m") # drop the unit of a dimensionless "unit" quantity du(x / x)x <- u(1, "km") # retrieve a dimensionless number # from x in units of "meter" du(x, "m") # drop the unit of a dimensionless "unit" quantity du(x / x)
The core function of this package making use of the fCWT library. It processes an input signal in form of a real valued numeric vector interpreted as an evenly spaced time series and returns the absolute values of the continuous wavelet transform, i.e. a real valued positive matrix with a time and a frequency dimension.
fcwt( x, x_sample_freq, sigma = 2 * pi, y_sample_freq = 3/sigma_res(sigma, freq_end)$time, freq_begin = 2 * x_sample_freq/length(x), freq_end = x_sample_freq/2, n_freqs = 3 * ceiling(log(du(freq_end/freq_begin), base = 1 + sigma_freq_res_rel(sigma))), freq_scale = c("log", "linear"), rm_coi = TRUE, n_threads = 2L )fcwt( x, x_sample_freq, sigma = 2 * pi, y_sample_freq = 3/sigma_res(sigma, freq_end)$time, freq_begin = 2 * x_sample_freq/length(x), freq_end = x_sample_freq/2, n_freqs = 3 * ceiling(log(du(freq_end/freq_begin), base = 1 + sigma_freq_res_rel(sigma))), freq_scale = c("log", "linear"), rm_coi = TRUE, n_threads = 2L )
x |
Real-valued time series. The time steps are assumed to be evenly spaced. |
x_sample_freq |
Sampling rate of input time series |
sigma |
Sets a dimensionless parameter For more information, see Defaults to |
y_sample_freq |
Sampling rate of output time series, in frequency units (see |
freq_begin, freq_end
|
Optionally specifies the frequency range |
n_freqs |
Number of frequency bins generated by the CWT. The frequencies
are linearly or logarithmically distributed, depending on the |
freq_scale |
One of |
rm_coi |
|
n_threads |
Number of threads used by the computation, if supported by your platform.
Defaults to 2 threads (to accommodate CRAN requirements).
If |
The wavelet used in this calculation is the so called Morlet wavelet,
a sinusoidal wave modulated by a Gaussian whose spread is controlled by
the argument sigma.
See the original paper Arts, L.P.A., van den Broek, E.L. The fast continuous wavelet transformation (fCWT) for real-time, high-quality, noise-resistant time–frequency analysis. Nat Comput Sci 2, 47–58 (2022). doi:10.1038/s43588-021-00183-z
The scalogram, a numeric real-valued matrix with a time (rows) and a
frequency (columns) dimension, curated with some additional properties.
Its dimensions are c(ceiling(length(x) / k), n_freqs), where k is the
number of input samples averaged per output sample (see y_sample_freq;
k = 1 if y_sample_freq = x_sample_freq). The columns are ordered from
the highest (freq_end) to the lowest (freq_begin) frequency.
This matrix is wrapped into a S3-class fcwtr_scalogram so that plotting and
coercion functions can be used conveniently. Use as.matrix() to strip
the curated information. Or use as.data.frame() to convert to another
data format.
ts_sin_440 <- sin((1:5000) * 2 * pi * 440 / 44100) fcwt( ts_sin_440, x_sample_freq = u(44.1, "kHz"), sigma = 5, freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10 )ts_sin_440 <- sin((1:5000) * 2 * pi * 440 / 44100) fcwt( ts_sin_440, x_sample_freq = u(44.1, "kHz"), sigma = 5, freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10 )
Performs a fast continuous wavelet transform on long sequences by sequentially
processing chunks (batches) of the input signal.
This is only useful for very long signals that cannot be processed by
fcwt() in one go.
It should not be used on short signals since boundary artefacts are
automatically discarded (and those potentially dominate for short signals).
fcwt_batch( x, x_sample_freq, sigma = 2 * pi, y_sample_freq = 3/sigma_res(sigma, freq_end)$time, freq_begin = 2 * x_sample_freq/length(x), freq_end = x_sample_freq/2, n_freqs = 3 * ceiling(log(du(freq_end/freq_begin), base = 1 + sigma_freq_res_rel(sigma))), freq_scale = c("log", "linear"), max_batch_size = default_max_batch_size(x_sample_freq, y_sample_freq, n_freqs), n_threads = 2L, progress_bar = FALSE )fcwt_batch( x, x_sample_freq, sigma = 2 * pi, y_sample_freq = 3/sigma_res(sigma, freq_end)$time, freq_begin = 2 * x_sample_freq/length(x), freq_end = x_sample_freq/2, n_freqs = 3 * ceiling(log(du(freq_end/freq_begin), base = 1 + sigma_freq_res_rel(sigma))), freq_scale = c("log", "linear"), max_batch_size = default_max_batch_size(x_sample_freq, y_sample_freq, n_freqs), n_threads = 2L, progress_bar = FALSE )
x |
Real-valued time series. The time steps are assumed to be evenly spaced. |
x_sample_freq |
Sampling rate of input time series |
sigma |
Sets a dimensionless parameter For more information, see Defaults to |
y_sample_freq |
Sampling rate of output time series, in frequency units (see |
freq_begin, freq_end
|
Optionally specifies the frequency range |
n_freqs |
Number of frequency bins generated by the CWT. The frequencies
are linearly or logarithmically distributed, depending on the |
freq_scale |
One of |
max_batch_size |
The maximal batch size (number of input samples) that is used for splitting up the input sequence. This limits the memory that is needed while processing a batch, which is roughly
bytes per input sample, where Independent of the batch size, the outputs of all batches are kept and finally joined, which needs about twice the memory of the final result. The actual batch size is the largest batch size that is not larger than
|
n_threads |
Number of threads used by the computation, if supported by your platform.
Defaults to 2 threads (to accommodate CRAN requirements).
If |
progress_bar |
Monitoring progress can sometimes be useful when performing time consuming
operations. Setting |
fcwt() computes the result frequency by frequency and averages over time
on the fly (see its y_sample_freq argument), so the size of its output
is usually not the limiting factor. However, it performs Fourier transforms
over the whole input signal. This requires memory proportional to the
signal length (several single-precision complex copies of the signal,
zero-padded to the next power of two), and the signal length is limited to
samples. For instance, a recording of 24 hours at a sampling
rate of 44100 Hz has about samples.
This function splits up the input sequence into overlapping batches,
processes each batch separately with fcwt(), removes the boundary
artefacts of each batch, and joins the outputs together.
Attention: In contrast to fcwt() boundary artefacts are automatically removed,
so some information at the beginning and the end of the
sequence is lost. (The amount depends on the lowest frequency freq_begin,
since low-frequency wavelets are spread out the most in time.)
The scalogram, a numeric real-valued matrix with dimensions roughly
dim ~ c(length(x) * y_sample_freq / x_sample_freq, n_freqs).
The exact length of the output depends on boundary effect details.
This matrix is wrapped into a S3-class "fcwtr_scalogram" so that plotting and
coercion functions can be used conveniently.
fcwt_batch( ts_sin_sin, x_sample_freq = u(44.1, "kHz"), sigma = 10, y_sample_freq = u(100, "Hz"), freq_begin = u(100, "Hz"), freq_end = u(11000, "Hz"), n_freqs = 30 )fcwt_batch( ts_sin_sin, x_sample_freq = u(44.1, "kHz"), sigma = 10, y_sample_freq = u(100, "Hz"), freq_begin = u(100, "Hz"), freq_end = u(11000, "Hz"), n_freqs = 30 )
This function checks if fCWTr was compiled with OpenMP support. It is
responsible for the multithreading capabilities of fcwt(). If OpenMP is
not enabled the parameter n_threads of fcwt() is ignored.
openmp_enabled()openmp_enabled()
OpenMP is used by fCWTr if the compiler supports it. In addition, the
Fourier transforms are multithreaded only if the fftw library on your
platform comes with OpenMP support (libfftw3f_omp); otherwise they run
single-threaded.
On Windows, OpenMP support is disabled, since the fftw library provided by Rtools is compiled without OpenMP support.
When using pre-built package binaries, it depends on the (CRAN) build server whether or not these conditions are met. When installing the package from source, the installation script detects whether these conditions are met.
( TRUE | FALSE )
Returns TRUE if OpenMP support is enabled, FALSE otherwise.
openmp_enabled()openmp_enabled()
Plots the scalogram resulting from fcwt().
Requires ggplot2.
## S3 method for class 'fcwtr_scalogram' plot(x, n = 1000, time_unit = NULL, freq_unit = "Hz", transf = identity, ...)## S3 method for class 'fcwtr_scalogram' plot(x, n = 1000, time_unit = NULL, freq_unit = "Hz", transf = identity, ...)
x |
An "fcwtr_scalogram" object resulting from |
n |
The plotting function reduces the time resolution by averaging
to generate a reasonable graphics format. |
time_unit |
A time unit that is used for the x-axis scale, e.g. |
freq_unit |
A frequency unit that is used for the y-axis scale.
Defaults to "Hz" - "Hertz".
See |
transf |
A function, taking a vector and returning a vector, that is used to transform the scalogram values before plotting. |
... |
Additional arguments are ignored. |
No return value, called for side effects.
ts_sin_440 <- sin((1:4410) * 2 * pi * 440 / 44100) res <- fcwt( ts_sin_440, x_sample_freq = u(44100, "Hz"), freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10, sigma = 5 ) plot(res, time_unit = "ms")ts_sin_440 <- sin((1:4410) * 2 * pi * 440 / 44100) res <- fcwt( ts_sin_440, x_sample_freq = u(44100, "Hz"), freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10, sigma = 5 ) plot(res, time_unit = "ms")
print() prints its argument and returns it invisibly (via invisible(x)).
## S3 method for class 'fcwtr_scalogram' print(x, ...)## S3 method for class 'fcwtr_scalogram' print(x, ...)
x |
The "fcwtr_scalogram" object resulting from |
... |
further arguments passed to or from other methods. |
Returns the argument x invisibly.
Given two or more scalograms with identical sampling frequencies, frequency scales and sigma, it can be useful to combine several into a single object creating a longer time series. The function errs if these conditions are not satisfied.
## S3 method for class 'fcwtr_scalogram' rbind(...)## S3 method for class 'fcwtr_scalogram' rbind(...)
... |
One or more "fcwtr_scalogram" objects, generated by |
The scalograms are stitched together in chronological fashion (i.e. the first argument will be the initial piece, etc.). Time offset information is kept from the first piece.
Returns a new time-wise combined "fcwtr_scalogram" object.
ts_sin_440 <- sin((1:5000) * 2 * pi * 440 / 44100) res <- fcwt( ts_sin_440, x_sample_freq = u(44.1, "kHz"), freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10, sigma = 5 ) print(res) # doubled scalogram res_doubled <- rbind(res, res) print(res_doubled)ts_sin_440 <- sin((1:5000) * 2 * pi * 440 / 44100) res <- fcwt( ts_sin_440, x_sample_freq = u(44.1, "kHz"), freq_begin = u(50, "Hz"), freq_end = u(1000, "Hz"), n_freqs = 10, sigma = 5 ) print(res) # doubled scalogram res_doubled <- rbind(res, res) print(res_doubled)
For a given sigma this function calculates
the expected relative frequency resolution respectively.
sigma_freq_res_rel(sigma)sigma_freq_res_rel(sigma)
sigma |
The dimensionless positive parameter in |
A number p representing the relative frequency resolution. I.e. at a given
frequency f, the frequency resolution is f*p.
Other sigma:
sigma_from_freq_res(),
sigma_from_freq_res_rel(),
sigma_from_time_res(),
sigma_res()
sigma_freq_res_rel(1)sigma_freq_res_rel(1)
Setting the correct value for sigma in fcwt() for a particular
use case is important.
Sigma controls the wavelet spread used by the FCWT and so determines
the time-/frequency resolution (depending on a given reference frequency).
sigma_from_freq_res(res, freq)sigma_from_freq_res(res, freq)
res |
The required frequency resolution in frequency units (see |
freq |
The reference frequency where the required resolution must hold.
Must be a quantity with frequency units (see |
If you set a high frequency resolution, the time resolution of the output signal will suffer, and vice versa. Determining the correct balance for a particular use case can be crucial. This function determines the value of sigma for a particular frequency resolution requirement.
A dimensionless number controlling the FCWT wavelet spread,
corresponding to the sigma argument in fcwt().
Other sigma:
sigma_freq_res_rel(),
sigma_from_freq_res_rel(),
sigma_from_time_res(),
sigma_res()
ref_freq <- u(440, "Hz") sigma <- sigma_from_freq_res(u(7, "Hz"), ref_freq) sigma_res(sigma, ref_freq)ref_freq <- u(440, "Hz") sigma <- sigma_from_freq_res(u(7, "Hz"), ref_freq) sigma_res(sigma, ref_freq)
Setting the correct value for sigma in fcwt() for a particular
use case is important.
Sigma controls the wavelet spread used by the FCWT and so determines
the time-/frequency resolution (depending on a given reference frequency).
sigma_from_freq_res_rel(res)sigma_from_freq_res_rel(res)
res |
The required relative frequency resolution, a number between 0 and 1. |
If you set a high frequency resolution, the time resolution of the output signal will suffer, and vice versa. Determining the correct balance for a particular use case can be crucial. This function determines the value of sigma for a particular relative frequency resolution requirement. Note that the relative frequency resolution does not depend on the frequency itself, in contrast to the absolute frequency resolution.
A dimensionless number controlling the FCWT wavelet spread,
corresponding to the sigma argument in fcwt().
Other sigma:
sigma_freq_res_rel(),
sigma_from_freq_res(),
sigma_from_time_res(),
sigma_res()
ref_freq <- u(440, "Hz") sigma <- sigma_from_freq_res_rel(0.2) sigma_res(sigma, ref_freq)ref_freq <- u(440, "Hz") sigma <- sigma_from_freq_res_rel(0.2) sigma_res(sigma, ref_freq)
Setting the correct value for sigma in fcwt() for a particular
use case is important.
Sigma controls the wavelet spread used by the FCWT and so determines
the time-/frequency resolution (depending on a given reference frequency).
sigma_from_time_res(res, freq)sigma_from_time_res(res, freq)
res |
The required time resolution in time units (see |
freq |
The reference frequency where the required resolution must hold.
Must be a quantity with frequency units (see |
If you set a high frequency resolution, the time resolution of the output signal will suffer, and vice versa. Determining the correct balance for a particular use case can be crucial. This function determines the value of sigma for a particular time resolution requirement.
A dimensionless number controlling the FCWT wavelet spread,
corresponding to the sigma argument in fcwt().
Other sigma:
sigma_freq_res_rel(),
sigma_from_freq_res(),
sigma_from_freq_res_rel(),
sigma_res()
ref_freq <- u(440, "Hz") sigma <- sigma_from_time_res(u(10, "ms"), ref_freq) sigma_res(sigma, ref_freq)ref_freq <- u(440, "Hz") sigma <- sigma_from_time_res(u(10, "ms"), ref_freq) sigma_res(sigma, ref_freq)
For a given sigma and reference frequency freq this function calculates
the expected time and frequency resolution respectively.
sigma_res(sigma, freq)sigma_res(sigma, freq)
sigma |
The dimensionless positive parameter in |
freq |
The reference frequency where the frequency and time resolution are
calculated. Must be a quantity with frequency units (see |
Note that this resolution depends on the reference frequency, since the FCWT scales the wavelet spread depending on the frequency in a natural way. (in contrast to a simple fixed-windowed Fourier Transform).
A named list with two elements: "time" and "freq", in time and frequency
units. They obey the property .
Other sigma:
sigma_freq_res_rel(),
sigma_from_freq_res(),
sigma_from_freq_res_rel(),
sigma_from_time_res()
sigma_res(1, u(440, "Hz"))sigma_res(1, u(440, "Hz"))
A piano playing the note A4 (440 Hz). Its sample frequency is 11025 Hz.
ts_piano_samplets_piano_sample
A numeric vector of length 438461 containing a time series signal.
Assuming a sample rate of 44100 Hz, the sine wave's frequency is 440 Hz, and the signal is 1 second long.
ts_sin_440ts_sin_440
A numeric vector of length 44100 containing a time series signal.
The frequency itself is changing in a sinusoidal fashion. Assuming a sample rate of 44100 Hz, the signal is 1 second long and its frequency varies between about 50 Hz and 10 kHz.
ts_sin_sints_sin_sin
A numeric vector of length 44100 containing a time series signal.
Assuming a sample rate of 44100 Hz, the signal consists of two consecutive parts of 3000 samples each: superimposed sine waves of 440 Hz, 880 Hz and 100 Hz in the first part, and of 500 Hz, 1200 Hz and 50 Hz in the second part.
ts_sin_superposts_sin_superpos
A numeric vector of length 6000 containing a time series signal.
A wrapper around units::set_units() mostly to have a short name to
create a dimensionful quantity.
u(x, unit = "1")u(x, unit = "1")
x |
A numeric vector to be augmented with a unit. |
unit |
A character indicating the unit. See |
u(10, "km") # 10 kilometer u(10, "mm") # 10 mm # comparison taking into account the unit u(100, "m") > u(1, "km")u(10, "km") # 10 kilometer u(10, "mm") # 10 mm # comparison taking into account the unit u(100, "m") > u(1, "km")