0

我知道这样做可能更优雅 - 但现在我只想了解这个逻辑......我的问题是,当我Y[t]=Y[t-1]+i[t]为模拟做典型的事情时,它在放入函数时不起作用。我想在每行的时间或 t 1-10 上使用正确的变量值生成一个数据框。现在循环内的猫表明我错了。

这是我的代码:

iter <- 10; i <- rep(0.1,iter);  
i <- c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0)
Y0 <- 0.25 ; O0 <- 4.16 
Y <- rep(0,iter); O <- rep(0,iter) 
Tot <- rep(0,iter)
t <- seq(1,iter) #start time and fill vector
Y[1]=Y0 #First iter
O[1]=O0
Tot[1]= Y0+O0
time<-rep(1,iter)#runtime unit

#This is a simplified version of the ICBM function, to test the logic and output
Isim <- function(i, h, Y0, O0,iter,time) {
  for (t in 2:iter) {
    time<- time+1
    Y[t]=(Y[t-1]+i[t-1]); O[t]=(O[t-1]+i[t-1]); Tot[t]=Y[t]+O[t];
    simout <- data.frame(i,Y0,O0,Y,O,Tot,time)
    cat(time)
  } 
  return(simout)
}

result <- Isim(i, h, Y0, O0,iter, time)
4

2 回答 2

1

(让我们抽象一下您的代码无法运行的事实。)您在这Y[t]=(Y[t-1]+i[t-1])一步遇到了范围问题。让我们看一个可重现的小例子:

increment_a <- function() { a <- a + 1; print(a); }
a <- 0; print(a); increment_a(); print(a);
# [1] 0 # ok
# [1] 1 # ok
# [1] 0 # not what you expected

在内部increment_a,当 R 计算时,它首先在函数的环境中a + 1查找。a该环境为空,然后a在调用该函数的环境中查找:您的全局环境。它在那里找到它,值为0. 它添加1到它0,然后在本地环境(即函数的环境a <-)中分配它(语句的一部分) 。

你怎么能解决这个问题?您可以告诉 R 将结果分配给a + 1a全局环境中找到的:使用<<-而不是<-

increment_a <- function() { a <<- a + 1; print(a); }
a <- 0; print(a); increment_a(); print(a);
# [1] 0
# [1] 1
# [1] 1

不建议这样做。这是危险的,会给你带来麻烦。相反,您需要完全接受函数式编程风格。我建议你阅读http://en.wikipedia.org/wiki/Functional_programming的第一段,尤其是关于没有副作用的函数的部分。事情是这样运作的:

  1. 使您的函数仅使用作为参数传递给它的对象。
  2. 通过return语句使用函数的输出。
  3. 不要让你的函数有副作用,特别是不要使用<<-.
  4. 如果您的函数需要修改对象:将它们作为参数传递,让您的函数修改它们并返回它们。然后重新分配结果,如下所示:
increment <- function(x) { x <- x + 1; print(x); return(x); }
a <- 0; print(a); a <- increment(a); print(a);
# [1] 0
# [1] 1
# [1] 1
于 2013-10-13T10:13:33.243 回答
0

在您的循环中time<- time+1,尝试使用time[t] <- t..

当您在每次迭代中递增时,您以向量结束time1

    time
    [1] 10 10 10 10 10 10 10 10 10 10

这是 中的最终输入simout

simout$time在每次迭代中更改如下:

    2 2 2 2 ... 
    3 3 3 3 ...
    ...
    10 10 10 ...

time所以你应该在每次迭代中只改变一个特定的元素。

现在(您可以从中看到catsimout$time更改为:

    1 1 1 1 ...
    1 2 1 1 ...
    1 2 3 1 ...
    ...
    1 2 3 4 5 6 7 8 9 10 #this is the final input in "simout"
于 2013-10-13T10:33:57.113 回答