looking for a way to get from an floating point number the power of 10 to which it is noted
6.45e-8 - would be 8
3.21e-4 would be 4
0.013 would be 2
or minus in all
is ther e a function which would do the following
instead of multiplying with 6.45e_8 it would be at first dividing by 1e-8 and then multiply with (6.45e-8/1e8=...).
How about
floor(log10(x))
? log10 computes the log base 10, floor finds the next smaller integer.
tenexp <- function(x){c <- trunc(log10(abs(x))); return(abs(c-1*(c<0)))}
Here's the (desired?) result:
> tenexp(0.0134)
[1] 2
> tenexp(6.45e-8)
[1] 8
> tenexp(6.45e+3)
[1] 3
> tenexp(-1.28e+4)
[1] 4
Related
I have numeric's like this one:
a <- -1.542045
And I want to round them down (or round up the abs) to 2 digits after the decimal point.
signif(a,3) will round it down and give me 1.54 as a result but for this example the result I want is -1.55.
Any idea?
I think you are looking for floor(a * 100) / 100.
Quick Test
a <- c(-1.542045, 1.542045)
floor(a * 100) / 100
# [1] -1.55 1.54
I just noticed that you changed your question 7 hours ago. Then my answer is not doing exactly what you want (as I am assuming by "rounding down" you always want to round toward -Inf). But I have discussed this in first version of my answer. Now I am going to copy those relevant back here.
With sign(a) * ceiling(abs(a) * 100) / 100 you can round data toward Inf for positive values and -Inf for negative values.
With sign(a) * floor(abs(a) * 100) / 100, you round both positive and negative values toward 0.
A quick test
a <- c(-1.542045, 1.542045)
sign(a) * ceiling(abs(a) * 100) / 100
# [1] -1.55 1.55
sign(a) * floor(abs(a) * 100) / 100
# [1] -1.54 1.54
You misunderstand the issue. If the value is in -1.542045, it will always be.
Now you can print it to two decimals or get a two decimal char:
> print(a, digits=3)
[1] -1.54
> format(a, digits=3)
[1] "-1.54"
>
Should you really desire to create a new representation you can:
> b <- trunc(a*1e2)*1e-2
> b
[1] -1.54
>
A preferable way may be
> b <- round(a, digits=2)
> b
[1] -1.54
>
A combination of ceiling(), abs() and sign() can be used to round up the abs of the number, irrespective of its sign. Such a rounding at two decimal digits can be obtained with:
ceiling(abs(a)*100)/100*sign(a)
Example:
a <- c(-1.542045, 1.542045)
ceiling(abs(a)*100)/100*sign(a)
#[1] -1.55 1.55
Running gamma(200) returns Inf in R. Would it be possible to have R return the actual number somehow? It looks like anything above gamma(171.6) returns an Inf in R.
The issue is that you cannot represent it with double precision:
gamma(200) # too large value
#R> [1] Inf
lgamma(200) # but log is not
#R> [1] 857.9337
exp(857) # the issue!
#R> [1] Inf
.Machine$double.xmax # maximum double value
#R> [1] 1.797693e+308
gamma(171) # almost there!
#R> [1] 7.257416e+306
You can work with the log of the gamma function instead using lgamma. Otherwise you will need to use a third party library which has higher precision than R's floating points.
A google search suggests that the Rmpfr::igamma function might be what you want if you cannot work with the log of the gamma function:
Rmpfr::igamma(171, 0)
#R> 1 'mpfr' number of precision 53 bits
#R> [1] 7.257415615307999e+306
Rmpfr::igamma(200, 0)
#R> 1 'mpfr' number of precision 53 bits
#R> [1] 3.9432893368239526e+372
Using lgamma as proposed by Benjamin Cristoffersen, you can calculate the significand and the exponent (base 10) as individual variables:
(res <- gamma(100))
9.332622e+155
# Natural logarithm of result
(ln_res <- lgamma(100))
359.1342
# log base 10 of result
(log10_res <- ln_res/log(10))
155.97
# decimal part of the number above, raised to the 10th power
(significand_res <- 10 ^ (log10_res %% 1))
9.332622
# non-decimal part
(exp_res <- log10_res %/% 1)
155
For gamma(200) this returns: 3.9432 * 10 ^ 372
I have a vector:
r <- runif(10)
r
[1] 0.52324423 0.89110751 0.44616915 0.70163640 0.63741495 0.31263977
[7] 0.73947973 0.83278799 0.04971461 0.01820381
I also have a probability distribution
p <- c(0, cumsum(rep(0.25, 4)))
p
[1] 0.00 0.25 0.50 0.75 1.00
I would like to assign factors to r based on the probability distribution in p.
In other words, I would like my output to be:
r
[1] 3 4 2 3 3 2 3 4 1 1
When I try this, I get a warning:
which( r >= p) -1
[1] 3
Warning message:
In r < p : longer object length is not a multiple of shorter object length
In other words, only the first value in r is compared to p.
How would I go about converting r into a vector of levels that I can then turn into factors?
You can use cut
as.integer(cut(r, breaks=p))
How can I round off a number like 0.0000234889 (or in the form 8.829847e-07) to a power of ten, either below or above (whichever is my choice), ie here 0.00001 or 0.0001 ?
I tried round(...., digits=-100000) but it returns an error NaN error.
Ex: round(2e-07, digits=6) gives 0, while I would like 1e-06 and another function to give 1e-07.
# Is this what you're looking for?
# find the nearest power of ten for some number
x <- 0.0000234889 # Set test input value
y <- log10(x) # What is the fractional base ten logarithm?
yy <- round(y) # What is the nearest whole number base ten log?
xx <- 10 ^ yy # What integer power of ten is nearest the input?
print(xx)
# [1] 1e-05
The digits argument to the round() function must be positive. If you want your number to show up in scientific notation with an exponent n, just just do
round(value, 10^n)
However, this will only get you what you want up to a point. For example, you can do round(0.0000234889, 10^6) but you still get 2.34889e-05. (Notice that an exponent of 6 was specified but you got 5.)
Use options("scipen" = ) like this:
num <- 0.0000234889
> num
[1] 2.34889e-05
options("scipen" = 10)
options()$scipen
> num
[1] 0.0000234889
This will change the global option for the session. Read documentation here:https://stat.ethz.ch/R-manual/R-devel/library/base/html/options.html
Can anyone tell me how to code the SS between in R
to compute by hand, it is ∑ ni(meanXi - the grand mean)2
thanks,
lp
If you have a vector of values x and the mean in x_mean, you can compute the SS error manually simply like this:
> x=c(1,2,3,4,5)
> x_mean = mean(x)
> x-x_mean
[1] -2 -1 0 1 2
> (x-x_mean)^2
[1] 4 1 0 1 4
> sum((x-x_mean)^2)
[1] 10
Not sure this is what you want, but
# create sample dataset: 5 groups, 10 values per group
set.seed(1)
df <- data.frame(group=rep(LETTERS[1:5],each=10),value=rnorm(50))
# calculate between-group sum of squares (SSB)
sum((aggregate(value~group,df,mean)$value-mean(df$value))^2)
# [1] 0.07938908
This calculates the mean by group using aggregate(...) and then sums the squared difference between that and the grand mean (mean(df$value)).