Search code examples
rroundingsignificant-digits

Rounding a number based on the amount of decimals in another column in R


My goal is to calculate the standard deviation and the mean of a column in a data frame. After this calculation, I want to round the standard deviation to the first significant decimal and round the mean values to the same amount of decimals as the respective standard deviation.

This is what I have so far:

library("tidyverse")

# create some example data
data <- data.frame(name = c("A", "B", "C"), 
                   value = c(0.1, 0.11, 0.111,
                             5.0, 0.0003, 0.00002,
                             0.5, 0.13, 0.113))

# calculate the standard deviation (sd), as well as the mean, 
# and round sd to the first significant decimal
data <- data %>%
  mutate(sd = signif(sd(value), 1), mean = mean(value), .by = name) %>%
  select(- value) %>%
  distinct()

# remove trailing zeros from the sd values
data$sd <- data$sd %>% 
  str_remove("0+$") 

With this code, I calculate sd and mean, round the sd to the first significant decimal and delete trailing zeros for the sd. I have not found a way to round the mean to the same amount of decimals.

I would greatly appreciate your help with this!


Solution

  • Using the answer from this post to find number of decimals:

    decimalplaces <- function(x) {
      x <- as.double(x)
      if (abs(x - round(x)) > .Machine$double.eps^0.5) {
        nchar(strsplit(sub('0+$', '', as.character(x)), ".", fixed = TRUE)[[1]][[2]])
      } else {
        return(0)
      }
    }
    
    data %>%
      rowwise()%>%
      mutate(sd_ndecimal=decimalplaces(sd),
             mean=round(mean,sd_ndecimal)) %>%
      ungroup %>%
      select(-sd_ndecimal)
    
      name  sd     mean
      <chr> <chr> <dbl>
    1 A     3      2   
    2 B     0.07   0.08
    3 C     0.06   0.07