On 29/10/2021 4:34 a.m., PIKAL Petr wrote:> Hi > > One has to be careful when using fractions in seq step. > > Although it works for 0.5 >> (seq(0,10, .5) - round(seq(0,10,.5),2))==0 > [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE > TRUE > [16] TRUE TRUE TRUE TRUE TRUE TRUE > > in case of 0.3 (or others) it does not always result in expected values (see > FAQ 7.31 for explanation) > >> (seq(0,10, .3) - round(seq(0,10,.3),2))==0 > [1] TRUE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE > [13] FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE > [25] FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUEPetr is right, it's unsafe to use fractional values for the step. 0.5 works because it has a power of 2 in the denominator and so does the start value, but it's easy to make mistakes when you rely on that (e.g. changing the step size from 0.5 to 0.3 would break things). A better idea is to modify a sequence of integers. For example, to get 1.5 to 3.5 by 0.5, you can do (3:7)*0.5, and for 0 to 3 by 0.3, use (0:10)*0.3. Duncan Murdoch
>>>>> Duncan Murdoch >>>>> on Fri, 29 Oct 2021 09:07:31 -0400 writes:> On 29/10/2021 4:34 a.m., PIKAL Petr wrote: >> Hi >> >> One has to be careful when using fractions in seq step. >> >> Although it works for 0.5 >>> (seq(0,10, .5) - round(seq(0,10,.5),2))==0 >> [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE >> TRUE >> [16] TRUE TRUE TRUE TRUE TRUE TRUE >> >> in case of 0.3 (or others) it does not always result in expected values (see >> FAQ 7.31 for explanation) >> >>> (seq(0,10, .3) - round(seq(0,10,.3),2))==0 >> [1] TRUE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE >> [13] FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE >> [25] FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE > Petr is right, it's unsafe to use fractional values for the step. 0.5 > works because it has a power of 2 in the denominator and so does the > start value, but it's easy to make mistakes when you rely on that (e.g. > changing the step size from 0.5 to 0.3 would break things). > A better idea is to modify a sequence of integers. For example, to get > 1.5 to 3.5 by 0.5, you can do (3:7)*0.5, and for 0 to 3 by 0.3, use > (0:10)*0.3. Well, but you will not get truly equidistant (to the last bit) sequences also by that and people who are not aware of FAQ 7.31 and its consequences do wrongly assume that length(unique(diff(seqVec))) == 1 for any seqVec <- k * seq(....) # k a "scalar" (of length 1) but the reality of floating point arithmetic can be quite different than pure math : In this case and on my platform the two ways to construct the sequence are even identical:> identical((0:10)*0.3, seq(0, 3, by=.3))[1] TRUE> sv <- (0:10)*0.3 > length(unique(diff(sv))) # you'd like |--> 1 (the number 0.3 !)[1] 5>Martin
Hello, ?s 14:07 de 29/10/21, Duncan Murdoch escreveu:> On 29/10/2021 4:34 a.m., PIKAL Petr wrote: >> Hi >> >> One has to be careful when using fractions in seq step. >> >> Although it works for 0.5 >>> (seq(0,10, .5) - round(seq(0,10,.5),2))==0 >> ? [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE >> TRUE >> TRUE >> [16] TRUE TRUE TRUE TRUE TRUE TRUE >> >> in case of 0.3 (or others) it does not always result in expected >> values (see >> FAQ 7.31 for explanation) >> >>> (seq(0,10, .3) - round(seq(0,10,.3),2))==0 >> ? [1]? TRUE? TRUE? TRUE FALSE? TRUE? TRUE FALSE? TRUE? TRUE FALSE >> TRUE? TRUE >> [13] FALSE? TRUE? TRUE? TRUE? TRUE? TRUE FALSE? TRUE? TRUE? TRUE? TRUE >> FALSE >> [25] FALSE? TRUE? TRUE? TRUE? TRUE? TRUE? TRUE FALSE? TRUE? TRUE > > > Petr is right, it's unsafe to use fractional values for the step.? 0.5 > works because it has a power of 2 in the denominator and so does the > start value, but it's easy to make mistakes when you rely on that (e.g. > changing the step size from 0.5 to 0.3 would break things). > > A better idea is to modify a sequence of integers.? For example, to get > 1.5 to 3.5 by 0.5, you can do (3:7)*0.5, and for 0 to 3 by 0.3, use > (0:10)*0.3.But even this is not safe. Perhaps the most frequent sequence causing problems (R-Help questions) is the one from 0 to 1 by 0.1 and why it always returns FALSE when tested against certain values such as 0.6. And it also fails to create it with (0:10)*0.1. x <- seq(0, 1, by = 0.1) any(x == 0.6) #[1] FALSE y <- (0:10)*0.1 any(y == 0.6) #[1] FALSE all(x == y) #[1] TRUE Off-topic: FAQ 7.31 addresses this. Hope this helps, Rui Barradas> > Duncan Murdoch > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.