简体   繁体   中英

Storing values in matrix in nested for loops in R

I'm new here and in general to programming - was hoping for some help. I have the following code for backtracking an Extended Kalman Filter, which gives me the MSE for specific parameters. The problem is when I run the code, at the end, the matrix only stores the last set of values instead of all of them. If you need to run the code on your PC, just replace the file name with any data set you have on hand. It should still work.

start.time <- Sys.time()

library(invgamma)
w = read.csv("Reddy.csv")
q = ts(w[2])
num = length(q)

f = function(x){
  f1 = sqrt(x)
  return(f1)
}
h = function(x){
  h1 = x**3
  return(h1)
}


ae1 = seq(24,26)
ae2 = seq(24,26)

be1 = seq(1,3)
be2 = seq(1,3)

a = seq(1,3)
b = seq(1,3)

MSE = matrix(nrow = length(ae1)*length(ae2)*length(be1)*length(be2)*length(a)*length(b), ncol =7)

for (i in ae1){
  for (j in ae2){
    for (k in be1){
      for (l in be2){
        for (m in a){
          for (n in b){
            d = rep(0,num)
            for(o in 2:num){
              xt = rep(0,num)
              yt = rep(0,num)
              fx = rep(0,num)
              hx = rep(0,num)

              e = rinvgamma(num,i,k)
              g = rinvgamma(num,j,l)
              fx[o] = f(xt[o-1])
              xt[o] = m*fx[o] + e[o-1]
              hx[o] = h(xt[o])
              yt[o]= n*hx[o] +g[o]
              d[o] = (yt[o] - q[o])**2
            }
            MSE[,1] = mean(d)
            MSE[,2] = i
            MSE[,3] = j
            MSE[,4] = k
            MSE[,5] = l
            MSE[,6] = m
            MSE[,7] = n
            t = rbind(mean(d),i,j,k,l,m,n)
            print(t)
          }
        }
      }
    }
  }
}

end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

m = which.min(MSE[1])

Ideally, my matrix would have the first row as the MSE, the 2nd to 7th column would have the corresponding i,j,k,l,m,n values respectively and each iteration would get logged into a new row entry. Here, it seems to rewrite the entire matrix each time.

When you use

MSE[,2] = i

You actually call the entire column, and therefore the code is rewriting that column. I have updated the code with a counter that'll help.

start.time <- Sys.time()

library(invgamma)
w = read.csv("Reddy.csv")
q = ts(w[2])
num = length(q)

f = function(x){
  f1 = sqrt(x)
  return(f1)
}
h = function(x){
  h1 = x**3
  return(h1)
}


ae1 = seq(24,26)
ae2 = seq(24,26)

be1 = seq(1,3)
be2 = seq(1,3)

a = seq(1,3)
b = seq(1,3)

count = 0

MSE = matrix(nrow = length(ae1)*length(ae2)*length(be1)*length(be2)*length(a)*length(b), ncol =7)

for (i in ae1){
  for (j in ae2){
    for (k in be1){
      for (l in be2){
        for (m in a){
          for (n in b){
            d = rep(0,num)
            for(o in 2:num){
              xt = rep(0,num)
              yt = rep(0,num)
              fx = rep(0,num)
              hx = rep(0,num)

              e = rinvgamma(num,i,k)
              g = rinvgamma(num,j,l)
              fx[o] = f(xt[o-1])
              xt[o] = m*fx[o] + e[o-1]
              hx[o] = h(xt[o])
              yt[o]= n*hx[o] +g[o]
              d[o] = (yt[o] - q[o])**2
            }
            count <- count + 1
            MSE[count,1] = mean(d)
            MSE[count,2] = i
            MSE[count,3] = j
            MSE[count,4] = k
            MSE[count,5] = l
            MSE[count,6] = m
            MSE[count,7] = n
            t = rbind(mean(d),i,j,k,l,m,n)
            print(t)
          }
        }
      }
    }
  }
}

end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

m = which.min(MSE[1])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM