在R

时间:2018-07-10 07:07:42

标签: r random

我想生成一个介于0和1之间但不在.4和.6之间的随机数。在R中有没有比以下更好的方法了?

sample(c(runif(1,0,.4), runif(1,.6,1)), 1, prob=c(.5,.5))

4 个答案:

答案 0 :(得分:3)

类似于TC Zhang,但快了大约3倍(因为ifelse慢):

mysample_axe <- function(n = 1){
    tmp <- runif(n, max = 0.8)
    tmp + (tmp > 0.4) * 0.2
}

与TC Zhang(mysample)和Cath(samp_runif)的比较:

microbenchmark::microbenchmark(mysample(1e5), mysample_axe(1e5), samp_runif(1e5))
Unit: milliseconds
                expr       min        lq      mean    median        uq       max neval cld
     mysample(1e+05) 12.684764 13.193528 17.313560 13.420470 19.692859 130.23693   100   c
 mysample_axe(1e+05)  4.897770  5.159778  5.751177  5.187718  5.218367  14.60607   100 a  
   samp_runif(1e+05)  7.615363  8.101890  9.266797  8.139951  8.194121  25.44451   100  b
ggplot2::qplot(mysample_axe(1e5), breaks = I(seq(0, 1, 0.02)))

enter image description here

答案 1 :(得分:2)

从任何分布中抽样随机数的基本思想是inverse transform sampling

mysample <- function(n = 1){
  tmp <- runif(n)
  ifelse (tmp > 0.5, 0.8 * tmp + 0.2, 0.8 * tmp)
}

library(ggplot2)
## A density plot for confirmation
df <- data.frame(x= mysample(1000000))

gg <- ggplot(df, aes(x=x)) +
  geom_density()

gg

reprex package(v0.2.0.9000)于2018-07-10创建。

答案 2 :(得分:2)

您可以对[0,1]上的均匀分布进行采样,直到使用递归函数得到一个遵循约束的数字(比@Axeman解慢约两倍):

samp_runif <- function(n){
    x <- runif(n, 0, 1)
    wh_pb <- which(x>0.4 & x<0.6)
    if(length(wh_pb)){x[wh_pb] <- samp_runif(length(wh_pb)) ; return(x)} else return(x)
}

samp_runif(5)
# [1] 0.3633319 0.9586853 0.6766313 0.6903275 0.8090996

可视化:

test <- samp_runif(1e6)
plot(density(test))

enter image description here


概括:

您可以调整上述功能以将阈值(在示例中为0.4和0.6)作为参数,上下限相同(在示例中分别为0和1):

samp_runif <- function(n, a=0.4, b=0.6){
    x <- runif(n, 0, 1)
    wh_pb <- which(x>a & x<b)
    if(length(wh_pb)){x[wh_pb] <- samp_runif(length(wh_pb), a=a, b=b) ; return(x)} else return(x)
}
samp_runif(5, 0.2, 0.8)
#[1] 0.80316178 0.99624724 0.89554995 0.05928052 0.17771131

答案 3 :(得分:0)

是的,这个想法是完全荒谬的,所以我删除了它。感谢Axeman的有用反馈。

这是另一个想法(这次经过了更好的测试):

fx <- function() {y <- runif(1); if (y > 0.4 & y < 0.6) fx() else y}

除了校正0.4和0.6之间的值外,只需获取另一个即可。