R: force format(scientific=FALSE) not to round - r

I have been playing around with this command for a while and cannot seem to make it work the way I would like it to. I would like format to give me the full list of numbers as a text without any rounding even when the whole number portion is large. For example:
format(2290000000000000000.000081 , scientific=FALSE)
[1] "2290000000000000000"
While what I want returned is:
"2290000000000000000.000081"

As noted, you can't store that number exactly using double precision. You'll need to use multiple-precision floating point numbers.
library(Rmpfr)
mpfr("2290000000000000000.000081", precBits=85)
## 1 'mpfr' number of precision 85 bits
## [1] 2290000000000000000.000081

Related

Why does R paste more decimals than have been rounded, but only sometimes?

I know floating point numbers are strange, but I haven't come across this exact issue before. I have a vector of numbers in R. I see how many are bigger than zero, and I take the mean of this to get the proportion above zero. I assign the number to an object after rounding it. When I go to paste it, somehow the numbers come back. I would dput the vector, but it is too long to do so, but here's the head and str:
> head(x)
[1] 0.1616631 0.2117250 0.1782197 0.1791657 0.2067048 0.2042075
> str(x)
num [1:4000] 0.162 0.212 0.178 0.179 0.207 ...
Now here's where I run into issues:
> y <- round(mean(x > 0) * 100, 1)
> y
[1] 99.7
> str(y)
num 99.7
> paste(100 - y, "is the inverse")
[1] "0.299999999999997 is the inverse"
But it doesn't behave the same if I don't subtract from 100:
> paste(y, "is it pasted")
[1] "99.7 is it pasted"
I know I could put round right into the paste command or use sprintf, and I know how floats are represented in R, but I'm specifically wondering why it occurs for the former situation and not the latter? I cannot get a reproducible example, either, because I cannot get a randomly-generated vector to behave in the same way.
There's rounding error, but in this case R is not handling it nicely.
Any representation of floating-point numbers in R is done as double, which means 53 bits of precision, approximately 16 digits. That's also for the 99.7, you can see where it breaks down:
print(99.7, digits=16) # works fine
print(99.7, digits=17) # Adds a 3 at the end on my platform
That will be always a limit, which you are warned for when specifying it in print (in the docs).
But when you do calculations, any rounding error remains absolute, meaning your expected value of .3 has an absolute error that is just as big, but that is relatively 300 times larger. Therefore it "fails" with less significant digits:
print(100-99.7, digits=14) # works fine
print(100-99.7, digits=15) # Allready rounding error at digits=15
Now paste passes any number to the function as.character, which (in this case unfortunately) does not look at any options you've set, it always uses a default value of 15 significant digits.
To solve it, you can use format to specify the desired number of digits:
paste(format(100 - y, digits=14), "is the inverse")

r scientific notation limit mantissa decimal points

In r, is it possible to limit the number after decimal points of mantissa/significand. E.g 1.43566334245e-9, I want to ignore/round to 1.44e-9.
I do not want to simply say keep N numbers after decimal. Cause if there is another number in the dataset is 5.2340972e-5, I want it to be 5.23e-5 but not 5.234097e-5. So only limiting on mantissa's decimal point, rather than the whole number.
If I understood you correctly:
signif(1.43566334245e-9,3)
[1] 1.44e-09
signif(5.2340972e-5,3)
[1] 5.23e-05

Donot want large numbers to be rounded off in R

options(scipen=999)
625075741017804800
625075741017804806
When I type the above in the R console, I get the same output for the two numbers listed above. The output being: 625075741017804800
How do I avoid that?
Numbers greater than 2^53 are not going to be unambiguously stored in the R numeric classed vectors. There was a recent change to allow integer storage in the numeric abscissa, however your number is larger that that increased capacity for precision:
625075741017804806 > 2^53
[1] TRUE
Prior to that change integers could only be stored up to Machine$integer.max == 2147483647. Numbers larger than that value get silently coerced to 'numeric' class. You will either need to work with them using character values or install a package that is capable of achieving arbitrary precision. Rmpfr and gmp are two that come to mind.
You can use package Rmpfr for arbitrary precision
dig <- mpfr("625075741017804806")
print(dig, 18)
# 1 'mpfr' number of precision 60 bits
# [1] 6.25075741017804806e17

Round numbers in output to show small near-zero quantities as zero

I would like the output of my R console to look readable. To this end, I would like R to round all my numbers to the nearest N decimal places. I have some success but it doesn't work completely:
> options(scipen=100, digits=4)
> .000000001
[1] 0.000000001
> .1
[1] 0.1
> 1.23123123123
[1] 1.231
I would like the 0.000000001 to be displayed as simply 0. How does one do this? Let me be more specific: I would like a global fix for the entire R session. I realize I can start modifying things by rounding them but it's less helpful than simply setting things for the entire session.
Look at ?options, specifically the digits and scipen options.
try
sprintf("%.4f", 0.00000001)
[1] "0.0000"
Combine what Greg Snow and Ricardo Saporta already gave you to get the right answer: options('scipen'=+20) and options('digits'=2) , combined with round(x,4) .
round(x,4) will round small near-zero quantities.
Either you round off the results of your regression once and store it:
x <- round(x, 4)
... or else yes, you have to do that every time you display the small quantity, if you don't want to store its rounded value. In your case, since you said small near-zero quantities effectively represent zero, why don't you just round it?
If for some reason you need to keep both the precise and the rounded versions, then do.
x.rounded <- round(x, 4)

How do you cast a double to an integer in R?

My question is: Suppose you have computed an algorithm that gives the number of iterations and you would like to print the number of iterations out. But the output always many decimal places, like the following:
64.00000000
Is it possible to get an integer by doing type casting in R ? How would you do it ??
There are some gotchas in coercing to integer mode. Presumably you have a variety of numbers in some structure. If you are working with a matrix, then the print routine will display all the numbers at the same precision. However, you can change that level. If you have calculated this result with an arithmetic process it may be actually less than 64 bit display as that value.
> 64.00000000-.00000099999
[1] 64
> 64.00000000-.0000099999
[1] 63.99999
So assuming you want all the values in whatever structure this is part of, to be displayed as integers, the safest would be:
round(64.000000, 0)
... since this could happen, otherwise.
> as.integer(64.00000000-.00000000009)
[1] 63
The other gotcha is that the range of value for integers is considerably less than the range of floating point numbers.
The function is.integer can be used to test for integer mode.
is.integer(3)
[1] FALSE
is.integer(3L)
[1] TRUE
Neither round nor trunc will return a vector in integer mode:
is.integer(trunc(3.4))
[1] FALSE
Instead of trying to convert the output into an integer, find out why it is not an integer in the first place, and fix it there.
Did you initialize it as an integer, e.g. num.iterations <- 0L or num.iterations <- integer(1) or did you make the mistake of setting it to 0 (a numeric)?
When you incremented it, did you add 1 (a numeric) or 1L (an integer)?
If you are not sure, go through your code and check your variable's type using the class function.
Fixing the problem at the root could save you a lot of trouble down the line. It could also make your code more efficient as numerous operations are faster on integers than numerics (an example).
The function as.integer() truncate the number up to 0 order, so you must add a 0.5 to get a proper approx
dd<-64.00000000
as.integer(dd+0.5)
If you have a numeric matrix you wish to coerce to an integer matrix (e.g., you are creating a set of dummy variables from a factor), as.integer(matrix_object) will coerce the matrix to a vector, which is not what you want. Instead, you can use storage.mode(matrix_object) <- "integer" to maintain the matrix form.

Resources