This is an update to the first question I asked. I essentially am still missing the pretty obvious learning lesson and can't expand the code that worked originally.
Trying to store a nested loop that runs all permutations of calculations.
I'm missing understanding on how to set up the index still. I am now trying to set this up with three sets of loops (and really, I want to set this up so I understand how to do it with any # of them). The code below doesn't exactly work, the third loop doesn’t index over every combination (but I get 1000 calculations anyway) I commented the part that is clearly wrong...
With only two loops, this was sufficient, per the answer of my first post:
index <- 10*(i-1) j
So not sure why the way I changed it for 3 loops doesn't work, but it's obviously wrong.
iter = 10 #length of parameter ranges to test
perm = 3 #how many parameters are being varied
n_c <- 1
m_c <- 1
n_n <- 1
m_n <- 1
n_v <- 1
my_data_c <- vector("numeric", iter^perm)
my_data_n <- vector("numeric", iter^perm)
my_data_v <- vector("numeric", iter^perm)
rho_c_store <- vector("numeric", iter)
rho_n_store <- vector("numeric", iter)
rho_v_store <- vector("numeric", iter)
for (i in 1:iter) {
# you can move this assignment to the outer loop
rho_c <- (i / 10)
x <- (rho_c * n_c)/m_c
for (j in 1:iter) {
rho_n <- (j / 10)
y <- (rho_n * n_n)/m_n
for (k in 1:iter){
rho_v <- (k / 10)
z <- rho_v/n_v
index <- iter*(i-2) j k #Clearly where the error is
rho_c_store[index] <- rho_c
rho_n_store[index] <- rho_n
rho_v_store[index] <- rho_v
my_data_c[index] <- x
my_data_n[index] <- y
my_data_v[index] <- z
}
}
}
my_data <- cbind(rho_c_store, rho_n_store, rho_v_store, my_data_c, my_data_n,my_data_v)
print(my_data)
CodePudding user response:
Think of it as if you were counting: the ones move the fastest, next come the tens, then the hundredes. 001, 002, ..., 010, ..., 099, 100, 101. You can think of your loop variables ijk
like the digits of a number - k moves the fastest, j slower and i slower still. To get the right index you have to multiply the i with 100, the j with 10 and the k with one, givin you the index 100 * (i-1) 10 * (j-1) k
. The -1
for i and j is necessary because the loop variable starts from 1, but we want to start by adding 0 * 100
and 0 * 10
.
So all you need to do is change your index calculation to index <- iter^2*(i-1) iter*(j-1) k
.
# I stripped the example to the essentials for easier understanding
iter = 10 #length of parameter ranges to test
perm = 3 #how many parameters are being varied
my_data_c <- vector("numeric", iter^perm)
my_data_n <- vector("numeric", iter^perm)
my_data_v <- vector("numeric", iter^perm)
for (i in 1:iter) {
x <- i / 10
for (j in 1:iter) {
y <- j / 10
for (k in 1:iter){
z <- k / 10
index <- iter^2*(i-1) iter*(j-1) k
my_data_c[index] <- x
my_data_n[index] <- y
my_data_v[index] <- z
}
}
}
my_data <- cbind(my_data_c, my_data_n, my_data_v)
print(my_data)
Anyway, while it's great to develop an deep understanding of these things you're certainly on the right track when you move away from looping with explicit indices and use R's toolkit for such tasks.
Hope this helps
CodePudding user response:
In case anyone else wants to try this...expand.grid is definitely the way to go. Still not sure how to deal with the nested loop from a coding perspective, but oh well..
n_c <- 1
m_c <- 1
n_n <- 1
m_n <- 1
n_v <- 1
c = c(1,2)
n = c(10,20)
v = c(100,200)
parm_length = 3
iter = length(c)
test <- data.frame(matrix(ncol=parm_length, nrow=iter^parm_length))
test[] <- expand.grid(c,n,v)
x <- (test[,1] * n_c)/m_c
y <- (test[,2]* n_n)/m_n
z <- (test[,3]/n_v)
group <- cbind(test,x,y,z)
print(group)