Reputation:
I have a complicated function that works on a matrix row by row. The function returns values that must be used as entries of the matrix rows, row by row. I need to use a for
loop to make sure that these values are stored correctly. I cannot apply the function at once using a simple lapply
or for
loop, as there must be a condition based on the values of each row. Is there a way to run the for
loop on each item and store the result in a matrix before moving to the next item? Note that this is different from my other posted question. My last question was on applying a condition on a matrix. However, here, I need to use a function on items and store them in a matrix, row by row.
In a simple way:
Here I have a list of vectors (stored in a list x
). I need the for loop
to loop over each vector of x
before moves to the elements of the second vector. For this case, I create an empty matrix (Mat
). Then, I need to apply the square on the first vector of x
(i.e, c(1:4)
). Then, and before moving to square the next vector of x
, if any entries of this row are != 0
, then the result is stored in Mat
(last row (row 5
)), and the loop moves to the second vector. However, if all entries are ==0
, then the loop must stop and return me an empty matrix. If the result of the second vector is all ==0
, then the loop stores zeros to all rows (except the row 5
) of Mat
. If not, then the loop moves to the third vector, and so on.
My code gives me an error Error in Mat[k, i] <- res[[i]] : number of items to replace is not a multiple of replacement length In addition: Warning message: In seq_len(k - 1) : first element used of 'length.out' argument
x <- list(c(1:4), c(2,0,0), c(0,0,0), 0)
res <- list() ## I would like to store the result of squares.
Mat <- matrix(0,5,5) ## here is the matrix where the result
d <- 5
for(k in d:2){
for (i in seq_along(k-1)){
res[[i]] <- x[[i]]^2 ## here I would like to find the result of the first item only before moving to the next one.
Mat[k,i] <- res[[i]] ## store the result of the vector sas a row (bottom to top)
if(all(setdiff(Mat[k,i], 0) == 0, na.rm = TRUE)){ ## if the result of the current vector is `0` then, I want to stop. The current row and coming rows set to zero.
Mat[k,] <- 0
break
}
}
}
Expected result:
Mat
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 4 0 0 0 0
[5,] 1 4 9 16 0
Upvotes: 2
Views: 85
Reputation: 102770
We can try for
loop like this
x <- list(c(1:4), c(2, 0, 0), c(0, 0, 0), 0)
Mat <- matrix(0, 5, 5)
for (k in seq_along(x)) {
r <- x[[k]]^2
if (any(r != 0)) {
Mat[nrow(Mat) - k + 1, seq_along(r)] <- r
} else {
break
}
}
which gives
> Mat
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 4 0 0 0 0
[5,] 1 4 9 16 0
Upvotes: 0