Agreed that's it's rounding error, and all.equal would be the way to go.
I wouldn't call it a bug, it's simply part of working with floating point
numbers, any language has the same issue.
And while we're at it, I think the function can be a lot shorter:
.is_continous_evenly_spaced <- function(n){
length(n)>1 && isTRUE(all.equal(n[order(n)], seq(from=min(n), to=max(n),
length.out = length(n))))
}
Cheers, Emil
El vie., 31 ago. 2018 a las 15:10, Felix Ernst
(<[email protected]>) escribió:
>
> Dear all,
>
> I a bit unsure, whether this qualifies as a bug, but it is definitly a
strange behaviour. That why I wanted to discuss it.
>
> With the following function, I want to test for evenly space numbers,
starting from anywhere.
>
> .is_continous_evenly_spaced <- function(n){
> if(length(n) < 2) return(FALSE)
> n <- n[order(n)]
> n <- n - min(n)
> step <- n[2] - n[1]
> test <- seq(from = min(n), to = max(n), by = step)
> if(length(n) == length(test) &&
> all(n == test)){
> return(TRUE)
> }
> return(FALSE)
> }
>
> > .is_continous_evenly_spaced(c(1,2,3,4))
> [1] TRUE
> > .is_continous_evenly_spaced(c(1,3,4,5))
> [1] FALSE
> > .is_continous_evenly_spaced(c(1,1.1,1.2,1.3))
> [1] FALSE
>
> I expect the result for 1 and 2, but not for 3. Upon Investigation it
turns out, that n == test is TRUE for every pair, but not for the pair of 0.2.
>
> The types reported are always double, however n[2] == 0.1 reports FALSE
as well.
>
> The whole problem is solved by switching from all(n == test) to
all(as.character(n) == as.character(test)). However that is weird, isn’t it?
>
> Does this work as intended? Thanks for any help, advise and suggestions
in advance.
I guess this has something to do with how the sequence is built and
the inherent error of floating point arithmetic. In fact, if you
return test minus n, you'll get:
[1] 0.000000e+00 0.000000e+00 2.220446e-16 0.000000e+00
and the error gets bigger when you continue the sequence; e.g., this
is for c(1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7):
[1] 0.000000e+00 0.000000e+00 2.220446e-16 2.220446e-16 4.440892e-16
[6] 4.440892e-16 4.440892e-16 0.000000e+00
So, independently of this is considered a bug or not, instead of
length(n) == length(test) && all(n == test)
I would use the following condition:
isTRUE(all.equal(n, test))
Iñaki
>
> Best regards,
> Felix
>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> [email protected] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
--
Iñaki Ucar
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel