首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在函数中从for循环获得正确的输出

在函数中从for循环获得正确的输出
EN

Stack Overflow用户
提问于 2013-10-13 17:01:25
回答 2查看 90关注 0票数 0

我知道这样做可能更优雅--但现在我只想摸索一下这个逻辑……我的问题是,当我做一个典型的Y[t]=Y[t-1]+i[t]模拟时,它在放入一个函数时不起作用。我想有一个数据帧出来与正确的变量值在每一行的时间或t1-10。现在,循环中的猫显示我错了。

下面是我的代码:

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

发布于 2013-10-13 18:13:33

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

代码语言:javascript
复制
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 + 1的结果赋给在全局环境中找到的a:使用<<-而不是<-

代码语言:javascript
复制
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的第一段,特别是关于函数没有副作用的部分。事情是这样运作的:

让你的函数只使用作为参数传递给它的对象,通过arguments.

  • make statement.

  • Do使用函数的输出不会使你的函数产生副作用,特别是,不要使用<<-.

  • if你的函数需要修改的对象:将它们作为参数传递,使你的函数修改并返回它们。然后重新分配结果,如下所示:

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2013-10-13 18:33:57

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

当您在每次迭代中按1递增time时,您将以向量结束:

代码语言:javascript
复制
    time
    [1] 10 10 10 10 10 10 10 10 10 10

这是simout中的最终输入。

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

代码语言:javascript
复制
    2 2 2 2 ... 
    3 3 3 3 ...
    ...
    10 10 10 ...

因此,您应该在每次迭代中只更改time的一个特定元素。

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

代码语言:javascript
复制
    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"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19343473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档