Closed elipousson closed 1 year ago
I think that this is an upstream issue, i.e. a property of the UDUNITS library; please note that this R package is only an interface to that library, the package description mentions Uses the UNIDATA udunits library and unit database for unit compatibility checking and conversion.
This definitely is an upstream issue:
library(units)
#> udunits database from /usr/share/udunits/udunits2.xml
x <- set_units(1, foot)
y <- set_units(1, feet)
print(x, nsmall=20)
#> 1.00000000000000000000 [foot]
print(y, nsmall=20)
#> 1.00000000000000000000 [feet]
units(y) <- units(x)
print(x, nsmall=20)
#> 1.00000000000000000000 [foot]
print(y, nsmall=20)
#> 0.99999999999999988898 [foot]
print(set_units(set_units(x, m), foot), nsmall=20)
#> 0.99999999999999988898 [foot]
From the last line, there is some error when converting from/to SI and imperial units (which probably cannot be avoided), but the issue is that conversion from/to plural and singular units (and symbols) seems to go through the conversion to SI.
Thank you both for the quick and information replies! I went ahead and submitted an issue to the UDUNITS repository. I'm using units within a wrapper function so I can probably figure out a work around in the interim.
I wanted to share my wrapper function here in case anyone else finds this issue and either finds it useful or has a suggestion for a better approach:
is_same_units <- function(x, y) {
if (is.character(x)) {
x <- units::as_units(x)
}
if (is.character(y)) {
y <- units::as_units(y)
}
x <- units(x)
y <- units(y)
in_opts <- c("in", "inch", "inches", "international_inch", "international_inches")
ft_opts <- c("ft", "foot", "feet", "international_foot", "international_feet")
yd_opts <- c("yd", "yard", "yards", "international_yard", "international_yards")
nums <- c(x[["numerator"]], y[["numerator"]])
dens <- c(x[["denominator"]], y[["denominator"]])
if (any(
c(all(nums %in% in_opts), all(nums %in% ft_opts), all(nums %in% yd_opts))
) && all(dens == character(0))) {
return(TRUE)
}
units::as_units(x) == units::as_units(y)
}
is_same_units("inch", "inches")
#> [1] TRUE
is_same_units("international_inch", "international_inches")
#> [1] TRUE
is_same_units("foot", "feet")
#> [1] TRUE
is_same_units("in", "inch")
#> [1] TRUE
is_same_units("in", "international_inch")
#> [1] TRUE
is_same_units("ft", "foot")
#> [1] TRUE
Created on 2022-12-19 with reprex v2.0.2
Thanks, closing here.
I'll leave it to you, @Enchufa2 or @edzer to decide if it is appropriate to re-open this issue but it looks like the maintainers for UDUNITS do not believe this is an upstream issue and recommend using the ut_compare() method as a possible solution. I don't have any experience with R packages that build on C libraries but I'm happy to try to figure it out if you can point me in the direction of a place to start.
Fantastic!
I discovered what seem to be some inconsistencies in the handling of plural and abbreviated units "inch" and "foot" units. I initially thought this may just be how the pre-defined units from UDUNITS2 work but I noticed that "foot" and "feet" are listed as valid
name_singular_aliases
andname_plural_aliases
in the data.frame returned byunits::valid_udunits()
(and plural forms that work like degrees are not) so I'm unsure why these comparisons work the way they do.If there is another approach to verify that the strings "ft" and "foot" represent the same unit, I'd welcome the suggestion but I figured I'd open an issue just in case it is a bug (or at least a missing feature) that could be addressed.
Created on 2022-12-18 with reprex v2.0.2