【问题标题】:R function that uses its output as its own input repeatedly重复使用其输出作为自己的输入的 R 函数
【发布时间】:2018-05-31 03:44:50
【问题描述】:

给定 R 函数 auto(如下),我想知道是否有可能从第二次运行 for 循环输出 ps 被用作 pr

例如,如果循环要运行 3 次(即,length(n) = 3),那么在循环的第一次运行中,pr 将按原样使用,但从第二次运行开始,ps 的结果(即,ps(x)) 从之前的运行中取代pr 直到length(n) 的数量。

因此,在for 循环的第一次运行之后,每次,上一次运行中的ps(x) 都会在下一次运行中扮演pr 的角色。我的最终目标是curve最终以这种方式获得的ps

auto <- function(n, dat){

for(i in 1:length(n)){           
 pr = function(x) dbeta(x, 1, 1)
 lk = function(x) dbinom(dat[i], n[i], x) # So, here first `n = 100` and 
 ps = function(x) pr(x)*lk(x)             # `dat = 55` will go thru first 
  }                                       # round of the loop and produce
 curve(ps)                                # a `ps`. But in the second run of
}                                         # the loop, the `ps` just
# Example of use:                         # produced will be used as `pr`
auto(n = c(100, 50), dat = c(55, 60) )    # for `n = 50` and `dat = 60`
                                          # to produce a new `ps`.

【问题讨论】:

  • 你是在问如何写一个递归函数?
  • 我不明白这个问题,但这里有一个递归定义函数的例子:factorial &lt;- function(x) if (x==0) return(1) else return(x*factorial(x-1)); factorial(5)。这些在 R 中通常效率不高,并且堆栈深度有限制。
  • 你想从function返回function吗?如果是,那么您只能返回 1 个函数。您帖子中的ps。现在有什么问题?
  • 我认为他想在运行后更改 for 运算符中的功能
  • R 中的 @morouzian 函数不是有限状态自动化。而且您没有像 C# 中那样用于状态保存的 yield 关键字。可能,您可以在函数代码中使用函数名称并使用 do.call 运算符按名称调用。

标签: r function for-loop


【解决方案1】:

让我试着给出一个答案。

所以,首先,我认为您需要有限状态自动机函数。这种方法需要使用环境使用,您需要在其中存储函数调用的状态和值。 但是,您只需要根据您的周期指数值进行选择。 这要容易得多,因为您只需要 switch 运算符,仅此而已。

auto <- function(n, dat, n.loop){
x <- 0.1;
for(i in 1:n.loop){
val <- switch(i, dbeta(x, 1, 1), dbinom(dat, n, x), dbeta(x, 1, 1)*dbinom(dat, n, x))
print(val);
  }
}

auto(n = 100, dat = 55, n.loop = 3)

我有 2 个问题应该很好地重新组织代码。 1) 您在汽车中使用的x 值是什么?这不是您的代码中的参数,因此,您应该直接确定autox 的值。也许这是一个论点? 2) 你的函数需要返回什么值?

因此,添加了x &lt;- 0.1print(val) 以检查代码执行情况。

【讨论】:

  • @rnorouzian 我会尽快改进我的代码 - 需要更改位置。)因此,您将为您的任务提供正确的代码。))
  • @rnorouzian 现在你让我有点困惑了。从您的帖子中,我可以建议您不仅需要更改函数,还需要更改像这样的参数 `x => y = pr(x); y => z = lk(y); z => s = pr(z)*lk(z)?
  • @rnorouzian 不,我会等。可能,我会在早上重写我的答案。希望,我可以帮助你一点。很快再见。
【解决方案2】:

我想用不同的方式。虽然,我还没有完成它,但仍然想与他人分享改进的想法。我正在寻找非常基本和粗略的方法来解决它。

auto <- function(n, dat){
  pr = function(x) dbeta(x, 1, 1)
  lk = function(x) dbinom(dat[1], n[1], x)
  ps = function(x) pr(x)*lk(x) 
  #keep the funtion till now in psold 
  psold = ps
  #loop through 2nd to 2nd last element
  for(i in 2:length(n)-1){
    lk = function(x) dbinom(dat[i], n[i], x)
    #Use psold to evaluate new function ps
    ps = function(x) psold(x)*lk(x)
    psold = ps
  }
  lk = function(x) dbinom(dat[length(n)], n[length(n)], x)
  #Finaly function to be returned.
  ps = function(x) psold(x)*lk(x)  
}
# Example of use:
auto(n = c(100, 50), dat = c(55, 60) )

【讨论】:

  • 非常感谢,但如果您尝试使用curve(ps) 绘制最终的ps,则会收到以下错误:Error: evaluation nested too deeply: infinite recursion / options(expressions=)? Error during wrapup: evaluation nested too deeply: infinite recursion / options(expressions=)?
  • @morouzian 是的。我现在看到了。我试图弄清楚为什么它会导致嵌套太深。也许调试是下一个选择。
【解决方案3】:

不确定我是否完全理解这个问题。我在 for 循环中添加了一个 if 语句来检查它是否是第一次迭代。如果是,它将通过您的原始语句定义pr。如果不是,则通过 pr(x) * 上一次迭代的 lk(x) 函数定义它,该函数由i-1 子集。我确定我在这里遗漏了一些东西..

我也很困惑 x 输入的来源。

auto <- function(n, dat){

  for(i in 1:length(n)){
    if(i == 1){pr = function(x) dbeta(x, 1, 1)} else{pr = function(x) dbeta(x, 1, 1) * function(x) dbinom(dat[i-1], n[i-1], x)}
    lk = function(x) dbinom(dat[i], n[i], x)
    ps = function(x) pr(x)*lk(x)
  }
  curve(ps)
}
# Example of use:
auto(n = c(100, 50), dat = c(55, 60) )

【讨论】:

  • 谢谢,但我收到以下错误:Error in dbeta(x, 1, 1) * function(x) dbinom(dat[i - 1], n[i - 1], x) : non-numeric argument to binary operator
  • 你能解释一下x是什么吗?
  • @MattW。 pr = function(x) dbeta(x, 1, 1) * function(x) dbinom(dat[i-1], n[i-1], x) 无效 - 您需要使用以下内容:pr = function(x) { dbeta(x, 1, 1) * dbinom(dat[i-1], n[i-1], x) }
  • 啊,明白了。谢谢@Dmitriy!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 2022-11-21
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多