在应用于向量的函数中使用ifelse和随机变量生成

Ric*_*ard 2 random r

我想创建一个函数,根据其输入生成一个随机数,并将其应用于布尔向量.该功能将用于生成大约500M元素的测试数据.

f <- function(x, p) ifelse(x, runif(1)^p, runif(1)^(1/p))
f(c(T,T,T,F,F,F), 2)   
Run Code Online (Sandbox Code Playgroud)

我得到的不是我想要的.

[1] 0.0054 0.0054 0.0054 0.8278 0.8278 0.8278
Run Code Online (Sandbox Code Playgroud)

我期望输入向量的每个元素都有一个新的随机数,而不是重复的两个随机数.为什么我得到这个结果,我怎样才能得到与之相同的结果

c(runif(3)^2, runif(3)^(1/2))
Run Code Online (Sandbox Code Playgroud)

这会为每个元素产生一个新的随机数

0.0774 0.7071 0.2184 0.8719 0.9990 0.8819
Run Code Online (Sandbox Code Playgroud)

Ben*_*ker 9

@BondedDust的答案是正确的(即,ifelse()没有真正循环)但效率稍低 - 它的随机均匀偏差的数量是必要的两倍(实际上除非你使用巨大的矢量或运行巨大的功能,否则无关紧要次数).这是一个稍微高效的版本,它通过power(^)运算符进行矢量化:

set.seed(1001)
f <- function(x, p=2) {
    rvec <- runif(length(x))
    rvec^(ifelse(x, p, 1/p))
}
## best to avoid the T/F shortcut ...
test <-  c(TRUE,TRUE,TRUE,FALSE,FALSE,FALSE)
f(test, 2) 
Run Code Online (Sandbox Code Playgroud)

@Frank在评论中指出runif(length(x))^(p^(2*x-1))甚至更好,虽然它对我的口味有点过于聪明.

fortunes::fortune("7ms")
Run Code Online (Sandbox Code Playgroud)

...... Brian Ripley:'太慢了'sic:在你节省的7ms里你打算做什么?

f_bb <- f
f_bd <- function(x, p=2)
    ifelse(x, runif( length(x) )^p, runif( length(x) )^(1/p))
f_frank <- function(x,p=2) runif(length(x))^(p^(2*x-1))
library("rbenchmark")
benchmark(f_bb(test),f_bd(test),f_frank(test),replications=10000,
         columns=c("test","replications","elapsed","relative"))
##            test replications elapsed relative
## 1    f_bb(test)        10000   0.161    2.516
## 2    f_bd(test)        10000   0.199    3.109
## 3 f_frank(test)        10000   0.064    1.000
Run Code Online (Sandbox Code Playgroud)


42-*_*42- 6

您需要制作两个与x-vector 长度相同的随机数矢量.

 f <- function(x, p) ifelse(x, runif(6)^p, runif(6)^(1/p))
 f(c(T,T,T,F,F,F), 2)   
 [1] 0.3040201 0.5543376 0.7291466 0.5205014 0.3563542 0.8697398
Run Code Online (Sandbox Code Playgroud)

或者更一般地说:

f <- function(x, p) ifelse(x, runif( length(x) )^p, runif( length(x) )^(1/p))
Run Code Online (Sandbox Code Playgroud)

ifelse功能全是不是真的做循环.第二个和第三个参数分别进行评估.