2

I have numbers which vary significantly. From really small to really big. I want to round them all and do not see a proper solution for me.

Usually people round to a certain number of decimals. Simply round(x, 2) or whatever.

My situation is different.

For instance, I have very different numbers. And numbers below 1 with multiple zeros are my biggest challenge, because I do not want them to be rounded to zero.

x <- c(100.56, 100.132554444123, 10044400000.2523324, 
       1.2343454555424, 0.04454443, 0.0000000000000000000000543)

lapply(x, signif)

It gives me

[[1]]
[1] 100.56

[[2]]
[1] 100.133

[[3]]
[1] 10044400000

[[4]]
[1] 1.23435

[[5]]
[1] 0.0445444

[[6]]
[1] 0.0000000000000000000000543

This is almost what I need. But I would like to limit numbers below 1 with some decimals. For instance, round it the the closest meaningful decimal (first non-zero number).

I also tried a couple of other options like

prettyNum(x)

formatC(x)

but they do not resolve my question.

P.S. Sorry for confusion. I want to round small numbers to the closest possible decimal (not sure if I explain in properly in English, sorry).

So it should be a custom function. I will round big number with certain decimals (from 0 to 3). Something like this

x <- c(100.56, 100.132554444123, 100444.2523324, 1.2343454555424, 0.04454443, 0.0000000000000000000000543)

rounded_value <- function(value) {

if (is.na(value)) return (NA)
if (value >= 100) value <- round(value,2)
if (value >= 1000) value <- round(value,0)
if (value >= 1000000) value <- round(value,3)

return (value)
}


lapply(x, rounded_value)

[[1]]
[1] 100.56

[[2]]
[1] 100.13

[[3]]
[1] 100444

[[4]]
[1] 1.234345

[[5]]
[1] 0.04454443

[[6]]
[1] 0.0000000000000000000000543

My problem is with two last values - 0.04454443, 0.0000000000000000000000543. I want to round values below 1 individually. For instance, into 0.04 and 0.00000000000000000000006. Trying to find a function which will help me to do this.

Updated. Thanks to everybody. I am trying to rewrite this function in a more intuitive way. Sorry if my initial question was not exactly you see here.

rounded_value <- function(value)
{
if (is.na(value)) return (NA)

decimals <- 1
value_out <- value
while ( (value_out<-round(value,(decimals+1))) == 0 & decimals < 10) { 
decimals <- decimals + 1 }

if (value_out > 100) value_out <- round(value_out,1)
if (value_out > 1000) value_out <- round(value_out,0)

value_out <- as.numeric(value_out) 

return (value_out)
}

Update 3. My best guess now is

x <- c(100.56, 100.132554444123, 100444.2523324, 1.2343454555424, 0.04454443, 
0.00543)

rounded_value <- function(value) {

# if (is.na(value)) return (NA)
if (value >= 100) value <- round(value,2)
if (value >= 1000) value <- round(value,0)
if (value >= 1000000) value <- round(value,3)
while (value <= 1) value <- signif(x, 10)

return (value)
}

rounded_value(x)

It gives me

[1]    100.56    100.13 100444.25      1.23      0.04      0.01
Anakin Skywalker
  • 2,400
  • 5
  • 35
  • 63

1 Answers1

3

Not exactly sure what you are asking. Maybe this will work - or get you closer?

R> x <- c(100.56, 100.132554444123, 10044400000.2523324, 
+        1.2343454555424, 0.04454443, 0.0000000000000000000000543)
R> ifelse(abs(x)>1, round(x), signif(x, digits=1))
[1] 1.01000e+02 1.00000e+02 1.00444e+10 1.00000e+00 4.00000e-02 5.00000e-23
keithpjolley
  • 2,089
  • 1
  • 17
  • 20
  • 2
    why are you loading `plyr` ... ? – Ben Bolker Aug 06 '18 at 02:05
  • 1
    @keithpjolley, added more specific example, hopefully. – Anakin Skywalker Aug 06 '18 at 03:09
  • @keithpjolley, you option give me a bunch of zeros after first four values. [1] 101.00000000000000000000000 100.00000000000000000000000 10044400000.00000000000000000000000 1.00000000000000000000000 [5] 0.04000000000000000083267 0.00000000000000000000005. I will round them specifically. Values below 1 is my challenge. – Anakin Skywalker Aug 06 '18 at 03:13
  • 2
    @Oleksiy At that point, you may need to convert to `character` class to get what you want... those extra digits are floating point precision problems. See the FAQ [Why are these numbers not equal?](https://stackoverflow.com/q/9508518/903061) for reading on that. – Gregor Thomas Aug 06 '18 at 03:22
  • 1
    `R> c(1/3, 1)` gives you `[1] 0.3333333 1.0000000`. Changing this behavior in `R` is beyond my skills. – keithpjolley Aug 06 '18 at 03:27
  • @keithpjolley, I updated the initial question with a specific example, which I tried to rewrite with the help of signif(). – Anakin Skywalker Aug 06 '18 at 03:34
  • 1
    I think @Gregor's suggestion to convert to character and do what you need to do as a string is the way to go. Floating points are only occasionally accurate out to the number of decimals you are wanting. `R> 0.0000000000000444 + 1 - 1` -> `[1] 4.440892e-14` – keithpjolley Aug 06 '18 at 03:40