Subsetting an array based on multiple columns - arrays

I have a large array in r and would like to subset it using points I obtained from a different matrix.
i.e.
,,1
34 1 1 3 4
32 1 3 4 5
23 1 1 3 4
35 1 3 4 4
23 1 2 3 4
,,2
234 1 1 3 4
32 1 3 4 5
324 1 1 3 4
23 1 3 4 4
232 1 2 3 4
and would like it to return
34 1 1 3 4
23 1 1 3 4
23 1 2 3 4
234 1 1 3 4
324 1 1 3 4
232 1 2 3 4
in some format.
These particular rows would be returned as I am choosing based on the last 3 columns
(i.e I want all the rows with last 3 digits 1,3,4 and 2,3,4)

One way is
m1 <- apply(ar1, 2, `[`)
m1[m1[,2]%in% 1:2 & m1[,3]==3 & m1[,4]==4,]
# [,1] [,2] [,3] [,4]
#[1,] 1 1 3 4
#[2,] 1 1 3 4
#[3,] 1 2 3 4
#[4,] 1 1 3 4
#[5,] 1 1 3 4
#[6,] 1 2 3 4
Or
res <- do.call(rbind,lapply(seq(dim(ar1)[3]), function(i) {
x1 <- ar1[,,i]
x2 <- t(x1[,-1])
x1[colSums(x2==c(1,3,4)|x2==c(2,3,4))==3,]}))
res
# [,1] [,2] [,3] [,4]
#[1,] 1 1 3 4
#[2,] 1 1 3 4
#[3,] 1 2 3 4
#[4,] 1 1 3 4
#[5,] 1 1 3 4
#[6,] 1 2 3 4
Update
Suppose if the values to match are in a matrix with each row as the matching vector.
toMatch <- rbind(c(1,3,4), c(2,3,4), c(4,3,2), c(1,9,4))
indx1 <- apply(toMatch, 1, paste, collapse="")
res <- do.call(rbind,lapply(seq(dim(ar1)[3]), function(i) {
x1 <- ar1[,,i]
x1[apply(x1[,-1], 1, paste, collapse='') %in% indx1,]
}))
data
ar1 <- structure(c(1, 1, 1, 1, 1, 1, 3, 1, 3, 2, 3, 4, 3, 4, 3, 4, 5,
4, 4, 4, 1, 1, 1, 1, 1, 1, 3, 1, 3, 2, 3, 4, 3, 4, 3, 4, 5, 4,
4, 4), .Dim = c(5L, 4L, 2L))

Related

Julia: delete rows and columns from an array or matix

How can I delete one or more rows and/or columns from an array?
Working with:
julia> array = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]
4×4 Array{Int64,2}:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
To delete a single row (here row 2):
julia> newarray = array[1:end .!= 2, :]
3×4 Array{Int64,2}:
1 2 3 4
9 10 11 12
13 14 15 16
To delete a single column (here column 3):
julia> newarray = array[:, 1:end .!= 3]
4×3 Array{Int64,2}:
1 2 4
5 6 8
9 10 12
13 14 16
To delete a single row and a single column (here row 2, column 3):
julia> newarray = array[1:end .!= 3, 1:end .!= 3]
3×3 Array{Int64,2}:
1 2 4
5 6 8
13 14 16
To delete multiple rows (here rows 2, 4):
julia> newarray = array[setdiff(1:end, (2,4)), :]
2×4 Array{Int64,2}:
1 2 3 4
9 10 11 12
To delete multiple columns (here columns 2, 4):
julia> newarray = array[:, setdiff(1:end, (2,4))]
4×2 Array{Int64,2}:
1 3
5 7
9 11
13 15
To delete a single row and multiple columns (here row 4 and columns 3, 4):
julia> newarray = array[1:end .!= 4, setdiff(1:end, (3,4))]
3×2 Array{Int64,2}:
1 2
5 6
9 10
# or
julia> newarray = array[setdiff(1:end, 4), setdiff(1:end, (3,4))]
3×2 Array{Int64,2}:
1 2
5 6
9 10
# or
julia> newarray = array[setdiff(1:end, (4,)), setdiff(1:end, (3,4))]
3×2 Array{Int64,2}:
1 2
5 6
9 10
To delete multiple rows and columns (here rows 1, 2 and columns 3, 4):
julia> newarray = array[setdiff(1:end, (1,2)), setdiff(1:end, (3,4))]
2×2 Array{Int64,2}:
9 10
13 14

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.

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

How to find a row or column under specific conditions in a matrix in R [duplicate]

This question already has answers here:
given value of matrix, getting it's coordinate
(2 answers)
Closed 7 years ago.
For example, if we have a matrix or say array with the following format
How can we find the index of rows or columns which only have numbers between 10 to 20 inside ?
M = array(c(1,1,12,34,0,19,15,1,0,17,12,0,21,1,11,1), dim=c(4,4))
And, also, I am not allowed to use for or while loops to do this.
Another thing is that the matrix or array may have a more than 2 dimensions. if the method can also apply to multi-dimensional matrix or array, it will be better for me. Thanks.
Instead of trying to find the index of qualified single elements, I need to find those rows or columns in which all the elements are between the interval.
In this example, I hope to have a result telling me that Row number 3 is a row that all the numbers within this row are between 10 to 20.
Use which(..., arr.ind = TRUE). Here I assume between means 10 and 20 are non-inclusive
which(M > 10 & M < 20, arr.ind = TRUE)
# row col
# [1,] 3 1
# [2,] 2 2
# [3,] 3 2
# [4,] 2 3
# [5,] 3 3
# [6,] 3 4
This will also work on 3-dimensional arrays (and higher).
## Three dimensions
dim(M) <- c(2, 4, 2)
which(M > 10 & M < 20, arr.ind = TRUE)
# dim1 dim2 dim3
# [1,] 1 2 1
# [2,] 2 3 1
# [3,] 1 4 1
# [4,] 2 1 2
# [5,] 1 2 2
# [6,] 1 4 2
## Four dimensions
dim(M) <- rep(2, 4)
which(M > 10 & M < 20, arr.ind = TRUE)
# dim1 dim2 dim3 dim4
# [1,] 1 2 1 1
# [2,] 2 1 2 1
# [3,] 1 2 2 1
# [4,] 2 1 1 2
# [5,] 1 2 1 2
# [6,] 1 2 2 2
## ... and so on
Note: To include 10 and 20, just use M >= 10 & M <= 20
Data:
M <- structure(c(1, 1, 12, 34, 0, 19, 15, 1, 0, 17, 12, 0, 21, 1,
11, 1), .Dim = c(4L, 4L))
Update: From your edit, you can find the row numbers for which all values are between 10 and 20 with
which(rowSums(M >= 10 & M <= 20) == ncol(M))
# [1] 3

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

Resources