Generate Random Integers Between Two Values with a Given Probability Using R

generate random integers between two values with a given probability using R

You can directly use sample, more specifcally the probs argument. Just divide the probability over all the 586 numbers. Category A get's 0.5/207 weight each, etc.

A <- 1:207
B <- 208:386
C <- 387:486
D <- 487:586
L <- sapply(list(A, B, C, D), length)

x <- sample(c(A, B, C, D),
size = 20000,
prob = rep(c(1/2, 1/6, 1/6, 1/6) / L, L),
replace = TRUE)

Generate random number with given probability

You could just do a weighted random sample, without worrying about your cumsum method:

sample(c(1, 2, 3), size = 100, replace = TRUE, prob = c(0.5, 0.1, 0.4))

If you already have the numbers, you could also do:

x <- runif(10, 0, 1)
as.numeric(cut(x, breaks = c(0, 0.5, 0.6, 1)))

Generate random number with different probabilities for each line in R

The problem is that you are passing 4 vectors to the probs parameter of sample (the entire columns p00, p10, p01, and p11), but sample is not vectorised in this way, and only takes a single vector of probabilities.

You need to write a version of sample that is vectorized on probs. Something like this:

vec_sample <- function(A, B, C, D)
{
do.call("c", lapply(seq_along(A), function(i)
{
sample(1:4, 1, replace = TRUE, prob=c(A[i], B[i], C[i], D[i]))
}))
}

So your code would work like this:

data02 <- data01 %>% mutate(u = vec_sample(p00, p10, p01, p11))

Generating random numbers (0 and 1) given specific probability values in R

You can use rbinom() to generate random samples from a binomial distribution.

Try this:

prob <- c(0.9, 0.3, 0.6, 0.8, 0.23, 0.45, 0.1, 0.3, 0.5, 0.03)
rbinom(length(prob), size = 1, prob=prob)

[1] 1 1 1 0 0 0 0 1 0 0

To demonstrate that the probabilities are in fact what you are after, try using replicate() to repeatedly draw samples using your probabilities:

x <- t(replicate(100, rbinom(length(prob), size = 1, prob=prob)))
head(x)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 0 1 1 1 1 0 0 1 0
[2,] 1 1 1 1 0 1 0 1 0 0
[3,] 1 0 1 1 0 0 0 1 0 0
[4,] 1 0 1 0 0 1 0 0 1 0
[5,] 1 1 1 1 0 0 0 0 0 0
[6,] 1 0 0 0 0 0 0 0 0 0

Now you can use colMeans() to compare the actual achieved probability against your specification:

colMeans(x)
[1] 0.93 0.28 0.61 0.67 0.25 0.43 0.11 0.29 0.40 0.01

how to generate a random number based on probability in r

If you want to start with a simple function that samples from a range of numbers mynumbers with a given probability myprob, you could use the base R sample function:

 mynumbers = c(1,2) #you numbers to sample from
myprob = c(.25, .75) #your probabilities
d = sample(mynumbers,
size = 1000, #1000 times sampled from `mynumbers`
replace = T,
prob = myprob)

table(d) #This should show you the approximate probability of `myprob`

Does this help?

Generate N random integers that sum to M in R

Normalize.

rand_vect <- function(N, M, sd = 1, pos.only = TRUE) {
vec <- rnorm(N, M/N, sd)
if (abs(sum(vec)) < 0.01) vec <- vec + 1
vec <- round(vec / sum(vec) * M)
deviation <- M - sum(vec)
for (. in seq_len(abs(deviation))) {
vec[i] <- vec[i <- sample(N, 1)] + sign(deviation)
}
if (pos.only) while (any(vec < 0)) {
negs <- vec < 0
pos <- vec > 0
vec[negs][i] <- vec[negs][i <- sample(sum(negs), 1)] + 1
vec[pos][i] <- vec[pos ][i <- sample(sum(pos ), 1)] - 1
}
vec
}

For a continuous version, simply use:

rand_vect_cont <- function(N, M, sd = 1) {
vec <- rnorm(N, M/N, sd)
vec / sum(vec) * M
}

Examples

rand_vect(3, 50)
# [1] 17 16 17

rand_vect(10, 10, pos.only = FALSE)
# [1] 0 2 3 2 0 0 -1 2 1 1

rand_vect(10, 5, pos.only = TRUE)
# [1] 0 0 0 0 2 0 0 1 2 0

rand_vect_cont(3, 10)
# [1] 2.832636 3.722558 3.444806

rand_vect(10, -1, pos.only = FALSE)
# [1] -1 -1 1 -2 2 1 1 0 -1 -1

Generate integer random numbers from range (0:10^12)

The real problem lies in the fact that you cannot store the sequence of 0:10^12 into memory. By just defining 0 and 10^12 as boundaries of a uniform distribution, you could get what you seek:

runif(10000, 0, 10^12)
[1] 136086417828 280099797063 747063538991 250189170474 589044594904
[6] 65385828028 361086657969 186271687970 338900779840 649082854623 ........

This will draw from the uniform distribution (with replacement, though I doubt that matters).

However, what you cannot see is that these are actually floating numbers.

You can use ceiling to round them up:

samp = runif(1, 0, 10^12)
samp
[1] 19199806033
samp == 19199806033
[1] FALSE
ceiling(samp) == 19199806033
[1] TRUE

So the full code would be:

ceiling(runif(10000, 0, 10^12))

Further nitpicking:

Note that this technically will not allow 0 to be there (since 0.0001 would be rounded up), so you could just draw from

ceiling(runif(10000, -1, 10^12))

As Carl Witthoft mentions, numbers that do not fit into the size of an integer will not be integers obviously, so you cannot count on these numbers to be integers. You can still count on them to evaluate to TRUE when compared to the same floating number without decimals though.



Related Topics



Leave a reply



Submit