Home > Software engineering >  Referring to Elements in an Array in a For Loop in R - beginner
Referring to Elements in an Array in a For Loop in R - beginner

Time:03-07

Edit: Someone said the question is unclear, edited.

I have made a 3 dimensional array, and assigned values as follows:

D <- c('g', 't', NA, 'd')
nPeriods = 4
column.names = c('aaa', 'bbb')
row.names = c('jjj', 'hhh')
threeD.names = c(1:nPeriods)
E = array(c(D), dim=c(2, 2, nPeriods),
          dimnames = list(row.names, column.names, threeD.names))

values <- c(g = 5,
            t = 2,
            d = 7)

G <- apply(E, 1:3, function(x) values[x])

Now I want to make a for loop, to do things like:

for (i in 2:nPeriods){
  G[1,1,i]=G[1,1,i-1]*G[2,1,i-1] G[2,2,i]
}

But I don't want to have to find the location of g, t and d each time I want to write something like this. I just want to be able to use g, t, and d if possible.

Question ends here.


Below is some helpful code that could possibly be adapted to find a solution?

I have this code which looks up and returns an index for each value:

result <- G
for (i in 2:dim(G)[3]) {
  idx <- which(E[, , 1] == 'g', arr.ind = T)
  row <- idx[1, 'row']
  col <- idx[1, 'col']
  result[row, col, i] <- result[row, col, i-1] * 2
}

For a simpler problem, but my real array is quite large, so writing for each element will be long. Is there a way of automating this?

They also suggested this - which is great for simple sums, but I'm not sure how it could apply to the type of sum I have above:

funcs <- c(g = '*', t = ' ', d = '-')
modifiers <- c(g = 2, t = 3, d = 4)

G <- apply(E, 1:3, function(x) values[x])

result <- G
for (i in 2:dim(G)[3]) {
  for (j in names(values)) {
    idx <- which(E[, , 1] == j, arr.ind = T)
    row <- idx[1, 'row']
    col <- idx[1, 'col']
    result[row, col, i] <- do.call(funcs[j], args = list(result[row, col, i-1], modifiers[j]))
  }
}

CodePudding user response:

Based on the clarification, maybe this works - get the row/column index for 'g', 't', 'd' from the E[, , 1], loop over the nPeriods from 2, and update the 'result' by subseting the elements with a matrix index created with cbind using gidx, tidx and didx with i or i-1 to update recursively

result <- G
gidx <- which(E[, , 1] == 'g', arr.ind = TRUE)
tidx <- which(E[, , 1] == 't', arr.ind = TRUE)
didx <- which(E[, , 1] == 'd', arr.ind = TRUE)
for (i in 2:nPeriods) {     
      result[cbind(gidx, i)] <- result[cbind(gidx, i-1)] * 
               result[cbind(tidx, i-1)]   result[cbind(didx, i)]
  }

-output

> result
, , 1

    aaa bbb
jjj   5  NA
hhh   2   7

, , 2

    aaa bbb
jjj  17  NA
hhh   2   7

, , 3

    aaa bbb
jjj  41  NA
hhh   2   7

, , 4

    aaa bbb
jjj  89  NA
hhh   2   7

-checking with OP's output

resultold <- G

for (i in 2:nPeriods){
  resultold[1, 1, i] <- resultold[1,1,i-1]* resultold[2,1,i-1] resultold[2,2,i]
}

 identical(result, resultold)
[1] TRUE
  • Related