Outlander
Outlander

Reputation: 583

Calculate significant digits of a number in R

Maybe a daft question but why does R remove the significant 0 in the end of a number? For example 1.250 becomes 1.25 which has not the same accuracy. I have been trying to calculate the number of significant digits of a number by using as.character() in combination with gsub() and regular expressions (according to various posts) but i get the wrong result for numbers such as 1.250, since as.character removes the last 0 digit. Therefore the answer for 1.250 comes out as 2 digits rather than 3 which is the correct.

To be more specific why this is an issue for me:

I have long tables in word comprising of bond lengths which are in the format eg: 1.2450(20):

enter image description here

The number in parenthesis is the uncertainty in the measurement which means that the real value is somewhere between 1.2450+0.0020 and 1.2450-0.0020. I have imported all these data from word in a large data frame like so:

df<-data.frame(Activity = c(69790, 201420, 17090),
               WN1=c(1.7598, 1.759, 1.760),
               WN1sd=c(17, 15, 3))

My aim is to plot the WN1 values against activity but also have the error bar on. This means that i will need to manually convert the WN1sd to: WN1sd=c(0.0017, 0.015, 0.003) which is not the R way to go, hence the need to obtain the number of significant digits of WN1. This works fine for the first two WN1 values but not for the 3rd value since R mistakenly thinks that the last 0 is not significant.

Upvotes: 2

Views: 326

Answers (2)

pietrodito
pietrodito

Reputation: 2090

You have to prepare the standard deviations at the time you import your data from your word document

There's a point where you should have strings like that :

"1.2345(89)" "4.230(34)" "3.100(7)"

This is a function you can apply to those chars and get the sd right:

split.mean.sd = function(mean.sd) {
   mean <- gsub("(.*)\\(.*", "\\1", mean.sd)
   sd  <- gsub(".*\\((.*)\\)", "\\1", mean.sd)
   digits.after.dot <- nchar(gsub(".*\\.(.*).*", "\\1", mean))
   sd  <- as.numeric(sd)*10^(-digits.after.dot)
   mean <- as.numeric(mean)
   c(mean, sd)
   }

For example:

v <- c("1.2345(89)","4.230(34)","3.100(7)")
sapply(v, split.mean.sd)

gives you

     1.2345(89) 4.230(34) 3.100(7)
[1,]     1.2345     4.230    3.100 
[2,]     0.0089     0.034    0.007

Upvotes: 1

liori
liori

Reputation: 42267

Most programming languages, R included, do not track the number of significant digits for floating-point values. This is because in many cases significant digits are not necessary, would significantly slow down computations and require more RAM.

You may want to be interested in some libraries for computations with uncertainties, like the errors (PDF) package.

Upvotes: 0

Related Questions