我刚刚在我的 R 代码中发现了一个非常微妙的错误。以下代码将对象列表作为输入,并为每个对象创建新字段。

每个对象本来就有两个字段(w, p, s, u),然后我又创建了more,beta,phi等。普通的变量就OK了。然而,动态函数(Q、K、K1、K2)是不正确的。假设我有两个 nigs,nigs[[1]] 和 nigs[[2]], nigs[[1]] 的函数 Q、K、K1 和 K2 将与 nigs[[2]] 相同!

我刚刚发现了这个错误,并会咨询如何使此代码正确(同时保持其优雅:)谢谢!

  D <- length(nigs)

  for (i in 1:D) {
    w <- nigs[[i]]$w
    p <- nigs[[i]]$p
    s <- nigs[[i]]$s
    u <- nigs[[i]]$u

    nigs[[i]]$beta <- beta <- w / s * p * (1-p^2)^(-1/2);
    nigs[[i]]$phi <- phi <- w^2 / s^2;

    nigs[[i]]$z <- z <- (x-u)/s;
    nigs[[i]]$alpha_bar <- alpha_bar <- w * (1-p^2)^(-1/2);
    nigs[[i]]$y_bar <- y_bar <- sqrt(1+z^2);

    nigs[[i]]$Q <- Q <- function(t) { sqrt(1 - (2*beta*t+t^2)/phi) }
    nigs[[i]]$K <- K <- function(t) { u*t - w*Q(t) + w }
    nigs[[i]]$K1 <- K1 <- function(t) { (u + w * (beta+t) / (Q(t)*phi)) }
    nigs[[i]]$K2 <- K2 <- function(t) { qt = Q(t); (w/(qt * phi) + w * (beta+t)^2 / (qt^3 * phi^2)); }
  }

编辑

我犯的主要错误是我假设 for { } 引入了新的范围,在这种情况下,w,p,s,u 每次都是不同的 w,p,s,u,实际上不是。只有 R 中的函数引入了新的作用域。并且这个范围规则不同于 C/Java。

最佳答案

这是词法作用域的正常行为。
您可以改用闭包。

f <- list()
g <- list()
for (i in 1:2) {
    j <- i * 2
    f[[i]] <- function() print(j)
    g[[i]] <- (function() {j <- j; function() print(j)}) ()
}

然后,
> for (i in 1:2) f[[i]]()
[1] 4
[1] 4
> for (i in 1:2) g[[i]]()
[1] 2
[1] 4

关于r - 在 R 中创建动态函数的错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9062525/

10-12 23:29