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

时间:2015-07-28 19:53:18

标签: r random

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

f <- function(x, p) ifelse(x, runif(1)^p, runif(1)^(1/p))
f(c(T,T,T,F,F,F), 2)   

我得到的不是我想要的。

[1] 0.0054 0.0054 0.0054 0.8278 0.8278 0.8278

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

相同的结果
c(runif(3)^2, runif(3)^(1/2))

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

0.0774 0.7071 0.2184 0.8719 0.9990 0.8819

2 个答案:

答案 0 :(得分:9)

@BondedDust的答案是正确的(即,ifelse()并没有真正循环)但效率稍低 - 它会根据需要采样两倍的随机均匀偏差(实际上它不会&#39除非你使用巨大的矢量或运行大量的功能,否则很重要。这是一个稍微高效的版本,它可以在功率(^)运算符上进行矢量化:

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) 

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

fortunes::fortune("7ms")
  

...... 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

答案 1 :(得分:6)

你需要制作两个与var myString = [ 'One line', 'Another line' ].join('\n'); - 矢量长度相同的随机数矢量。

x

或更一般地说:

 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

f <- function(x, p) ifelse(x, runif( length(x) )^p, runif( length(x) )^(1/p)) - 函数并没有真正循环。第二个和第三个参数分别进行评估。