将重复循环的所有迭代结果保存到 R 中的工作区

Save all iteration result of repeat loop to workspace in R

我尝试创建一个基于逻辑案例的重复循环函数,如下所示:

n=5    # number of element in lambda
t=10   # limit state
lambda=c(runif(n,2,4)) #vector to be tested


tes=function(x)
{
  if(x>=t) {a=0;b=0;c=0} 
  else
  {  
    repeat
    {
      a=runif(1,0.5,0.8)
      b=runif(1, 5, 8)
      c=x+a+b
      print(a)
      print(b)
      if (c>=t) {break}
    }
  }
return(list(a,b,c))
}

我需要将所有重复循环迭代输出保存到工作区中的一个对象中,以便以后使用。但是我的函数只保存迭代的最新值。 这是 lambda[1] 的迭代示例: 迭代次数:

[1] 0.6714837
[1] 5.840948
[1] 0.7914275
[1] 7.264076

列表中保存的结果:

[[1]]
[[1]][[1]]
[1] 0.7914275

[[1]][[2]]
[1] 7.264076

[[1]][[3]]
[1] 11.03819

如何在输出列表中保存每次迭代的每个结果? 我已经查看了其他线程,但我还没有找到适合我的案例的解决方案。谢谢。

问题中也遇到了类似的问题,希望对您有用。因此,您应该在您的函数中插入一个累积函数,如下例所示。它模拟了一个游戏,如果获胜,您将获得金钱,否则您将输掉金钱。此程序存储您在整个过程中的储蓄波动。

x <- y <- 10

while (x > 0) {
  if (rbinom(1, 1, 0.5) == 1) {
    x <- x + 10
  } else {
    x <- x - 1
  }
  y <- c(y, x)
}

否则,如果您的问题出现在更高级的维度级别,您可以尝试矢量化方法,这种方法要快得多。但是对于你的问题,公开的方法应该没问题。

您可以将中间结果保存在列表中,然后 return 它 (loop_results)。见下文。我还对您的代码进行了一些格式化,以便以更 intelligible/compact 的方式打印中间结果,并命名 returned 列表。

tes <- function(x) {
  if(x>=t) {
    a=0;b=0;c=0
    } else {
      loop_results <- list()
      i=0
    repeat
    {
      i <- i+1
      a=runif(1,0.5,0.8)
      b=runif(1, 5, 8)
      c=x+a+b
      cat("iteration ", i, "a: ", a, "b: ", b, "\n")
      loop_results[[i]] <- list(a=a, b=b, c=c)
      if (c>=t) {break}
    }
  }
  return(list(a=a, b=b, c=c, loop_results=loop_results))
}

您可以将结果累积到 data.frame。

我还建议您不要分配像 ct 这样的标识符,因为它们是内置函数,可以被本地人屏蔽,尤其是当您将函数作为参数传递时, 例如 do.call(c,...).

我还建议将极限状态变量作为另一个参数传递给函数可能是合适的。

tes <- function(x,lim) {
    res <- data.frame(a=double(),b=double(),c=double());
    if (x >= lim) {
        res[1L,] <- c(0,0,0);
    } else {
        i <- 1L;
        repeat {
            ta <- runif(1L,0.5,0.8);
            tb <- runif(1L,5,8);
            tc <- x+ta+tb;
            res[i,] <- c(ta,tb,tc);
            print(ta);
            print(tb);
            if (tc >= lim) break;
            i <- i+1L;
        };
    };
    return(res);
};

演示:

set.seed(5L);
n <- 5L; ## number of elements in lambda
lambda <- runif(n,2,4); ## vector to be tested
lambda;
## [1] 2.400429 3.370437 3.833752 2.568799 2.209300
res <- lapply(lambda,tes,10);
## [1] 0.7103172
## [1] 6.58388
## [1] 0.7423806
## [1] 7.8695
## [1] 0.5331359
## [1] 5.819855
## [1] 0.647154
## [1] 5.955212
## [1] 0.6677518
## [1] 5.787779
## [1] 0.5605626
## [1] 6.162577
## [1] 0.7663609
## [1] 6.664768
## [1] 0.7526538
## [1] 7.670621
## [1] 0.7162103
## [1] 5.634021
## [1] 0.5677152
## [1] 5.419951
## [1] 0.6439742
## [1] 6.312236
## [1] 0.7897892
## [1] 5.425742
## [1] 0.7864937
## [1] 6.334192
## [1] 0.5178087
## [1] 5.825448
## [1] 0.5093445
## [1] 5.043447
## [1] 0.6461507
## [1] 6.785455
## [1] 0.6793559
## [1] 6.193042
## [1] 0.6190491
## [1] 7.448228
res;
## [[1]]
##           a       b         c
## 1 0.7103172 6.58388  9.694626
## 2 0.7423806 7.86950 11.012310
##
## [[2]]
##           a        b         c
## 1 0.5331359 5.819855  9.723428
## 2 0.6471540 5.955212  9.972803
## 3 0.6677518 5.787779  9.825968
## 4 0.5605626 6.162577 10.093577
##
## [[3]]
##           a        b        c
## 1 0.7663609 6.664768 11.26488
##
## [[4]]
##           a        b        c
## 1 0.7526538 7.670621 10.99207
##
## [[5]]
##            a        b         c
## 1  0.7162103 5.634021  8.559531
## 2  0.5677152 5.419951  8.196967
## 3  0.6439742 6.312236  9.165510
## 4  0.7897892 5.425742  8.424831
## 5  0.7864937 6.334192  9.329986
## 6  0.5178087 5.825448  8.552557
## 7  0.5093445 5.043447  7.762092
## 8  0.6461507 6.785455  9.640906
## 9  0.6793559 6.193042  9.081698
## 10 0.6190491 7.448228 10.276578

我冒昧地在函数中添加了一个参数和一个 "maximum iteration" 参数以及一个警告。我认为最佳结果形式是向量 a、b 和 c 的数据框。

然后,要将其应用于矢量,我建议使用 lapply 函数。

n <- 5                    # number of element in lambda
limitstate <- 10          # limit state
lambda <- c(runif(n,2,4)) #vector to be tested

tes <- function(x, t, maxiter = 1000) {
  if( x >= t) {
    return(data.frame(a=0, b=0, c=0))
  } else {
    iter <- 1
    a <- c()
    b <- c()
    c <- c()
    repeat {
      a[iter] <- runif(1, 0.5, 0.8)
      b[iter] <- runif(1, 5, 8)
      c[iter] <- x + a[iter] + b[iter]
      if (c[iter] >= t) break
      iter <- iter+1
      if (iter >= maxiter) {
        warning("Maximum iteration reached")
        break
      }
    }
  }
  return(data.frame(a=a,b=b,c=c))
}

tes(2, 10)
lapply(lambda, tes, t=limitstate)