Giter Club home page Giter Club logo

units's People

Contributors

bart1 avatar billdenney avatar cregouby avatar edzer avatar enchufa2 avatar gmp216 avatar jeroen avatar kendonb avatar krlmlr avatar langmm avatar lewinfox avatar lionel- avatar mailund avatar mjwoods avatar t-kalinowski avatar uchidamizuki avatar yasirs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

units's Issues

Non Integer Powers

A possible suggestion on a way you could incorporate non-integer powers from -1 to 1.

It multiplies each symbolic unit element by the power after checking they are wholly divisible. There is probably a nicer way of coding it.

Within arith.R replace the pw section with:

if (pw) { # FIXME: I am not sure how to take powers of non-integers yet
    if (inherits(e2, "units") || length(e2) > 1L)
      stop("power operation only allowed with length-one numeric power")
    # if (round(e2) != e2)
    #   stop("currently you can only take integer powers of units")
    
    # we repeat each unit the number of times given by e2. They are already
    # sorted so they will remain sorted. We need to flip numerator and denominator
    # when the power is negative and we have a special case when it is zero where
    # units should be removed.
    if (e2 == 0) {
      attr(e1, "units") <- unitless
    } else if (e2 >= 1) {
      if (round(e2) != e2) {
        stop("currently you can only take integer powers of units above 1")}
      attr(e1, "units") <- .symbolic_units(rep(units(e1)$numerator, e2),
                                           rep(units(e1)$denominator, e2))
    } else if (e2 <= -1) {
      if (round(e2) != e2) {
        stop("currently you can only take integer powers of units below -1")}
      attr(e1, "units") <- .symbolic_units(rep(units(e1)$denominator, abs(e2)),
                                           rep(units(e1)$numerator, abs(e2)))
    } else if (e2 > 0) { # 0 < e2 < 1
      if ((1/e2) %% 1 != 0) {
        stop("not a integer divisor")} # work on wording
      if (any((table(units(e1)$denominator)*e2) %% 1 != 0) | 
          any((table(units(e1)$numerator)*e2) %% 1 != 0)) {
            stop("units not divisible")} # work on wording
      attr(e1, "units") <- .symbolic_units(
        rep(unique(units(e1)$numerator),table(units(e1)$numerator)*e2),
        rep(unique(units(e1)$denominator),table(units(e1)$denominator)*e2))
    } else {
      if ((1/e2) %% 1 != 0) {
        stop("not a integer divisor")} # work on wording
      if (any((table(units(e1)$denominator)*e2) %% 1 != 0) | 
          any((table(units(e1)$numerator)*e2) %% 1 != 0)) {
        stop("units not divisible")} # work on wording
      attr(e1, "units") <- .symbolic_units(
        rep(unique(units(e1)$denominator),table(units(e1)$denominator)*abs(e2)),
        rep(unique(units(e1)$numerator),table(units(e1)$numerator)*abs(e2)))
    }
    
  }

sin, cos etc on radial units

We have

> set_units(1:3, rad)
Units: rad
[1] 1 2 3
> sin(set_units(1:3, rad))
[1] 0.8414710 0.9092974 0.1411200
Warning message:
In Math.units(set_units(1:3, rad)) : Operation sin not meaningful for units

but this is actually meaningful.

Consider automating udunits installation?

I am on RHEL6.3 (no root access) and it seems like my only option to install udunits is to install from source.

System requirements seem like a barrier to reproducibility that would be nice to overcome. I imagine automating this would encourage some adoption of units and sf .

Is this even possible?

many udunits not accepted

> set_units(1, °C)
Error: unexpected input in "set_units(1, �"

although

> ud_units[["°C"]]
1 °C

and

> set_units(1, degree_C)
Error in eval(substitute(value), ud_units, parent.frame()) : 
  object 'degree_C' not found

although degree_C is a name (alias) in xml/udunits/udunits2-common.xml.

Cleanup unitless handling

> units(make_unit("1"))
$numerator
[1] "1"

$denominator
character(0)

attr(,"class")
[1] "symbolic_units"
> units(make_unit(""))
$numerator
[1] ""

$denominator
character(0)

attr(,"class")
[1] "symbolic_units"
> unitless
$numerator
character(0)

$denominator
character(0)

attr(,"class")
[1] "symbolic_units"

Units not printed as inline output in R Markdown documents

I am trying to use the units package in R Markdown. It would make it very easy to do some calculations and write about the results. For some reason the units are not printed after the numbers in the inline R code. See the example below. I am unsure whether it is a problem with the print.units() function (I don't think it is, since it works nicely from the console) or how R Markdown handles printing in inline R code.

---
title: "Units inline problem"
author: "Emil Tveden Bjerglund"
date: "9 aug 2017"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(units)
```

We can define things with units, and when called from within a chunk they print as expected.

```{r}
v <- set_units(10, m/s)
t <- set_units(25, s)
d <- v*t
d
```

But when trying to write about the calculations and pasting in variables (i.e. `r d`) the units are     not printed. Trying to do `r print(d)` prints nothing.

image

missing parentheses

This

> make_unit("m/s") * make_unit("km/h")
1 km/h*m/s

doesn't look good.

Inches: units "in" conflicts with R's "in"

auto plotting inches breaks axis labels (in is an R reserved word):


> library(units)
> inch = make_unit("in")
> x = rnorm(100) * inch
> hist(x)
Error in parse(text = str) : <text>:1:14: unexpected 'in'
1: x*~group('[',in
                 ^

print and read units the way udunits does.

udunits understands units like m s-1, and that seems the prefered format for printing, instead of what we now do, m*m/s/s would have to become m2 s-2. units now understands such strings, but drops the logic that allows simplification later on because we don't parse m2 s-2.

> make_unit("m2 s-2") + with(ud_units, m^2/s^2)
2 (m2 s-2)
> str(make_unit("m2 s-2") + with(ud_units, m^2/s^2))
Class 'units'  atomic [1:1] 2
  ..- attr(*, "units")=List of 2
  .. ..$ nominator  : chr "m2 s-2"
  .. ..$ denominator: chr(0) 
  .. ..- attr(*, "class")= chr "symbolic_units"
> make_unit("m2 s-2") * make_unit("s2") # can be simplified...
1 (m2 s-2)*s2 # but isn't!

See here for a list of CF units. They are read by

demo(cf)

units for functions

Dear all,

Is it possible to add units to functions? So far I've tried without success:

f <- function(V) {3}
f <- f * parse_unit(paste0("g km-1"))
units(f) <- with(ud_units, g/km)
units(f(1)) <- with(ud_units, g/km)

support complex and arbitrary precision numbers

> set_units(3 * 4i, km/h)
Error in UseMethod("set_units") : 
  no applicable method for 'set_units' applied to an object of class "complex"

possibly deal with other types, such as those in packages gmp or Rmpfr.

incorrect acres to ft^2 conversion

Hi, according to Units and Symbols Found in the UDUNITS2 Database, an acre is

unit of area in the US Customary System, used in land and sea floor measurement, equal to 43560 square feet (exact).

If that is true, then the following is incorrect:

library(units)

ad <- with(ud_units, 1 * acre)

ad
1 acre


units(ad) <- with(ud_units, ft^2)

ad
43560.17 ft^2

If the current definition of acres is incorrect within units, then will you correct it then?

Thank you.

Irucka Embry

handle non-units in %*%

Right now, we have (building upon the example of the R Journal vignette)

as_units(year_duration) %*% rep(1, length(year_duration))

through an error, where

> as_units(year_duration) %*% rep(set_units(1), length(year_duration)) / length(year_duration)
Units: d
         [,1]
[1,] 365.2545

doesn't. This needs to be handled more gracefully.

Make it easier to find the list of predefined units?

I have skimmed through blog posts, function documentation, github README, and can't find a link to this. Am I being blind?

I would suggest, at least, putting a link to this on all the function documentation pages in details.

how to set unitless units?

> set_units(1:3, m)
Units: m
[1] 1 2 3
> set_units(1:3, 1)
Error: inherits(u, "units") is not TRUE
> set_units(1:3, unitless)
Error: inherits(u, "units") is not TRUE

this should be easier.

matrices coerced to vectors

Hi there -- love this package. Thanks for all your work on it.

When I use some mathematical operations such as inequalities on units objects that are matrices, the matrices are coerced into vectors.

With multiplication between a matrix and for example a scalar, it works as I expected, resulting in a matrix:

> my_matrix <- set_units(cbind(1:3, 4:6), "km")

> my_matrix * set_units(5, "km")
Units: km^2
[,1] [,2]
[1,]    5   20
[2,]   10   25
[3,]   15   30

However, when I do the same thing except use an inequality instead of multiplication, a vector results:

> my_matrix <= set_units(5, "km")
[1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE

Apologies if this has been answered elsewhere!

Pipe-friendly unit conversion?

This could be something like convert_units:

with(ud_units,
     1:10 %>% 
       as.units(ha) %>% 
       convert_units(m^2)
)

Instead of:

with(ud_units,
     1:10 %>% 
       as.units(ha) %>% 
       `units<-`(m^2)
)

boxplot of units

> 1:3 %>% set_units('m') %>% boxplot(x=.)
Error in Summary.units(c(1, 1.5, 2, 2.5, 3), numeric(0), NULL, na.rm = FALSE) : 
  argument 2 is not of class units

boxplot.units might be needed?

thanks

get rid of parens around units

> units::set_units(x, m/s)
Units: m/s
 [1]  1  2  3  4  5  6  7  8  9 10
> units::set_units(x, "m/s")
Units: (m/s)
 [1]  1  2  3  4  5  6  7  8  9 10

they should not be needed.

Defining conversion for custom units

I really like this package, it is very useful. I already had the issue in my collaborations that conversion between units made by the user led to problem in the data that were exchange. So I really support this package!

Now, to the issue, I would like to define custom units that are generic, and allow to assign actual units a posteriori. A concrete example: I am developing a package where distances are measures in pixel units and time in number of frames. These units are very useful, but their actual units depends on a particular setup. So I would like the user to be able to read a file where I setup internally that it is in pixel units. If the user knows the actual length of the pixel, I would like this to automagically propagate.

I could also do that for frames, but I show you with pixel units what I did. I am not sure what the best syntax for this would be, but this is what I wanted to do:

px <- make_unit("px")
len <- runif(5)*px
print(len) # the units are properly set has px
px <- 255*ud_units$nm # so one pixel is 255 nm wide
print(len) # the units are still px. I guess this is expected, even though this would be nice to already have the conversion there
units(len) <- 255*ud_units$nm # throws an error 

The error is Error in `units<-.units`(`*tmp*`, value = 255) : cannot convert px into nm which, looking at the code is normal because it is executing .get_unit_conversion_constant that has a FIXME ;)

For the first way I wanted to assign actual units, maybe one should use a reactive expression. But I guess we should experiment.

Anyway, what do you think?

Feature request: engineering notation

Not included in R, but used all the time, is engineering notation.
This uses SI prefixes (kilo 10E3, Mega 10E6, Giga 10E9, etc).
It is something that you use all the time because it corresponds to normal units you use all the time (meter, kilometer, kg, tonne, etc).

It would be great if your package could include Engineering notation somehow.

%*% drops units without warning

Example:

> f = function(a, b, c) sum(a * b) / sum(c)
> g = function(a, b, c) sum(a %*% b) / sum(c)
> library(units)
> a = set_units(1:3, m)
> b = set_units(1:3, s)
> c = set_units(1:3, m*s)
> f(a,b,c)
2.333333 1
> g(a,b,c)
2.333333 1/m/s

(see also r-quantities/errors#11)

The resolution I can see is to have

2 * set_units(2, km/h)

give a warning that 2 has no units, but is assumed to have unit 1, and explicitly require

set_units(2) * set_units(2, km/h)

to get rid of this warning. This means: to drop the implicit assumption that numbers without units have unit 1. (In the context of errors: not implicitly assume that unclassed numbers have zero error.)

Comparing units using ==

I was just trying the units package and got some strange results when comparing to vectors of different units but the same quantity. Here I construct two vectors of the same speed but one in m/s while the other one is in km/h. Two things are there to notice, the order of arguments matters for the results and second even thought the speeds are the same "==" does not consider them the same. For the later issue it probably relates to numerical precision of comparison. An alternative would be to check if the values are the same within some precision limit but I'm not sure if that does not have other unintended consequences or produces unexpected results. An alternative would be to provide some methods that check for equality using some tolerance like all.equal as shown below.

For the order of the arguments I guess one unit is converted in the other one (second into first). An alternative would in case of two different units always convert into SI units so the order of the argument would at least not matter.

> require(units)
> a<-set_units(1:4,m/s)
> bb<-set_units(c(3.6,7.2, 10.8,14.4),km/h)
> a==bb
[1]  TRUE  TRUE FALSE  TRUE
> bb==a
[1] FALSE FALSE FALSE FALSE
> as.numeric(bb)-as.numeric(set_units(a,km/h))
[1] 4.440892e-16 8.881784e-16 1.776357e-15 1.776357e-15
> as.numeric(a)-as.numeric(set_units(bb,m/s))
[1]  0.000000e+00  0.000000e+00 -4.440892e-16  0.000000e+00
> abs(as.numeric(bb)-as.numeric(set_units(a,km/h))) < sqrt(.Machine$double.eps)
[1] TRUE TRUE TRUE TRUE
> sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 17.04

Matrix products: default
BLAS: /usr/lib/openblas-base/libblas.so.3
LAPACK: /usr/lib/libopenblasp-r0.2.19.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=de_DE.UTF-8       
 [4] LC_COLLATE=en_US.UTF-8     LC_MONETARY=de_DE.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=de_DE.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] units_0.4-5

loaded via a namespace (and not attached):
[1] compiler_3.4.1 tools_3.4.1    udunits2_0.13 

.get_conversion_constant_sequence

in .get_conversion_constant I had to uncomment the call to .get_conversion_constant_sequence, otherwise I get this:

> library(units)
> x = make_unit("m")
> y = make_unit("s")
> x + x * y
2 m

@mailund repair, or remove?

Should user-defined units always be parsed?

This arose here: thomasp85/ggforce#15 (comment)

> make_unit("m sec-1")
1 (m sec-1)
> parse_unit("m sec-1")
1 m/sec
> 1/make_unit("m sec-1")
1 1/(m sec-1)
> 1/parse_unit("m sec-1")
1 sec/m

Should we always try to parse a unit when using make_unit?
parse_unit now works for CF units, but miserably fails when a / is present:

> parse_unit("m/sec-1")
1 1/(m/sec)

units not working due to missing udunits C libraries

The package units depends on the packages udunits2. However, while the udunits2 package seems to successfully install after running install.packages('udunits2'), it doesn't actually work out-of-the-box. You can see this when you try to install it from from source.

I received the following error when I tried to install udunits2 from source...

> install.packages('udunits2', type = 'source')

[OMITTED]

-----Error: libudunits2 not found-----
     If the udunits2 library is installed in a non-standard location,
     use --configure-args='--with-udunits2-lib=/usr/local/lib' for example,
     or --configure-args='--with-udunits2-include=/usr/include/udunits2'
     replacing paths with appropriate values for your installation.
     You can alternatively use the UDUNITS2_INCLUDE and UDUNITS2_LIB
     environment variables.
     If udunits2 is not installed, please install it.
     It is required for this package.
ERROR: configuration failed for package ‘udunits2’
-----Error: libudunits2 not found-----
     If the udunits2 library is installed in a non-standard location,
     use --configure-args='--with-udunits2-lib=/usr/local/lib' for example,
     or --configure-args='--with-udunits2-include=/usr/include/udunits2'
     replacing paths with appropriate values for your installation.
     You can alternatively use the UDUNITS2_INCLUDE and UDUNITS2_LIB
     environment variables.
     If udunits2 is not installed, please install it.
     It is required for this package.
ERROR: configuration failed for package ‘udunits2’

Hence, what we need are these libraries.

Here is how I solved it on my mac using Homebrew.

  1. In your Terminal.app, do the following:
brew install udunits

While I used Homebrew, it appears you can download the libraries here. I did not do it this way, but I'm assuming that if you do this successfully, then you should be able to do steps 2 and 3.

  1. Once installed, go to R and install udunits2 from source...
install.packages('udunits2', type = 'source', repo = 'cran.rstudio.com')
  1. Install units (I installed the development version).
devtools::install_github('edzer/units', type = 'source')

Or

install.packages('units', type = 'source')

DONE

logarithmic units not supported in math

When you take the log of a units, the "units" attribute is set as a character, not a units or symbolic_units. All subsequent math operations thus fail.

x <- c(1, 2) * ud_units$m
x <- log(x)
str(x)
str(units(x))
min(x) #error
x + x #error

sort out udunits calender and R's calender

e.g. how to convert from POSIXct or Date to a udunits value. See also here.

The question is whether udunits calender has additional value to R:

> d = make_units("days since 1970-01-01")
> as.numeric(as.Date("1971-01-01")) * d
365 (days since 1970-01-01)
> d * as.Date("1974-01-01")
1461 (days since 1970-01-01)
Warning message:
Incompatible methods ("Ops.units", "Ops.Date") for "*" 

For this particular case, I think the warning message could disappear, since both have identical units.

Convenient constructor

I think it would be nice to have a convenient constructor like:

unit(100, km / s)
unit(10, m ^ 3)

Conflict with spatstat print.units()

When "spatstat" is attached, printing objects of class "units" fails (moved over from r-spatial/sf#523):

library("units")

# works
set_units(1000, "m")
print(set_units(1000, "m"))

library("spatstat")

# error
set_units(1000, "m")
print(set_units(1000, "m"))

# but this works
units:::print.units(set_units(1000, "m"))

The error is:

Error: $ operator is invalid for atomic vectors

Because spatstat's print.units() overrides the correct method. Changing the order in which packages are loaded does not help. spatstat's print.units() is not exported as a S3 method.

Same issue at spatstat/spatstat#63.

FR: as.hms.units()

Simply as.hms.units <- function(x, ...) as.hms(as.dt(x, ...)), but probably needs to import hms.

make_units2() and .udunits_symbols_info()

Hello,

As part of a project I recently built something ontop of the units package, and in the process I made some helper functions that might be beneficial to others.

make_unit2()

The first is make_unit2(). (There is probably a better name for it, but this was the best I could come up with after a few minutes of thought).

This was to address some issues I had with units::make_unit(). The first is that make_unit does not parse strings correctly as expressions into denominator and numerator fields of the “symbolic_units” object.

format(units(make_unit("ug/l")))
##   numerator denominator 
##      "ug/l"          ""
format(units(make_unit2("ug/l")))
##   numerator denominator 
##        "ug"         "l"

This had downstream effects in that it a) interfered with unit simplification, and b) units were printed in parenthesis by default ("

format(make_unit("ug/l"))
## [1] "1 (ug/l)"
format(make_unit2("ug/l"))
## [1] "1 ug/l"

Finally, another issue was that make_unit would create units that were not valid or did not return true for udunits2::ud.is.parseable(). I think that flexibility is important to have, but I needed a version that would throw an error instead of create an invalid or unrecognized unit.

make_unit("foo")
## 1 foo
try(make_unit2("foo"))

make_unit2() is somewhat fancy in that it works with both strings or expressions. Here are some extended examples I included in the documentation:

# different ways to specify units
 # all 3 should be identical
 make_unit2(ug/l)
## 1 ug/l
 make_unit2("ug/l")
## 1 ug/l
 string <- "ug/l"
 make_unit2(string)
## 1 ug/l
 # valid unit names not found in units::ud_units also parse
 make_unit2(ug/gallon)
## 1 ug/gallon
 make_unit2("ug/gallon")
## 1 ug/gallon
 string <- "ug/gallon"
 make_unit2(string)
## 1 ug/gallon
 # the normal evaluation of the supplied argument is attempted first before
 # inspecting supplied expression. The expression is only inspected if it does
 # not resolve to a character vector"
 ug <- "kilogram"
 make_unit2(ug)
## 1 kilogram
 # note that even if one of the symbols is bound, NSE is done on the whole
 # expression or not at all
 make_unit2(ug/l)
## 1 ug/l
 # to avoid expression parsing, use argument .SEonly (e.g., defensive programmig
 # inside a function)
 # make_unit2(ug/l, .SEonly = TRUE) # ERROR
 make_unit2("ug/l", .SEonly = FALSE) # the default
## 1 ug/l
 make_unit2(ug, .SEonly = TRUE)
## 1 kilogram
 # some examples for how to convert units
 # first assign units to a numeric, this makes a vector with units
 x <- 1:3
 (units(x) <- make_unit2(ug/l))
## 1 ug/l
 # then, assigning units to a vector with units performs conversion
 set_units(x, make_unit2("mg/l"))
## Units: mg/l
## [1] 0.001 0.002 0.003
 set_units(x, make_unit2("g/l"))
## Units: g/l
## [1] 1e-06 2e-06 3e-06
 set_units(x, make_unit2("ug/tbsp"))
## Units: ug/tbsp
## [1] 0.01478677 0.02957353 0.04436030
 set_units(x, make_unit2(kg/US_liquid_gallon))
## Units: kg/US_liquid_gallon
## [1] 3.785412e-09 7.570824e-09 1.135624e-08
 # `set_units(x, u)` is a pipe friendly equivelant version of `units(x) <- u`
 (units(x) <-  make_unit2("mg/l") )
## 1 mg/l
 units(x) <- make_unit2(ug/l)

 # reserved words like in and special characters like % and ' must be
 # backticked if passed as bare expression, however they work just fine if
 # passed as a character string.
 make_unit2(`in`)
## 1 in
 make_unit2("in")
## 1 in
 make_unit2("%/gallon")
## 1 %/gallon
 make_unit2("%/'")
## 34.37747 1
 make_unit2("'/%")
## 0.02908882 1
 make_unit2(`%`/gallon)
## 1 %/gallon
 make_unit2(`%`*T)
## 1 %*T
 make_unit2(T/F)
## 1 T/F
 # make_unit2(T/FALSE) # ERROR

 # attempting to convert between incompatable units throws an error
 # units(x) <- make_unit2(ft) # ERROR
 # not recognized units throw an error
 # make_unit2(foo/bar) # ERROR

.udunits_symbols_info()

Finally, since there are many more units than there are symbols in ud_units, and since ud_units does not come with a key, and since make_unit2 accepts not only symbols but the full unit names, I wanted to easily pull up a reference for what are the accepted units. hence this function. Here, i parse the udunits2.xml file into a dataframe

.udunits_symbols_info()
## udunits system database read from C:/Users/kalinowskit/Documents/R/win-library/3.4/udunits2/share/udunits/udunits2.xml
## # A tibble: 275 x 11
##    source_xml_table_name symbol symbol_aliases name_singular
##                    <chr>  <chr>          <chr>         <chr>
##  1                  base      m                        meter
##  2                  base     kg                     kilogram
##  3                  base      s                       second
##  4                  base      A                       ampere
##  5                  base      K                       kelvin
##  6                  base    mol                         mole
##  7                  base     cd                      candela
##  8               derived    rad                       radian
##  9               derived     sr                    steradian
## 10               derived     Hz                        hertz
## 11               derived      g                         gram
## 12               derived      N                       newton
## 13               derived     Pa                       pascal
## 14               derived      J                        joule
## 15               derived      W                         watt
## # ... with 260 more rows, and 7 more variables:
## #   name_singular_aliases <chr>, name_plural <chr>,
## #   name_plural_aliases <chr>, def <chr>, definition <chr>, comment <chr>,
## #   dimensionless <lgl>
.udunits_prefix_info()
## udunits system database read from C:/Users/kalinowskit/Documents/R/win-library/3.4/udunits2/share/udunits/udunits2.xml
## # A tibble: 20 x 4
##    symbol symbol_aliases  name value
##     <chr>          <chr> <chr> <dbl>
##  1      Y                yotta 1e+24
##  2      Z                zetta 1e+21
##  3      E                  exa 1e+18
##  4      P                 peta 1e+15
##  5      T                 tera 1e+12
##  6      G                 giga 1e+09
##  7      M                 mega 1e+06
##  8      k                 kilo 1e+03
##  9      h                hecto 1e+02
## 10     da                 deka 1e+01
## 11      d                 deci 1e-01
## 12      c                centi 1e-02
## 13      m                milli 1e-03
## 14      µ           µ, u micro 1e-06
## 15      n                 nano 1e-09
## 16      p                 pico 1e-12
## 17      f                femto 1e-15
## 18      a                 atto 1e-18
## 19      z                zepto 1e-21
## 20      y                yocto 1e-24

If there is interest, I could submit a pull request with these 3 new functions.

Error message in misc tests.

I get the error message

Error in `units<-.units`(`*tmp*`, value = structure(list(numerator = "m",  : 
  cannot convert s into m

when I run the unit tests for misc. It is not an error, as such, the test correctly predicts an error, but the message is a bit annoying. I don't know why we get it, though...

Unit conversion on Temperature not accurate

Hi.

In my below attempt to convert Temperature units below I get an inaccurate result:

library(units)
Temp <- 75 * parse_unit('degF')
units(Temp) <- parse_unit('degK')
print(Temp)
# Result check with udunits2
udunits2::ud.convert(75,'degF','degK')

The result is:

> library(units)
> Temp <- 75 * parse_unit('degF')
> units(Temp) <- parse_unit('degK')
> print(Temp)
19194.58 degK
> udunits2::ud.convert(75,'degF','degK')
[1] 297.0389

The correct answer is 297K

I have used this method to convert units of Pressure, Length, Velocity, Time and Power seemingly without issue.

Am I doing something wrong?

Session info below:

> sessionInfo()
R version 3.3.2 (2016-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

locale:
[1] LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252   
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Australia.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] units_0.4-1

loaded via a namespace (and not attached):
[1] tools_3.3.2   udunits2_0.13 knitr_1.15.1 

Thanks for any assistance

Add support for acres

It would be useful for the final example to also work, building on r-spatial/sf#413

library(sf)
#> Linking to GEOS 3.5.1, GDAL 2.1.3, proj.4 4.9.2, lwgeom 2.3.2 r15302
library(units)
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
#> Reading layer `nc' from data source `/home/robin/R/x86_64-pc-linux-gnu-library/3.4/sf/shape/nc.shp' using driver `ESRI Shapefile'
#> Simple feature collection with 100 features and 14 fields
#> geometry type:  MULTIPOLYGON
#> dimension:      XY
#> bbox:           xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> epsg (SRID):    4267
#> proj4string:    +proj=longlat +datum=NAD27 +no_defs
a = st_area(nc[1, ])
units::set_units(x = a, value = km^2)
#> 1137.389 km^2
units::set_units(x = a, value = ha)
#> 113738.9 ha
units::set_units(a, acre)
#> Error in stopifnot(is.character(value)): object 'acre' not found

Pull request opportunities (flexible unit parsing, simpler function interface)

Thanks for bringing unit documentation and conversion to life in R with this wonderful package. I've been using it extensively for some heavy data parsing, and through that process, ended up building my own wrapper around the package. That is described in detail here:

https://github.com/ezwelty/units2

Now, I would love to incorporate some of the functionality I developed back into units, but figured it was best to bring it up for discussion before slapping some pull requests around. I look forward to your thoughts.

units2::parse_unit (vs. units::parse_unit)

  1. Supports product power form, arithmetic expressions, and any combination thereof.
  2. Correctly handles units with numbers in their names.
  3. units::parse_unit silently creates new units, which was dangerous for automation from unknown inputs. My version throws an error, but I could see adding an argument to control the behavior.
  4. A "side effect" of the parsing approached used by units2::parse_unit (evaluating against units::ud_units) is that it replaces unit names with their corresponding symbols. This is the behavior I wanted, as otherwise, it is hard to know whether the unit name was actually correctly recognized. But this could be addressed for example by adding a corresponding units::ud_units_synonyms to fallback on, which would also make unit names more transparent for users.

units2::deparse_unit (vs. units::as_cf)

Renamed for symmetry with parse_unit. I could never remember "as_cf".

units2::as_units & units2::convert_units (vs. units::as.units & units::set_units)

As opposed to their units equivalents, these allow either string or units objects as unit specification, for somewhat more compact coercion and conversion syntax:

library(magrittr)
x <- 1:10
from <- "meters s-1"
to <- "km hour-1"
# units
x %>%
  units::as.units(value = units::parse_unit(from)) %>%
  units::set_units(value = units::parse_unit(to))
# units2 equivalent
x %>%
  units2::convert_units(from = from, to = to)
# or
x %>%
  units2::as_units(from) %>%
  units2::as_units(to)

With units2::parse_unit supporting arithmetic expression in string form, I dropped the non-standard evaluation in units::set_units to avoid dangerous and/or confusing behavior:

units2::as_units(x, "meters/s")
units::set_units(x, meters/s)
meters <- 0.01
units::set_units(x, meters/s)

With string input, things always work the same way:

units::as.units(x, m/s) # does not work
units::set_units(x, m/s) # works
units::set_units(x, °/s) # does not work
units::set_units(x, `°`/s) # works
units2::as_units(x, "m/s") # always works the same way
units2::as_units(x, "°/s")

na.rm=TRUE doesn't work in summary functions

because it is not passed.

summaries.R:

 6 Summary.units = function(..., na.rm = FALSE) {
 ...
 11  args = list(...)
 ...
 23   as.units(do.call(.Generic, args), u)

fix:

23  as.units(do.call(.Generic, args, na.rm), u)

units missing in ud_units

many units are missing in ud_units, e.g. in or celsius

> library(units)
> with(ud_units, 2 * cm + 1 * ft)
32.48 cm
> with(ud_units, 2 * cm + 1 * in)
Error: unexpected 'in' in "with(ud_units, 2 * cm + 1 * in"

Strange behavior when performing operations of single elements with vectors

Hi,
I am using this package and I am performing a simple operation and I am getting what I think is a wrong result. Doing:

library(units)
H<-with(ud_units, ((1:10)*0.05)*m)
Q<-with(ud_units,1*m^3/s)

I am getting

Q
##1 m^3/s
H
##Units: m
## [1] 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50
H*Q
##Units: m^5/s
## [1] 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50

On the other hand, with simple values the behavior is as expected

H<-with(ud_units, 0.5*m)
Q<-with(ud_units,1*m^3/s)

then

Q
##1 m^3/s
H
##0.5 m
H*Q
##0.5 m^4/s

Is it a bug?

For reference, I have posted the same here: http://stackoverflow.com/questions/42248894/weird-behavior-of-package-units-or-misunderstanding

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.