Matrix - select all except specified indices
I know that you can directly select the indices of the required matrix:
mat <- matrix(1:6,ncol=3)
select <- matrix(c(1,2,1,2,3,3),ncol=2)
colnames(select) = c("row","col")
mat[select]
#[1] 3 6 5
Is there a way in R to select all elements in a matrix except for certain indices? This is convenient for vectors with LETTERS[-1]
. Ideally I could do something like mat[-select]
, but when I try this I get:
mat[-select]
#Error in mat[-select] :
# negative values are not allowed in a matrix subscript
What I have tried:
library(dplyr)
all_ind <- expand.grid(row=1:nrow(mat),col=1:ncol(mat))
keep<-anti_join(all_ind,as.data.frame(select))
mat[as.matrix(keep)]
#[1] 4 2 1
It works, but it takes some coercion and connection, which is not ideal. It might just be me, but I couldn't find any easy approaches to this.
source to share
Here's one way, still pretty confusing:
dplyr::anti_join(
reshape2::melt(mat),
as.data.frame(select),
by=c(Var1 = "row", Var2 = "col")
)$value
# [1] 4 2 1
I use reshape2:::melt.matrix
it because I think "the verse has no analogue at the moment".
Alternatively, the math converts from matrix (or array) indices back to vector indices:
mat[ - (select[,"row"] + (select[,"col"]-1)*nrow(mat)) ]
# [1] 1 2 4
source to share
setdiff(mat, mat[select])
#[1] 1 2 4
#Will most likely NOT WORK if there are duplicated values
Perhaps a workaround could be to create another matrix ( ind
) with the same dimension as mat
but with indices as its values. Then use the same approach as above
mat <- matrix(6:11,ncol=3) #NOTE this is different than in question
select <- matrix(c(1,2,1,2,3,3),ncol=2)
ind = matrix(1:length(mat), ncol = 3)
mat[setdiff(ind, ind[select])]
#[1] 6 7 9
source to share