Reputation: 59
I have tried different functions to round decimals to two digits, such as format()
, formatC()
,signif()
and round()
. None of them can truly round all decimals to two decimal places.
For example, my data frame DF has three columns: Index, PDF and CDF:
Index PDF CDF
1 -1.00 8.306360e-07 8.306360e-09
2 -0.99 8.332774e-07 1.663913e-08
3 -0.98 8.411712e-07 2.505085e-08
4 -0.97 8.542267e-07 3.359311e-08
5 -0.96 8.722951e-07 4.231606e-08
6 -0.95 8.951719e-07 5.126778e-08
7 -0.94 9.226012e-07 6.049380e-08
8 -0.93 9.542808e-07 7.003660e-08
9 -0.92 9.898679e-07 7.993528e-08
10 -0.91 1.028986e-06 9.022514e-08
...
...
...
The column Index
is a vector, from -1.00 to 10.00.The difference between any consecutive elements is 0.01. It implies that unique(diff(Index))
should return only one value and it must be 0.01. However, unique(diff(Index))
can return several 0.01.
My purpose is to compute the difference between any two elements of the columnCDF
, and these two elements are selected by indicating their Index
. For example,
a<-DF$CDF[DF$Index==(r+dr)];
b<-DF$CDF[DF$Index==(r-dr)];
res<-a-b;
r
is any number of Index
, dr
can be 0.01, 0.02 or 0.03. However, since some elements of Index
cannot be rounded to 2 digits (although they all look like that), therefore I cannot compute res
for any r and dr.
How should I tackle this problem? Thanks for your advice in advance!
Upvotes: 0
Views: 1416
Reputation: 4417
At some point in the function unique
, the function will have to test, if two Index-Diffs are the same and it will likely do this with ==
. However, comparing floating point values with ==
is rarely a good idea. Use your favourite searching page with "floating point equal" or "floating point comparison" or read at http://floating-point-gui.de/errors/comparison/ about this problem, which you should always be aware of, not only for this specific problem.
My advice in this case: Multiply you index values by 100, convert them to integers and ==
(and thereby unique
) will work perfectly alright with integers.
Thanks to the comments by @hrbrmstr below I found, that you need to not only as.integer
but to also round
the numbers, as illustrated in the following code
#wrong result due to floating point arithmetic
unique(diff(seq(-1,1,0.1)))
# multiple steps towards a working solution
seq(-1, 1, 0.1)
10*seq(-1, 1, 0.1)
as.integer(round(10*seq(-1, 1, 0.1)))
diff(as.integer(round(10*seq(-1, 1, 0.1))))
unique(diff(as.integer(round(10*seq(-1, 1, 0.1))))) # works!
Upvotes: 5