Wrong number of digits in format.pval()? - r

When specifying 3 digits in format.pval(), why does, say, 0.019950 outputs 4 digits:
format.pval(0.019950, eps=.001, digits=3, nsmall=3)
"0.0199"
But, say, 0.019951 outputs 3 digits:
format.pval(0.019951, eps=.001, digits=3, nsmall=3)
"0.020"
Edit (Solution):
The solution to having 3 digits while preserving the p-value formatting, based on dcarlson's answer, was simply to round the value to 3 digits before passing it to format.pval():
format.pval(round(0.019950, digits=3), eps=.001, digits=3, nsmall=3)
"0.020"

To address your first question "why does, say, 0.019950 outputs 4 digits": With the argument digits = 3 you specify that you'd like to show the first 3 significant digits after the decimal point (which are 199). From ?format.pval
digits: how many significant digits are to be used.
In response to your second question: 0.019951 with digits = 3 first gets rounded to "0.02" (you can confirm that by looking at the output of format.pval(0.019951, eps=.001, digits=3)). Then by setting nsmall = 3 you ask for 3 digits after the decimal point, which turns "0.02" into "0.020".

The digits= argument here and elsewhere in R is SIGNIFICANT digits, not decimal digits. Significant digits ignore leading 0's in a decimal so the first response is 3 significant digits since you do not count the 0 following the decimal point. In the second example the answer is rounded up to .02, but nsmall=3 forces the additional trailing 0.
In addition, specifying a digits= argument in R is usually treated as advisory so it may not be followed. You can always force R to print the number of decimals using round or the formatting function sprintf.
format.pval(round(0.019950, 3), digits=3, nsmall=3)
# [1] "0.020"
sprintf("%.3f", .019950)
# [1] "0.020"

Related

Can as.numeric(as.character(x)), where x is originally a numeric, ever change x?

I am wondering if converting numerics to characters and then back again in R can ever change the number? For example, does as.character round off numerics after a certain amount of decimal places (if so, how many)?
#jogo thanks for the suggestion :)
Here is the comment as an answer:
From ?as.character():
as.character represents real and complex numbers to 15 significant
digits (technically the compiler's setting of the ISO C constant
DBL_DIG, which will be 15 on machines supporting IEC60559 arithmetic
according to the C99 standard). This ensures that all the digits in
the result will be reliable (and not the result of representation
error), but does mean that conversion to character and back to numeric
may change the number. If you want to convert numbers to character
with the maximum possible precision, use format.
So yes it does change the number if you have more than 15 significant digits. See:
> as.character(1.000000000000001) # more than 15 significant digits
[1] "1"
> as.character(1.00000000000001) # less than 15 significant digits
[1] "1.00000000000001"
Here are some other examples:
y <- as.numeric(as.character(pi))
identical(y, pi) ### gives FALSE
or
x <- 1/7
y <- as.numeric(as.character(x))
x-y
or
as.numeric(as.character(.Machine$double.xmax)) ## result: Inf

Exceed the 7 digit decimal limit for numeric values in R?

Just noticed that R limits numeric values to 7 digits below the decimal. I'm needing to calculate and output numeric values of down to 16 digits. Is it possible to exceed the supposed 7 digit decimal limit in R?
As you can see in the example below, it won't output
any digits below 7.
> 0.6431159420289856
[1] 0.6431159
Desired output of course is
> 0.6431159420289856
[1] 0.6431159420289856
My particular use case requires those values to be outputted.
You can change the decimal places displayed with options(digits = 16) to get your requested output. That said, R will do math on all the digits available, regardless of the options setting for decimal places.
options(digits = 16)
0.6431159420289856
[1] 0.6431159420289856

r keeping only specific digits after the decimal point and printing the number

In R, How can I ensure that i only print 3 characters/numbers after the decimal point?
I thought that format command with nsmall parameter is sufficient but i am not getting required answer
> format(0.6791787, nsmall=3)
[1] "0.6791787"
I want 0.679
Using sprintf it would be
sprintf("%.3f", 0.6791787)
# [1] "0.679"
The number after the . and before the f is the number of digits to print after the decimal.

rounding of digits

I'm having troubles with
set.seed(1)
sum(abs(rnorm(100)))
set.seed(1)
cumsum(abs(rnorm(100)))
Why does the value of the sum differ from the last value of the cumulative sum with the cumulative sum preserving the all decimal digits and sum rounding 1 digit off.
Also note that this really really is about how values are printed i.e. presented. This does not change the values themselves, e.g. ...
set.seed(1)
d1 <- sum(abs(rnorm(100)))
set.seed(1)
d2 <- cumsum(abs(rnorm(100)))
(d1 == d2)[100]
## [1] TRUE
This is a consequence of the way R prints atomic vectors.
With the default digits option set to 7 as you likely have, any value between -1 and 1 will print with seven decimal places. Because of the way R prints atomic vectors, all other values in the vector will also have seven decimal places. Furthermore, a value of .6264538 with digits option set to 7 must print with eight digits (0.6264538) because it must have a leading zero. There are two of these values in your rnorm() vector.
If you look at cumsum(abs(rnorm(100)))[100] alone and you can see the difference (actually it becomes the same as printed value as sum(abs(rnorm(100))), although not exactly the same value).
sum(abs(rnorm(100)))
# [1] 71.67207
cumsum(abs(rnorm(100)))[100]
# [1] 71.67207
Notice that both of these values have seven digits. Probably the most basic example of this I can think of is as follows
0.123456789
#[1] 0.1234568
1.123456789
#[1] 1.123457
11.123456789
# [1] 11.12346
## and so on ...

using scientific notation in R

I'm currently using printCoefmat to print a matrix out and want to apply some formatting to the numbers.
I want to force scientific notation when the numbers have an exponent greater than 3.
I can't quite figure out how scipen works, Does anyone have any idea how I can do this?
Just type in a big number to get R to display unscientific notation.
options( scipen = 20 )
If that's not enough, make the number bigger...
How does the scipen penalty work?
It is confusing, but the penalty is applied to the scientific notation version, as in R looks at how many characters it takes to print a particular string. It adds the value scipen penalty to the number of characters in scientific notation and if it is still less than the number of characters required to print the actual number then it will print scientific and vice versa. I hope this example will illustrate the point:
options( scipen = 0 )
options( digits = 6 )
>1e5
#[1] 1e+05 ----> 5 characters in scientific, vs. 6 for '100000' in normal
>1e4
#[1] 10000 ----> 5 characters in normal, vs. 5 for '1e+04' in scientific
options(scipen = 1 )
>1e5
#[1] 100000 ----> 6 characters in normal, vs. 5 + 1 for '1e+05' + scipen penalty in scientific

Resources