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.

+3


source to share


2 answers


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

      

+3


source


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

      

+1


source







All Articles