首页 > 解决方案 > R:根据最后一次调用的输出递归地指定函数的输入

问题描述

我希望从有界范围 [a, b] 中选择一系列随机样本,其中b递归地替换为先前采样中绘制的值。

所以,假设我在第一轮从 [0.01, 0.1] 中抽取 0.07,那么我想在下一轮从 [0.01, 0.07] 中抽取。如果现在我绘制 0.033,那么我希望下一次绘制在 [0.01, 0.33] 范围内。为简单起见,假设我希望随机抽取在每次迭代中均匀分布。

参数应该是要进行的抽奖次数,例如 10、100、1000 等。最有效的方法是什么?理想情况下使用一些函数式编程细节。


编辑:

这是一个紧跟斐波那契递归示例的函数:

get_rand_1 = function(n, lower = 0.001, upper = 0.1) {
  if(n == 1) return(runif(1, lower, upper))
  return(runif(1, 0.01, get_rand_1(n-1, lower, upper)))
}

set.seed(1234567)
sapply(1:10, get_rand_1)

这确实做了我需要它做的事情,但它确实会NaN不时产生 s ,如以下输出所示:

> sapply(1:10, get_rand_1)
 [1] 0.05666382 0.06759059        NaN 0.01245241 0.01019525 0.01117497 0.01096470 0.01001802
 [9] 0.01005574 0.01001110
Warning messages:
1: In runif(1, 0.01, get_rand_1(n - 1, lower, upper)) : NAs produced
2: In runif(1, 0.01, get_rand_1(n - 1, lower, upper)) : NAs produced

我不确定这是否是种子的产物,或者这是否是程序的固有缺陷或两者兼而有之。

具体来说,如果我硬编码上限和下限并且不将它们作为参数传递,则不会发生这种情况。

get_rand = function(n) {
  if(n == 1) return(runif(1, 0.001, 0.1))
  return(runif(1, 0.001, get_rand(n-1)))
}
set.seed(1234567)
sapply(1:10, get_rand)

这会产生:

> set.seed(1234567)
> sapply(1:10, get_rand)
 [1] 0.056663823 0.066827837 0.002083137 0.004200264 0.001238414 0.003118070 0.001038515 0.001121686
 [9] 0.001084810 0.001020310

这是在 Windows 10 机器上。我可以根据需要提供会话信息。

无论哪种情况,我仍然希望以最有效的方式实现这一点。欢迎提出建议。

标签: rrecursionfunctional-programming

解决方案


这是一个基本的方法。几乎可以肯定不是最有效的,但它会起作用。请注意,它倾向于收敛到下限,因为选择的随机数永远不会大于前一个数字。runif(...) 函数从均匀分布中采样。

 your_sampler <- function(x, a, b){
  temp_list <- c()
  temp_list[1] <- runif(1, min = a, max = b)
  for(i in 2:x){
  temp_list[i] <- runif(1, min = a, max = temp_list[i-1])
  }
  temp_list
}

# Example
your_sampler(10, 0.3, 10)

推荐阅读