Rotate matrices within array by 90 degrees - arrays

I do apology for my silly question but I am just starting to familiarise with arrays.
I just need to rotate the matrices within my array by 90degrees.
Here some data and what I tried so far:
mat1 = as.matrix(data.frame(col1 = c(1,2,3,4,5,6,7,8), col2 = c(2,3,'NA',5,6,7,8,9), col3 = c(3,4,5,6,7,8,9,10), col4 = c(2,3,4,1,2,6,7,8),
col5 = c(2,3,'NA','NA',6,7,8,9), col6 = c(1,2,3,5,6,7,8,9), col7 = c(1,2,3,4,6,7,'NA','NA')))
mat2 = as.matrix(data.frame(col1 = c('NA',2,3,4,5,6,7,8), col2 = c(2,3,1,5,6,7,8,9), col3 = c(3,4,5,6,7,8,9,'NA'), col4 = c(2,3,4,1,2,6,7,8),
col5 = c(2,3,11,88,6,7,8,9), col6 = c(1,2,3,5,6,7,8,9), col7 = c(1,2,3,4,6,7,'NA','NA')))
#ignore warnings
class(mat1) = 'numeric'
class(mat2) = 'numeric'
my_array = array(c(mat1, mat2), dim = c(8,7,2))
What I tired with no success:
library(pracma)
ar_rot = array(dim=c(8,7,2))
for (i in 1:2) {
ar_rot[,,i] = rot90(my_array[,,i], k = 1)
}
I think the issues lies in the indexes of ar_rot because if I apply the same code to only one matrix e.g.
ar_rot_1 = rot90(my_array[,,1], k = 1)
it works! but my array has got thousands of matrices!
Any hint?
Thanks

I found a way around my question by converting the array to a list, apply the function and then convert back the list to array:
lst = lapply(seq(dim(my_array)[3]), function(x) my_array[ , , x]) #convert to list
lst = lapply(lst, function(x) rot90(x, 1)) #rotate
#convert list back to array
ar_rot = array(as.numeric(unlist(lst)), dim=c(7, 8, 2))
> print(ar_rot)
, , 1
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 2 3 4 6 7 NA NA
[2,] 1 2 3 5 6 7 8 9
[3,] 2 3 NA NA 6 7 8 9
[4,] 2 3 4 1 2 6 7 8
[5,] 3 4 5 6 7 8 9 10
[6,] 2 3 NA 5 6 7 8 9
[7,] 1 2 3 4 5 6 7 8
, , 2
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 2 3 4 6 7 NA NA
[2,] 1 2 3 5 6 7 8 9
[3,] 2 3 11 88 6 7 8 9
[4,] 2 3 4 1 2 6 7 8
[5,] 3 4 5 6 7 8 9 NA
[6,] 2 3 1 5 6 7 8 9
[7,] NA 2 3 4 5 6 7 8

Related

Identifying dimension-specific index position in R using arr.ind

I understand that by setting ind.arr = TRUE, R will treat the array as an array or matrix instead of a single vector. However, I am having trouble extracting elements from a multi-dimensional array.
Creating a 3x2x3 array
qux <- array (data = c(10, 5, 1, 4, 7, 4, 3, 3, 1, 3, 4, 3, 1, 7, 8, 3, 7, 3), dim=c(3,2,3))
Output
> qux
, , 1
[,1] [,2]
[1,] 10 4
[2,] 5 7
[3,] 1 4
, , 2
[,1] [,2]
[1,] 3 3
[2,] 3 4
[3,] 1 3
, , 3
[,1] [,2]
[1,] 1 3
[2,] 7 7
[3,] 8 3
I would like to identify the dimension-specific index positions of elements that are either 3 OR 4. I tried to test it out by extracting elements that are 3 first and I got this as my output:
Extracting elements = 3
which ((qux ==3), arr.ind=T)
Output
> which ((qux ==3), arr.ind=T)
dim1 dim2 dim3
[1,] 1 1 2
[2,] 2 1 2
[3,] 1 2 2
[4,] 3 2 2
[5,] 1 2 3
[6,] 3 2 3
I'm not sure if what I'm doing is correct. May I know how do I get the exact position (row, column and dimension if possible) of elements that are either 3/4?
Edit
I got this as an output after using the code
which((qux ==3) | (qux==4), arr.ind=TRUE)
Output
dim1 dim2 dim3
[1,] 1 2 1
[2,] 3 2 1
[3,] 1 1 2
[4,] 2 1 2
[5,] 1 2 2
[6,] 2 2 2
[7,] 3 2 2
[8,] 1 2 3
[9,] 3 2 3
However, I do not understand what does all the 1s, 2s and 3s represent. Can someone explain it to me? Thank you.

Using a list-matrix to supply indices to N-dimensional object

I am working on a partial differential equations project where some N-dimensional objects are required. I got stuck in padding one N-dim object with a copy of each of its dimensions. Here is the function:
padreplicate <- function(a, padSize) {
# Pad an array by replicating values.
numDims <- length(padSize)
idx <- vector("list", numDims)
for (k in 1:numDims) {
M <- dim(a)[k] # 32
onesVector <- ones(1, padSize[k])
idx[[k]] <- c(onesVector, 1:M, M * onesVector)
}
# return(a[ unlist(idx[1]), unlist(idx[2]) ]) # this works for 2D
# return(a[ idx[[1]], idx[[2]] ]) # this also works for 2D
# return(a[apply(idx, 1, function(x) unlist[x])]) #:( doesn't work
# a[sapply(apply(idx, 1:length(dim(idx)), function(x) eval(parse(text=x))), unlist)] #:(
# 2D: "a[idx[[1]], idx[[2]]]" 3D: "a[idx[[1]], idx[[2]]], idx[[3]]]"
dim_text = paste0("a", "[ ",
paste0(sapply(1:length(idx), function(x)
paste0("idx", "[[", x, "]]")), collapse = ", ")," ]")
eval(parse(text=dim_text)) # this works
}
The first argument is the N-dim object; it could be a matrix, a 3D array or higher dimensional array.
An example for a 2D object or matrix would be:
# pad a matrix 4x3 with c(1,1)
set.seed(123456)
mx = matrix(sample.int(9, size = 9*100, replace = TRUE), nrow = 4, ncol = 3)
mx
# [,1] [,2] [,3]
# [1,] 8 4 9
# [2,] 7 2 2
# [3,] 4 5 8
# [4,] 4 1 6
padreplicate(mx, c(1,1))
The padded matrix looks like this:
[,1] [,2] [,3] [,4] [,5]
[1,] 8 8 4 9 9
[2,] 8 8 4 9 9
[3,] 7 7 2 2 2
[4,] 4 4 5 8 8
[5,] 4 4 1 6 6
[6,] 4 4 1 6 6
For a 3-D array the input array and the padded array.
ar = array(sample.int(9, size = 9*100, replace = TRUE), dim = c(3, 3, 1))
ar
padreplicate(ar, c(1,1,1))
# input 3x3x1 array
, , 1
[,1] [,2] [,3]
[1,] 3 4 6
[2,] 7 2 9
[3,] 3 4 8
# padded 5x5x3 array
, , 1
[,1] [,2] [,3] [,4] [,5]
[1,] 3 3 4 6 6
[2,] 3 3 4 6 6
[3,] 7 7 2 9 9
[4,] 3 3 4 8 8
[5,] 3 3 4 8 8
, , 2
[,1] [,2] [,3] [,4] [,5]
[1,] 3 3 4 6 6
[2,] 3 3 4 6 6
[3,] 7 7 2 9 9
[4,] 3 3 4 8 8
[5,] 3 3 4 8 8
, , 3
[,1] [,2] [,3] [,4] [,5]
[1,] 3 3 4 6 6
[2,] 3 3 4 6 6
[3,] 7 7 2 9 9
[4,] 3 3 4 8 8
[5,] 3 3 4 8 8
These are all correct results.
My question is this: "is there a better way of doing this N-dim padding operation?
EDIT 1
Thanks to Frank, now the N-dimensional padreplicate function:
padreplicate <- function(a, padSize) {
# Pad an array by replicating values.
numDims <- length(padSize)
idx <- vector("list", numDims)
for (k in 1:numDims) {
M <- dim(a)[k] # 32
onesVector <- ones(1, padSize[k])
idx[[k]] <- c(onesVector, 1:M, M * onesVector)
}
do.call( `[`, c(list(a), idx))
}
EDIT 2
Using matrix instead of my function ones. Sorry about that.
padreplicate <- function(a, padSize) {
# Pad an array by replicating values.
numDims <- length(padSize)
idx <- vector("list", numDims)
for (k in 1:numDims) {
M <- dim(a)[k] # 32
onesVector <- matrix(1, 1, padSize[k])
idx[[k]] <- c(onesVector, 1:M, M * onesVector)
}
do.call( `[`, c(list(a), idx))
}

R Filling 3-dimensional array by row

I know there have been similar topics but they don't seem to answer my problem. I have a 3-dimensional array, composed of matrices (10,5).
I want to fill each matrix by row, by let say 1:5.
Previous topics talks about aperm, but here's the problem : since my matrices are not symmetric, when I first fill them by column as follows :
kappa=array(0,dim=c(10,5,2))
kappa[1:10,,1]=1:5
kappa[,,1]
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[6,] 1 1 1 1 1
[7,] 2 2 2 2 2
[8,] 3 3 3 3 3
[9,] 4 4 4 4 4
[10,] 5 5 5 5 5
Since the column dimension is lower than the row dim, the sequence is replicated. So when I aperm the result, it gives :
aperm(kappa[,,1])
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 2 3 4 5 1 2 3 4 5
[2,] 1 2 3 4 5 1 2 3 4 5
[3,] 1 2 3 4 5 1 2 3 4 5
[4,] 1 2 3 4 5 1 2 3 4 5
[5,] 1 2 3 4 5 1 2 3 4 5
But what I want instead is
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 1 2 3 4 5
[3,] 1 2 3 4 5
[4,] 1 2 3 4 5
[5,] 1 2 3 4 5
[6,] 1 2 3 4 5
[7,] 1 2 3 4 5
[8,] 1 2 3 4 5
[9,] 1 2 3 4 5
[10,] 1 2 3 4 5

Finding the dimension indexes of elements of an array

Consider this array:
the.seq <- 1:4
sol<- outer(outer(the.seq, the.seq, `+`), the.seq, `+`)
I want to find all elements that sum 6. That is pretty easy to do with which:
indices <- which(sol == 6)
indices
[1] 4 7 10 13 19 22 25 34 37 49
Now I want a vector with the dimension indexes of these elements, the answer would be:
[,1] [,2] [,3]
[1,] 4 1 1
[2,] 3 2 1
[3,] 2 3 1
[4,] 1 4 1
[5,] 3 1 2
[6,] 2 2 2
[7,] 1 3 2
[8,] 2 1 3
[9,] 2 1 3
[10,] 1 1 4
How would you do this?
You can use the arr.ind argument in which. When set to TRUE, which will return the array indices for which its first argument is TRUE.
which(sol == 6, arr.ind = TRUE)
# dim1 dim2 dim3
# [1,] 4 1 1
# [2,] 3 2 1
# [3,] 2 3 1
# [4,] 1 4 1
# [5,] 3 1 2
# [6,] 2 2 2
# [7,] 1 3 2
# [8,] 2 1 3
# [9,] 1 2 3
#[10,] 1 1 4

Trivial subset selection with array in R

I have an 6*3*3 dimensional array:
a<-array(data=rep(1:5,10),dim=c(6,3,3)
I have another vector with 3 numbers:
b<-1:3
I would like to do the following selection:
Select from the first column of a those values that that have b in their second column.
I would like to use b as an index for the third dimension of a. i.e. the first value of b should be searched in a[,,1] the second value of b in a[,,2] and the third value in a[,,3]
The original array looks like this:
a
, , 1
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 3 4
[3,] 3 4 5
[4,] 4 5 1
[5,] 5 1 2
[6,] 1 2 3
, , 2
[,1] [,2] [,3]
[1,] 4 5 1
[2,] 5 1 2
[3,] 1 2 3
[4,] 2 3 4
[5,] 3 4 5
[6,] 4 5 1
, , 3
[,1] [,2] [,3]
[1,] 2 3 4
[2,] 3 4 5
[3,] 4 5 1
[4,] 5 1 2
[5,] 1 2 3
[6,] 2 3 4
after the selection this is what I would like to get:
, , 1
[,1]
[5,] 5
, , 2
[,1]
[3,] 1
, , 3
[,1]
[1,] 2
[6,] 2
You can do:
lapply(seq_along(b), function(i) a[a[, 2, i] == b[i], 1, i, drop = FALSE])
Note that the output is a list of one-column matrices. I don't think you can get away without a list because the number of matches for each b[i] may differ. Also, you might want to remove drop = FALSE so the output will just be a list of vectors.

Resources