Click here for other works of the author on RPubs
Define function r.norm
to generate random numbers from a normal distribution using samples from a standard normal distribution.
r.norm <- function(num, mu, v){
#check for invalid values
if(num%%1 != 0 | num < 0) stop('The number of samples to be selected must be a positive integer')
if(v <= 0) stop('Variance must be positive')
#generate samples from a standard normal distribution and convert them
#according to the mean and variance given
norm.sample = sqrt(v) * rnorm(num) + mu
return(norm.sample)
}
#plot the distribution of the normal sample with a fitted normal curve
norm.samp = r.norm(num = 10000, mu = 20, v = 10)
hist(norm.samp, breaks = 30,col = "gray", main = "Histogram of the normal sample", xlab = "Value", prob = TRUE)
curve(dnorm(x, mean = mean(norm.samp), sd = sd(norm.samp)), col = "darkblue", lwd = 2, add = TRUE, yaxt = "n")
Define function r.bin
to generate random numbers from a binomial distribution using samples from uniform distribution.
r.bin <- function(num, p, n){
#check for invalid values
if(num%%1 != 0 | num <= 0) stop('The number of samples to be selected must be a positive integer')
if(p < 0 | p > 1) stop('Parameter p must be between 0 and 1')
if(n%%1 != 0 | n <= 0) stop('Parameter n must be a positive integer')
#generate random numbers from a uniform distribution
unif.sample = matrix(runif(n * num), n, num)
#transform the samples into Bernoulli samples
Bern.sample = apply(unif.sample, c(1, 2), function(x) if(x >= p){x = 0} else{x = 1})
#sum Bernoulli samples into binomial samples
bin.sample = colSums(Bern.sample)
return(bin.sample)
}
#plot the distribution of the binomial sample with a fitted normal curve
bin.samp = r.bin(num = 10000, p = 0.5, n = 40)
hist(bin.samp, breaks = seq(min(bin.samp) - 0.5, max(bin.samp) + 0.5, by = 1),col = "gray", main = "Histogram of the binomial sample", xlab = "Value", prob = TRUE)
curve(dnorm(x, mean = mean(bin.samp), sd = sd(bin.samp)), col = "darkblue", lwd = 2, add = TRUE, yaxt = "n")
It is apperant that the binomial sample is also very similar to a normal distribution.
r.choose <- function(select, total){
#check for invalid values
if(select%%1 != 0 | select < 0) stop('The number of samples to be selected must be a positive integer')
if(total%%1 != 0 | total <= 0) stop('The total number of population must be a positive integer')
if(select > total) stop('The number of samples to be selected must not exceed the population size')
#seperate situations which the number of people to be selected is more than
#50% of the total to improve efficiency
if(select / total <= 0.5 | select == total){
#generate sample
choose = ceiling(runif(select, 0, total))
#replace duplicated numbers in the sample until all numbers are unique
while(length(choose[duplicated(choose)]) > 0){
choose[duplicated(choose)] = ceiling(runif(length(choose[duplicated(choose)]), 0, total))
}
}
else{
#generate sample for numbers not to be included
choose = ceiling(runif(total-select, 0, total))
#replace duplicated numbers in the sample until all numbers are unique
while(length(choose[duplicated(choose)])>0){
choose[duplicated(choose)] = ceiling(runif(length(choose[duplicated(choose)]), 0, total))
}
#remove numbers not to be included to get final sample
choose = c(1:total)[-choose]
}
#return results
return(sort(choose))
}
r.choose
to select 2 random samples without replacement#select 2 people from 18
r.choose(select = 2, total = 18)
## [1] 3 18