为什么while(is.null(..))经常与num_to_selection组合



为什么在下面的代码块中需要while循环?摘自R/examics包中提供的dist3练习。

sc <- NULL
while (is.null(sc)) {
p <- c(sample(1:3, 1), sample(1:5, 1))
q <- c(sample(4:5, 1), sample((1:5)[-p[2]], 1))
sol <- sqrt(sum((p - q)^2))
err <- c(sqrt(sum((p + q)^2)), sqrt(sum(abs(p - q))))
err <- err[abs(err - sol) > 0.1]
if (length(err) > 1) err <- sample(err, 1)
sc <- num_to_schoice(sol, wrong = err,
range = c(0.1, 10), delta = 0.3, digits = 3)
}

通常,函数num_to_schoice()(在本例中负责更新while循环条件所依据的变量sc(不能保证返回包含$questions文本和相应逻辑$solutions的列表。相反,当它无法设置具有指定属性(范围、最小距离等(的问题/解决方案时,它可能会返回NULL并发出警告。请参阅下面的一些说明。

因此,为了保证依赖于num_to_schoice()的练习总是产生有效的解决方案,首先用NULL初始化单选列表sc,然后重新采样参数并调用num_to_schoice(),直到sc不再是NULL(而是一个包含问题/解决方案的列表((备注:我在自己的练习中经常使用这个设置,通常不检查是否真的会发生任何问题。在这个特定的设置中,NULL值的问题似乎永远不会发生。(

为了说明,考虑以下简单的例子,其中正确的解是10,我们希望正确解和任何错误解之间的delta至少为1,并且我们对错误解使用不同的范围。

  • 首先,让我们使用范围[1,20],它总是找到一些错误的解。

    set.seed(2021)
    num_to_schoice(10, range = c(1, 20), delta = 1, digits = 0)
    ## $solutions
    ## [1] FALSE FALSE FALSE  TRUE FALSE
    ## 
    ## $questions
    ## [1] "$16$" "$17$" "$7$"  "$10$" "$13$"
    
  • 相反,对于最小距离为1的四个伪解,区间[9,11]永远不够大。

    num_to_schoice(10, range = c(9, 11), delta = 1, digits = 0)
    ## NULL
    ## Warning message:
    ## In num_to_schoice(10, range = c(9, 11), delta = 1, digits = 0) :
    ##   specified 'range' is too small for 'delta'
    
  • 最后,间隔[7,13]可能足够大,也可能不够大。这取决于在num_to_schoice()中执行的初始步骤,其中函数首先决定四个错误解中有多少应该在正确解的左侧与右侧。这是内置在函数中的,以避免系统地生成正确解决方案是最小或最大的问题列表。

    num_to_schoice(10, range = c(7, 13), delta = 1, digits = 0)
    ## $solutions
    ## [1] FALSE FALSE  TRUE FALSE FALSE
    ## 
    ## $questions
    ## [1] "$7$"  "$13$" "$10$" "$11$" "$9$" 
    num_to_schoice(10, range = c(7, 13), delta = 1, digits = 0)
    ## NULL
    ## Warning message:
    ## In num_to_schoice(10, range = c(7, 13), delta = 1, digits = 0) :
    ##   specified 'range' is too small for 'delta'
    

如果预先指定的wrong解决方案与正确的解决方案过于接近和/或使间隔过小等,则可能会发生更多不可能的设置。有关更多插图,请参阅?num_to_schoice中的示例。

最新更新