Я знаю, что вы можете напрямую выбрать индексы матрицы, которую вы хотите, выполнив:

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

Есть ли способ в R выбрать все элементы в матрице, кроме конкретных индексов? Это легко разрешается для векторов с LETTERS[-1]. В идеале я мог бы сделать что-то вроде mat[-select], но при этом я получаю:

mat[-select]
#Error in mat[-select] : 
#  negative values are not allowed in a matrix subscript

Что я пробовал:

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

Это работает, но требует некоторого принуждения и присоединения, что не идеально. Может быть, это только я, но я не мог найти легкий подход к этому.

3
Mike H. 3 Апр 2017 в 23:44

2 ответа

Лучший ответ

Вот один способ, все еще довольно запутанный:

dplyr::anti_join(
  reshape2::melt(mat),
  as.data.frame(select),
  by=c(Var1 = "row", Var2 = "col")
)$value
# [1] 4 2 1

Я использую reshape2:::melt.matrix, так как полагаю, что у стиха на данный момент нет аналогов.


В качестве альтернативы выполните математические вычисления для преобразования индексов матрицы (или массива) обратно в векторные индексы:

mat[ - (select[,"row"] + (select[,"col"]-1)*nrow(mat)) ]
# [1] 1 2 4
3
Frank 3 Апр 2017 в 21:07
setdiff(mat, mat[select])
#[1] 1 2 4
#Will most likely NOT WORK if there are duplicated values

Возможно, в качестве обходного пути можно создать другую матрицу (ind) с тем же размером, что и mat, но с индексами в качестве значений. Затем используйте тот же подход, что и выше

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
d.b 4 Апр 2017 в 02:35