【问题标题】:In loops i can not summarize the results in a matrix在循环中,我无法将结果汇总在矩阵中
【发布时间】:2013-12-11 08:47:31
【问题描述】:

对不起,也许我的问题的解决方案很简单,但我还是 R 新手,任何帮助 非常感谢!

我想创建一个数据框或矩阵,每个循环的输出都将存储在其中。 这是程序:

n<-c(10,8,7,5)
n_goal<-c(8,9,9,4)
w<-c(0.1,0.1,0.1,0.1)
matrix<-mat.or.vec(6,4)
FI<-function(n_t) {
  (((n_goal[1]-n[1]+W[1]-f[1]+n_t[1])^2)+((n_goal[2]-n[2]+W[2]-f[2]+n_t[2]-n_t[1])^2)+
  ((n_goal[3]-n[3]+W[3]-f[3]+n_t[3]-n_t[2])^2)+((n_goal[4]-n[4]+W[4]-f[4]-n_t[3])^2))
}
for (i in 1:6) {
    W<-c(n*w)
    sf<-c(1,1,1,1)
    f1<-W%*%sf
    f<-c(f1,0,0,0)
    out<-nlm(FI, n_t<-c(0,0,0), hessian=TRUE)
    for (i in 1:3) {
        if(out$estimate[i]<0)
            out$estimate[i]=0
    }
    n<-c(n-W+f-c(out$estimate,0)+c(0,out$estimate))
    matrix[i, ]<-n
    print(n)
}
matrix

n 是我想在每个循环的矩阵中存储的输出,以便随后绘制一个图。

(每个 n 将是一个点,我希望有 6 个单独的点---六个 4 维向量)

问题在这里:我得到错误的矩阵:

> print(matrix)
         [,1] [,2]     [,3]     [,4]
[1,] 0.000000    0 0.000000 0.000000
[2,] 0.000000    0 0.000000 0.000000
[3,] 8.000002    9 8.999999 3.999998
[4,] 0.000000    0 0.000000 0.000000
[5,] 0.000000    0 0.000000 0.000000
[6,] 0.000000    0 0.000000 0.000000

只有第三行的数字是正确的,其他的都是零,而 print(n) 似乎是正确的

[1] 8.0 9.0 8.5 4.5
[1] 8.00 9.00 8.95 4.05
[1] 8.000003 9.000000 8.999999 3.999998
[1] 8.000002 9.000000 8.999999 3.999998
[1] 8.000002 9.000000 8.999999 3.999998
[1] 8.000002 9.000000 8.999999 3.999998

其实我希望最新的矩阵和 print(n) 一样。

另外,我尝试创建一个数据框,但对我来说很难,因为输出是 向量而不是单个数字。

【问题讨论】:

    标签: r for-loop matrix


    【解决方案1】:

    无需深入了解您的功能正在尝试做什么......

    如果print(n) 确实给出了正确答案(即每个循环都是正确的),那么您可能需要out &lt;- rbind(out, n) 命令:

    所以伪代码可能是

    #start of code
    out <- vector()
    # rest of variables
    FI <- blah blaha..{
    #etc 
    for (i in 1:6)
    {
    #etc..rst of loop
    # not print (n)
    out<- rbind(out,n)
    }
    
    return(out)
    }
    

    或类似的。

    希望对你有帮助!

    【讨论】:

    • 好的,如果你想要的话,请关闭 Q。
    • 不幸的是它不起作用。不管怎样,谢谢你的建议
    【解决方案2】:

    您的优化中有一些错误。由于nlm 用于线性优化,我首先尝试简化您的最小化函数以使用 R 矢量化特征。我也避免使用全局变量来避免副作用。

    FIV <- function(n_t,n_goal,f,W) {
      n_th <- c(n_t,0)
      n_tt <- c(0,n_t)
      sum((n_goal-n+W-f+n_th-n_tt)^2)
    }
    

    为了清晰和更好的性能,然后我将静态初始化语句与主循环隔离开来。

    ## initilizations  
    n <- c(10,8,7,5)
    n_goal <- c(8,9,9,4)
    w <- c(0.1,0.1,0.1,0.1)
    matrix <-mat.or.vec(6,4)
    sf <- c(1,1,1,1)
    

    对于循环,这里不需要使用for。使用replicate,因为您在不使用索引的情况下重复相同的任务,并且因为您希望将最终结果存储在矩阵中。

    replicate(6,{
      W  <- c(n*w) 
      f1 <- W%*%sf
      f  <- c(f1,0,0,0)
      out<- nlm(FIV, c(0,0,0), n_goal,f,W,hessian=TRUE)
      est <- out$estimate
      est[est<0] <- 0
      c(n-W+f-c(est,0)+c(0,est))
    })
    
    # [,1] [,2] [,3] [,4] [,5] [,6]
    # [1,]  8.0  8.0  8.0  8.0  8.0  8.0
    # [2,]  9.0  9.0  9.0  9.0  9.0  9.0
    # [3,]  8.5  8.5  8.5  8.5  8.5  8.5
    # [4,]  4.5  4.5  4.5  4.5  4.5  4.5
    

    编辑您也可以使用sapply,并在每次迭代时更新n(注意使用全局赋值&lt;&lt;-,因为它是一个全局变量)

    sapply(1:6,function(x){
      W  <- c(n*w) 
      f1 <- W%*%sf
      f  <- c(f1,0,0,0)
      out<- nlm(FIV, c(0,0,0), n_goal,f,W,hessian=TRUE)
      est <- out$estimate
      est[est<0] <- 0
      n <<- c(n-W+f-c(est,0)+c(0,est))
      n
    })
    

    【讨论】:

    • 嗯,改动真的很有用,谢谢!问题是 n 在每次迭代时都会发生变化。这就是为什么你找到了一个具有相同元素的矩阵。我可以将此代码与 for 一起使用吗?
    • @user3035550 当然可以。但是你如何改变n?在这种情况下,最好用sapply 替换replicate。比如:sapply(1:6,function(x){ n &lt;- something; the_rest_of_replicate_code})
    • 在每个循环中我有 n
    • agstudy 抱歉,您能否更具体地谈谈您的最新想法?看起来很有趣,我想尝试一下。
    • 期待!非常感谢!
    猜你喜欢
    • 2014-01-09
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多