Gostaria de identificar todas as linhas em um data frame (ou matriz) cujos valores nas colunas 1 e 2 correspondem a um par específico. Por exemplo, se eu tiver uma matriz
testmat=rbind(c(1,1),c(1,2),c(1,4),c(2,1),c(2,4),c(3,4),c(3,10))
Gostaria de identificar as linhas que contêm qualquer um dos seguintes pares, ou seja, todas as linhas que contêm uma combinação de 1,2 ou 2,4 em suas primeira e segunda colunas
of_interest = rbind(c(1,2),c(2,4))
O seguinte não funciona
which(testmat[,1] %in% of_interest[,1] & testmat[,2] %in% of_interest[,2])
porque, como esperado, ele retorna todas as combinações de 1,2 na primeira coluna e 2,4 na segunda (ou seja, linhas 2,3,5 em vez de apenas as linhas 2 e 5, como desejado), de modo que a linha [1,4] é incluída, mesmo que este não seja um dos pares que estou consultando. Deve haver alguma maneira simples de usar which...%in%... para corresponder a pares específicos como este, mas não consegui encontrar um exemplo disso que funcione.
Observe que preciso das posições/números de linhas que correspondem à condição desejada.
Abordagem padrão
Eu assumo que, como você está usando,
which()
você quer a posição, em vez de apenas se há uma correspondência. Você podecbind()
o número da linha paratestmat
e entãomerge()
isto comof_interest
.Rcpp
abordagem com matriz muito grandeVocê mencionou em seu comentário que tem
10e8
linhas. Isso me faz pensar em duas coisas:merge()
isso, pois isso forçará as matrizes a quadros de dados, ou seja, copiará cada coluna em um vetor contíguo à memória, o que será muito caro.of_interest
também for grande, você quer quebrar o loop o mais cedo possível assim que a correspondência for encontrada, em vez de continuar a iterar. Veja esta pergunta para vantagens de desempenho.Dado isso, eu evitaria usar
which()
ou outras abordagens que não saiam cedo. Aqui está umRcpp
código que deve ser muito mais rápido do quemerge()
com grandes conjuntos de dados:Acho que acessar linhas como submatrizes é um código mais idiomático
Rcpp
do que um for-loop duplo com indexação de matriz, mas não tenho ideia de qual é mais rápido, então se o desempenho for sua principal preocupação, eu tentaria várias abordagens e faria um benchmark.Aqui está uma abordagem com
which
+asplit
o que pode ser um pouco ineficiente devido a
aplist
, mas deve funcionar bem para pequenos conjuntos de dados se a velocidade não for uma das suas preocupações.Você poderia usar
paste()
os valores do seu exemplo (testmat e of_interest) em um único valor e então fazer uma%in%
avaliação. Por exemplo:Se
%in%
não for rápido o suficiente para você, considere tentar%fin%
oufmatch()
comofastmatch
uma alternativa mais rápida para%in%
.Podemos usar
row.names()
+{ivs}
.Configurar:
Índice,
comparar,
e indexar novamente: