ifelse函数而不是for循环

时间:2018-11-24 10:19:56

标签: r for-loop if-statement

我的原始R代码如下。

 Bernoulli <- rbinom(1000, 1, 0.5)
 mix.sample <- rep(0, 1000)  #reserve storage
 for (i in 1:1000) { #for each Bernoulli realization
   if (Bernoulli[i] == 1){ #sample corresponding normal component
     mix.sample[i] <- rnorm(1, mean=10, sd=1)
   }
   else {
     mix.sample[i] <- rnorm(1, mean=0, sd=1)
   }
 }
 plot(density(mix.sample))

我尝试了以下代码而不是for循环,但是产生的结果似乎有问题,有人可以帮助我吗?

 Bernorm <- ifelse(Bernoulli == 1, rnorm(1, mean=10, sd=1), rnorm(1, mean=0, sd=1))

4 个答案:

答案 0 :(得分:1)

您可以代替for循环

set.seed(42)
sim.fun <- function(x) {
  if (x == 1) {
    rnorm(1, 10, 1)
  } else {
    rnorm(1, 0, 1)
  }
}

P <- sapply(Bernoulli, sim.fun)
plot(density(P))

或者,如果您依靠ifelse()sapply()一起使用,则:

P <- sapply(Bernoulli, function(x) ifelse(x == 1, rnorm(1, 10, 1), rnorm(1, 0, 1)))

该功能更快。

microbenchmark()产生:

Unit: milliseconds
    expr      min       lq     mean   median       uq      max neval cld
for-loop 8.015976 8.232972 8.712522 8.316147 8.475865 14.65216   100   c
 sim.fun 3.622982 3.672990 4.493131 3.700290 3.752339 54.14139   100 a  
  sapply 5.932761 6.016319 6.479058 6.070026 6.115951 12.38065   100  b 

答案 1 :(得分:1)

我个人认为您可以立即将 <?php $FName = $MName = $LName = $Gender = $add = $occu = $Resi = $eid = $pass = ""; $FNameerr = $MNameerr = $LNameerr = $Gendererr = $adderr = $occuerr = $Resierr = $eiderr = $passerr = ""; if ($_SERVER["REQUEST_METHOD"] == "POST"){ if (empty($_POST["FName"])){ $FNameerr = "firstname is required"; } else{ $FName = test_input($_POST["FName"]); if (!preg_match("/^[a-zA-z]*$/",$FName)){ $FNameerr = "Only letter and whitespaces allowed"; } } if (empty($_POST["MName"])){ $MNameerr = "middlename is required"; } else{ $MName = test_input($_POST["MName"]); if (!preg_match("/^[a-zA-z]*$/",$MName)){ $MNameerr = "Only letter and whitespaces allowed"; } } if (empty($_POST["LName"])){ $LNameerr = "lastname is required"; } else{ $LName = test_input($_POST["LName"]); if (!preg_match("/^[a-zA-z]*$/",$LName)){ $LNameerr = "Only letter and whitespaces allowed"; } } if (empty($_POST["Gender"])){ $Gendererr = "choosing a gender is required"; } else{ $Gender = test_input($_POST["Gender"]); } if (empty($_POST["add"])){ $adderr = "choosing a gender is required"; } else{ $add = test_input($_POST["add"]); } if (empty($_POST["occu"])){ $occuerr = "middlename is required"; } else{ $occu = test_input($_POST["occu"]); if (!preg_match("/^[a-zA-z]*$/",$occu)){ $occuerr = "Only letter and whitespaces allowed"; } } if (empty($_POST["Resi"])){ $Resierr = "choosing a gender is required"; } else{ $Resi = test_input($_POST["Resi"]); } if (empty($_POST["eid"])){ $eiderr = "email id is required"; } else{ $eid = test_input($_POST["eid"]); if (!filter_var($eid, FILTER_VALIDATE_EMAIL)) { $eidErr = "Invalid email format"; } } } function test_input($data){ $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } ?> here is my entire block of code 转换为Binomial

logical

答案 2 :(得分:0)

就像一次创建整个测试向量(rbinom)一样,您可以一次创建两个rnorm向量的所有值。将所有内容放入矩阵,使用测试向量的值选择两个值列中的任意一个。

set.seed(1)
n <- 8
m <- cbind(test = rbinom(n, 1, 0.5),
           norm0 = rnorm(n, mean = 0, sd = 1),
           norm10 = rnorm(n, mean = 10, sd = 1))

m <- cbind(m, res = m[cbind(1:nrow(m), (m[ , "test"] == 1) + 2)])
#     test      norm0    norm10        res
# [1,]   0  0.3295078  9.378759  0.3295078
# [2,]   0 -0.8204684  7.785300 -0.8204684
# [3,]   1  0.4874291 11.124931 11.1249309
# [4,]   1  0.7383247  9.955066  9.9550664
# [5,]   0  0.5757814  9.983810  0.5757814
# [6,]   1 -0.3053884 10.943836 10.9438362
# [7,]   1  1.5117812 10.821221 10.8212212
# [8,]   1  0.3898432 10.593901 10.5939013
# [10,]  0  1.1249309 10.619826  1.1249309  

答案 3 :(得分:0)

另一个选择是将值放入数据帧中,然后像开始时一样使用ifelse添加变量。在这里,我也只是绘制数据,但是您可以将其分配回来以存储值。

library(tidyverse)

set.seed(81)
df <- data_frame(Bernoulli = rbinom(1000, 1, 0.5))

df %>% 
  mutate(mix.sample = if_else(Bernoulli == 1, 
                              rnorm(1, mean=10, sd=1), 
                              rnorm(1, mean=0, sd=1))) %>%
  ggplot(aes(mix.sample))+
  geom_density()+
  scale_x_continuous(limits = c(-5, 15))