I'm trying to create a list of numbers from 0.001 to 1000 with multiplication of 10. So the list would be (0.001, 0.1, 10.....1000)
Is there any function for it?
a <- 0.0001
b <- 0.0001
for (i in 1:5) {
b = b*100
print(c)
a <- c(a, b)
}
Can we replace the loop here with something more simple?
It should be simple as:
0.001 * 10^(seq(0,6,2))
# > 0.001 * 10^(seq(0,6,2))
# [1] 0.001 0.100 10.000 1000.000
Alternatively, you can use the GeometricSequence function from the bsts package in such way:
GeometricSequence(5, initial.value = 0.0001, discount.factor = 100)
First argument - length (in an example it is 5) is a positive integer giving the length of the desired sequence. initial.value - the first term in the sequence.
discount.factor - the ratio between a sequence term and the preceding term.
Related
While working on an Rcpp program, I used the sample() function, which gave me the following error: "NAs not allowed in probability." I traced this issue to the fact that the probability vector I used had NA values in it. I have no idea how. Below is some R code that captures the errors:
n.0=20
n.1=20
n.reps=1
beta0.vals=rep(seq(-.3,.1,,n.0),n.reps)
beta1.vals=rep(seq(-7,0,,n.1),n.reps)
beta.grd=as.matrix(expand.grid(beta0.vals,beta1.vals))
n.rnd=200
beta.rnd.grd=cbind(runif(n.rnd,min(beta0.vals),max(beta0.vals)),runif(n.rnd,min(beta1.vals),max(beta1.vals)))
beta.grd=rbind(beta.grd,beta.rnd.grd)
N = 22670
count = 0
for(i in 1:dim(beta.grd)[1]){ # iterate through 600 possible beta values in beta grid
beta.ind = 0 # indicator for current pair of beta values
for(j in 1:N){ # iterate through all possible Nsums
logit = beta.grd[i,1]/N*(j - .1*N)^2 + beta.grd[i,2];
phi01 = exp(logit)/(1 + exp(logit))
if(is.na(phi01)){
count = count + 1
}
}
}
cat("Total number of invalid probabilities: ", count)
Here, $\beta_0 \in (-0.3, 0.1), \beta_1 \in (-7, 0), N = 22670, N_\text{sum} \in (1, N)$. Note that $N$ and $N_\text{sum}$ are integers, whereas the beta values may not be.
Since mathematically, $\phi_{01} \in (0,1)$, I'm assuming that NAs are arising because R is not liking extremely small values. I am receiving an overwhelming amount of NA values, too. More so than numbers. Why would I be getting NAs in this code?
Include print(logit) next to count = count + 1 and you will find lots of logit > 1000 values. exp(1000) == Inf so you divide Inf by Inf which will get you a NaN and NaN is NA:
> exp(500)
[1] 1.403592e+217
> Inf/Inf
[1] NaN
> is.na(NaN)
[1] TRUE
So your problems are not too small but to large numbers coming first out of the evaluation of exp(x) with x larger then roughly 700:
> exp(709)
[1] 8.218407e+307
> exp(710)
[1] Inf
Bernhard's answer correctly identifies the problem:
If logit is large, exp(logit) = Inf.
Here is a solution:
for(i in 1:dim(beta.grd)[1]){ # iterate through 600 possible beta values in beta grid
beta.ind = 0 # indicator for current pair of beta values
for(j in 1:N){ # iterate through all possible Nsums
logit = beta.grd[i,1]/N*(j - .1*N)^2 + beta.grd[i,2];
## This one isn't great because exp(logit) can be very large
# phi01 = exp(logit)/(1 + exp(logit))
## So, we say instead
## phi01 = 1 / ( 1 + exp(-logit) )
phi01 = plogis(logit)
if(is.na(phi01)){
count = count + 1
}
}
}
cat("Total number of invalid probabilities: ", count)
# Total number of invalid probabilities: 0
We can use the more stable 1 / (1 + exp(-logit)
(to convince yourself of this, multiply your expression with exp(-logit) / exp(-logit)),
and luckily either way, R has a builtin function plogis() that can calculate these probabilities quickly and accurately.
You can see from the help file (?plogis) that this function evaluates the expression I gave, but you can also double check to assure yourself
x = rnorm(1000)
y = 1 / (1 + exp(-x))
z = plogis(x)
all.equal(y, z)
[1] TRUE
I'd like to get the same answer by binom.test or prop.test in R for the following question. How can I get the same answer of my manual calculation(0.009903076)?
n=475, H0:p=0.05, H1:p>0.05
What is the probability of phat>0.0733?
n <- 475
p0 <- 0.05
p <- 0.0733
(z <- (p - p0)/sqrt(p0*(1 - p0)/n))
# [1] 2.33
(ans <- 1 - pnorm(z))
# [1] 0.009903076
You can get this from prop.test():
prop.test(n*p, n, p0, alternative="greater", correct=FALSE)
# data: n * p out of n, null probability p0
# X-squared = 5.4289, df = 1, p-value = 0.009903
# alternative hypothesis: true p is greater than 0.05
# 95 percent confidence interval:
# 0.05595424 1.00000000
# sample estimates:
# p
# 0.0733
#
You can't get the result from binom.test() so far as I can tell because n*p is not an integer, it's 34.8175. The binom.test() function only takes an integer values number of successes, so when you convert this to 35 by rounding, p effectively becomes 0.07368421, which makes the rest of your results not match. Even if you had a situation where n*p was an integer, binom.test() would still not produce the same answer because it's not using a normal approximation as your original code does - it's using the binomial distribution to calculate the probability above p0.
I think this is a rather common problem, but I could not find a solution.
I want to solve the following equation:
pbinom(18,25,p)=0.05.
Is there a way to find the unknown p with the program R?
Every help is appreciated.
Root finding:
print(
res <- uniroot(function(p) pbinom(18,25,p) - 0.05, c(0, 1),
tol = .Machine$double.eps)
)
pbinom(18,25,res$root)
#[1] 0.05
Brute force :
p = 0.0001 # starting point
while (abs(pbinom(18,25,p) - 0.05) > 0.001) p <- p + 0.001
This code evaluates the pdf for different values of p until you are "close enough" to 0.05. Here "close enough" means at the 0.001 range.
> p
[1] 0.8601
> pbinom(18,25,0.8601)
[1] 0.05070763
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
Thank you for your help with this function, which should :
Enter a a specific value
Insert the value in a function
Take a set of other values generated in a vector
Calculate a value for each element of a vector
Return a data frame with both vector and calculated values.
Here is what I tried:
rate<-function(Y2) {
ran<-seq(0.001,1,0.001)
for(i in ran) {
calculated<-as.vector(Y2/(1+i)+Y2/(1+i)^2+Y2/(1+i)^3+Y2/(1+i)^4)
tableau<-data.frame(ran,calculated)
}
return(tableau)
}
When testing with res<-rate(500), only the last value is returned 1000 times:
...
ran calculated
1 0.001 468.75
2 0.002 468.75
3 0.003 468.75
...
996 0.996 468.75
997 0.997 468.75
998 0.998 468.75
999 0.999 468.75
1000 1.000 468.75
What is wrong with my loop?
You're assigning the output of your as.vector(...) calculation to the same variable each time you loop. Then you're building a data.frame, named tableau each time you loop. You're only returning the last iteration. If you want to save each iteration, you'll need to index into something:
res[n] <- as.vector(...)
Or the more R-ish version, use one of the apply family (specifically lapply) and no loop at all:
rate <- function(Y2) {
ran <- seq(0.001, 1, 0.001)
result <- lapply(ran,
function(i) data.frame(ran = i,
calculated = as.vector(Y2/(1+i)+Y2/(1+i)^2+Y2/(1+i)^3+Y2/(1+i)^4)))
return (do.call(rbind, result))
}
With that said, there is no reason for a loop or an apply function. Use the fact that R is vectorized:
ran <- seq(0.001, 1, 0.001)
Y2 <- 500
calculated <- as.vector(Y2/(1+ran)+Y2/(1+ran)^2+Y2/(1+ran)^3+Y2/(1+ran)^4)
result <- data.frame(ran, calculated)
all.equal(result, rate(500))
# [1] TRUE