R:停止一环,当一个条件得到满足

0

的问题

我的工作R编程语言。 我创建了以下循环,产生1000随机号-再重复这个过程中10次:

results <- list()

for (i in 1:10){

a = rnorm(1000,10,1)
b = rnorm(1000,10,1)


d_i = data.frame(a,b)
d_i$index = 1:nrow(d_i)
d_i$iteration = as.factor(i)

 results[[i]] <- d_i

}



results_df <- do.call(rbind.data.frame, results)

问题: 我想改变这个循环的例,而不是仅仅产生1000随机数字,它保留产生随机数,直到某些条件得到满足,例如:保持产生随机数字,直到d_i$a>10和d_i$b>10.

使用"虽然()"的发言中,我试图做到这一点:

results <- list()

for (i in 1:10){

 while (d_i$a > 10 & d_i$b >10) {

a = rnorm(1000,10,1)
b = rnorm(1000,10,1)


d_i = data.frame(a,b)
d_i$index = 1:nrow(d_i)
d_i$iteration = as.factor(i)

 results[[i]] <- d_i

}

}


results_df <- do.call(rbind.data.frame, results)

问题: 然而,这一返回的以下警告(10次):

Warning messages:
1: In while (d_i$a > 10 & d_i$b > 10) { :
  the condition has length > 1 and only the first element will be used

并产生一个空白表:

> results_df

data frame with 0 columns and 0 rows

有人可以帮我解决这个问题?

谢谢!

data-manipulation loops r while-loop
2021-11-23 23:09:34
3

最好的答案

3

错误信息,在原来的职位是由于这样的事实, d_i$ad_i$b 都载有1 000个元素和10标量。 因此,R比较的第一个元素 d_i$a 与第一个元素 d_i$b 10.

要解决的错误消息,我们需要比较一矢量与长度为1至标10. 这要求重组的代码生成的随机数字之一的时间。 从说明,在原来的职位,目前还不清楚是否这种行为是故意的。

我将简化问题通过消除集的10次重复说明如何创建一个数据架随机数字,直至一个行具有两者 ab 值大于10。

第一,我们制定一种使回答可再现,以及随后初始化的一些对象。 通过设置 ab 为0,我们保证 while() 循环将执行至少一次。

set.seed(950141238) # for reproducibility 
results <- list()
a <- 0 # initialize a to a number < 10
b <- 0 # initialize b to a number < 10 
i <- 1 # set a counter 

具有初始化 abwhile() 循环计算 TRUE 产生两个随机数字,指定一个指标值,并将它们作为一个数据架的 results 名单。 的逻辑 while() 循环表明,如果既 a 小于或等于10或 b 小于或等于10,循环不断迭代. 它停止当时两人 ab 是大于10。

while(a <= 10 | b <= 10){
     a <- rnorm(1,10,1) # generate 1 random number with mean of 10 and sd of 1
     b <- rnorm(1,10,1) # ditto
     results[[i]] <- data.frame(index = i,a,b)
     i <- i + 1 # increment i
}

循环便停止执行后的第九次迭代,因为我们可以看到,通过印刷所产生的数据框架之后我们结合的单独行 do.call()rbind().

df <- do.call(rbind,results)
df

...和输出:

> df
  index         a         b
1     1  8.682442  8.846653
2     2  9.204682  8.501692
3     3  8.886819 10.488972
4     4 11.264142  8.952981
5     5  9.900112 10.918042
6     6  9.185120 10.625667
7     7  9.620793 10.316724
8     8 11.718397  9.256835
9     9 10.034793 11.634023
>

请注意,最后一行中的数据框架具有的价值大于10 ab.

多次重复的同时循环

重复的过程中10次是在原来的岗位,我们把操作中的一个 for() 循环,并添加第二个列表, combined_results 保存的结果,从每一次迭代。

set.seed(950141238) # for reproducibility 
combined_results <- list()
for(iteration in 1:10){
     results <- list()
     a <- 0 # initialize a to a number < 10
     b <- 0 # initialize b to a number < 10 
     i <- 1 # set a counter 
     while((a < 10) | (b < 10)){
          a <- rnorm(1,10,1) # generate 1 random number with mean of 10 and sd of 1
          b <- rnorm(1,10,1) # ditto
          results[[i]] <- data.frame(iteration,index = i,a,b)
          i <- i + 1 # increment i
     }
     combined_results[[iteration]] <- do.call(rbind,results)
}
df <- do.call(rbind,combined_results)
df[df$iteration < 5,] 

...和输出的第4次外循环:

> df[df$iteration < 5,]
   iteration index         a         b
1          1     1  8.682442  8.846653
2          1     2  9.204682  8.501692
3          1     3  8.886819 10.488972
4          1     4 11.264142  8.952981
5          1     5  9.900112 10.918042
6          1     6  9.185120 10.625667
7          1     7  9.620793 10.316724
8          1     8 11.718397  9.256835
9          1     9 10.034793 11.634023
10         2     1 11.634331  9.746453
11         2     2  9.195410  7.665265
12         2     3 11.323344  8.279968
13         2     4  9.617224 11.792142
14         2     5  9.360307 11.166162
15         2     6  7.963320 11.325801
16         2     7  8.022093  8.568503
17         2     8 10.440788  9.026129
18         2     9 10.841408 10.033346
19         3     1 11.618665 10.179793
20         4     1 10.975061  9.503309
21         4     2 10.209288 12.409656
> 

我们再次注意到,最后一行,在每次迭代(9、第18、19和21)具有的价值大于10 ab.

请注意,这种方法未能充分利用的矢量的行动,意义,而不是产生1 000个随机数字与每一个呼叫 rnorm(),代码的基础上 while() 产生一个单一的随机数量每次呼叫 rnorm(). 由于 rnorm() 是一个资源密集型的功能,代码,最大限度地减少的次数 rnorm() 执行是理想的。

2021-11-24 20:45:06
2

我希望这些评论有助于按照它如何工作。 它的主要使用 repeat 这只是一个无限的循环。 它可停止使用 break 关键词。

results <- list()


for (i in 1:10){
  
  # do until break
  repeat {
    
    # repeat many random numbers
    a = rnorm(1000,10,1)
    b = rnorm(1000,10,1)
    
    # does any pair meet the requirement
    if (any(a > 10 & b > 10)) {
      
      # put it in a data.frame
      d_i = data.frame(a,b)
      
      # end repeat
      break
    }
  }
  
  # select all rows until the first time the requirement is met
  # it must be met, otherwise the loop would not have ended
  d_i <- d_i[1:which(d_i$a > 10 & d_i$b > 10)[1], ]
  
  # prep other variables
  d_i$index = seq_len(nrow(d_i))
  d_i$iteration = as.factor(i)
  
  results[[i]] <- d_i
  
}
2021-11-24 01:19:52
2

打破的循环(同时或),简单地在一个 break() 后一个 if 条件。

out <- vector("integer", 26)
for (i in seq_along(letters)) {
  if(letters[i] == "t") break()
  out[i] <- i+1
}
out
#> [1]  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20  0  0  0  0  0  0  0

将打破的循环。 从 ?break控制转移到第一声明以外的内的最循环。

然而,从你的问题它是不完全清楚为什么你正在尝试这个-这样的控制流动可能不是最适当的解决办法,作为一个量化的解决办法可能存在。 另外,谨防这样做不必要的东西里面一环,它是一个常见原因为慢跑码。 在这里,我们可以采取一些东西出来的对环,例如 d_i$iterationd_i$index和最终仍然有相同的结果。 看看 第三圆圈.

2021-11-23 23:46:14

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................