How to make R more precise? - r

When I plug these equations into R I get:
> 1/(1+exp(-18))
[1] 1
> 1/(1+exp(-16))
[1] 0.9999999
But when I plug the same equations into Chrome I get:
1/(1+exp(-18))
0.99999998477
1/(1+exp(-16))
0.99999988746
So it seems like R is not very precise and rounds numbers up. Is it possible for me to get more digit precision with R? If so, how can I do that?

Thanks to user G5W, I realized I needed to do:
options(digits=11)
And rerun my exp() equations. B/c by default R does not display so many digits.

Related

Is there a way to handle calculations invovling exponential of big values in R?

I have looked a bit online and in the site but I did not find any solution. My problem is relatively simple so if you could point me to a possible solution, much appreciated.
test_vec <- c(2,8,709,600)
mean(exp(test_vec))
test_vec_bis <- c(2,8,710,600)
mean(exp(test_vec_bis))
exp(709)
exp(710)
# The numerical limit of R is at exp(709)
How can I calculate the mean of my vector and deal with the Inf values knowing that R could probably handle the mean value but not all values in the numerator of the mean calculation ?
There is an edge case where you can solve your problem by simply restating your problem mathematically, but that would require that the length of your vector is extremely large and/or that your large exp. numbers are close to the numeric limit:
Since the mean sum(x)/n can be written as sum(x/n) and since exp(x)/exp(y) = exp(x-y), you can calculate sum(exp(x-log(n))), which gives you a relief of log(n).
mean(exp(test_vec))
[1] 2.054602e+307
sum(exp(test_vec - log(length(test_vec))))
[1] 2.054602e+307
sum(exp(test_vec_bis - log(length(test_vec_bis))))
[1] 5.584987e+307
While this works for your example, most likely this won't work for your real vector.
In this case, you will have to consult packages like Rmpfr as suggested by #fra.
Here's one way where you qualify to only select those in your test_vec that give an answer < Inf:
mean(exp(test_vec)[which(exp(test_vec) < Inf)])
[1] 1.257673e+260
t2 <- c(2,8,600)
mean(exp(t2))
[1] 1.257673e+260
This assumes you were looking to exclude values that result in Inf, of course.

Correcting mis-typed data in R

I want to correct wrongly entered data in R. For example if I have a vector
V=c('PO','PO','P0')
I want R to recognize that the 0 in the last entry should be a o and to change it. Is there anyway to do that? I have trying to use correctTypos in the deducorrect package in R. However I am having some problem with the editset. I cannot seems to specify that all the entries have to be letters. Any help greatly appreciated.
Another example would be
V2=c('PL','P1','PL','XX')
That 1 should be an L.
The jaro-winkler distance was developed to find issues with data entry. But on entries only 2 long that is going to be difficult as 1 error tends to score higher than you want it to. You could combine this with other distance measurements available in the stringdist package. But in this case that might be too complicated.
Given your examples you might want to use the base function chartr and set up a replacement of numbers to letters.
chartr("01","OL", V2)
[1] "PL" "PL" "PL" "XX"
chartr("01","OL", V)
[1] "PO" "PO" "PO"
This will always replace the 1 by an L and a 0 (zero) by an O. You can add the 5 for S etc etc. But if there are other combo's it might get complicated.
Also note that the next iteration of the deducorrect package is the deductive package.

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

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

exponents and negative numbers

I do not know if other R users have found the following problem.
Within R I do the folowing operation:
> (3/-2)^(1/3)
[1] NaN
I obtain a NaN result.
I the similar way if I set:
> w<-(3/-2)
> g<-1/3
> w^g
[1] NaN
However, if I do:
> 3/-2
[1] -1.5
> -1.5^(1/3)
[1] -1.144714
Is there anybody that can explain this contradiction?
Where do you see a problem? -1.5^(1/3) is not the same as (-1.5)^(1/3). If you have basic maths education you shouldn't expect these to be the same.
Read help("Syntax") to learn that ^ has higher precedence than - in R.
This is due to the mathematical definition of exponentiation. For the continuous real exponentiation operator, you are not allowed to have a negative base.
Begin by doing (3/2)^(1/3) and after add "-"
you can't calculate a cube root of a negative number !
If you really want the answer you can do the computation over the complex numbers, i.e. get the cube root of -1.5+0i:
complex(real=-1.5,im=0)^(1/3)
## [1] 0.5723571+0.9913516i
This is actually only one of three complex roots of x^3+1.5==0:
polyroot(c(1.5,0,0,1))
[1] 0.5723571+0.9913516i -1.1447142+0.0000000i 0.5723571-0.9913516i
but the other answers probably come closer to addressing your real question.

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)

Resources