So basically I am doing a physics experiment, and in my table I want to have my data rounded to the same accuracy as the error is, which is rounded to 1 sig fig.
So for example if I have the following:
angle <- c(4, 4.1, 4.2)
angle.error <- c(0.024, 0.3, 0.113)
data <- data.frame(angle,angle.error)
want I want to end up with is the angle error rounded to 1 sig fig, and the angle rounded to the corresponding number of decimal places as the angle error, to give
angle <- c(4.00, 4.1, 4.2)
angle.error <- c(0.02,0.3,0.1)
data <- data.frame(angle, angle.error)
Hope this makes sense!! This is the standard way we are taught to present data, and as such I am surprised how difficult I am finding it to find a proper way of doing this. Any contributions would be great!!
EDIT:
If I want to turn this into a UDR where say the data is in column 5 and the errors in column 6 of my data frame, I write:
Conv2 <- function(x) {
x[6] <- signif(x[6],1)
exp <- floor(log10(x[6]))
man <- x[6]/10^exp
x[5] <- round(x[5], -exp) # Error associated with this line I think
sapply(seq_along(x[5]), function(i) format(x[i,5], nsmall=-exp[i]))
return(x)
}
When I implement it I get the error 'Error in FUN(X[[i]], ...) : non-numeric argument to mathematical function'
This can be done with signif()
. In contrast to round()
, which rounds to a number of decimal places, signif()
rounds to a specific number of significant places.
x <- c(1,1.0001,0.00001)
round(x,1) # rounds to the specified number of decimal places
signif(x,1) # rounds to the specified number of significant digits
Let's apply this to your case. Note that signif is vectorized over both arguments.
> signif(c(1.111,2.222,3.333),c(1,2,3))
[1] 1.00 2.20 3.33
This would mean the following for your case:
angle.error <- c(0.024, 0.3, 0.113)
cor <- signif(angle.error,1)
Rounding the angles is slightly more difficult. We need to round angle to the same number of decimal places as angle.error_corr. Therefore we will extract the mantissa and exponent of this number.
exp <- floor(log10(cor))
man <- cor/10^exp
Now it is possible to use the exponents to round your angles.
angle <- c(4, 4.1, 4.2)
angle_cor <- round(angle, -exp)
However, this does not give the intended result since R shows the number of digits of the most precise double and drops trailing zeros. We can solve this with the nsmall argument of format, which is unfortunately not vectorized.
sapply(seq_along(angle), function(i) format(angle[i], nsmall = -exp[i]))
Which should give you the answer you were looking for.