2010-11-27 13 views
1

Je ne peux pas croire que cela me prenne autant de temps à comprendre, et je n'arrive toujours pas à le comprendre.Vérifiez qu'un vecteur est contenu dans une matrice dans R

Je dois conserver une collection de vecteurs, et vérifier plus tard qu'un certain vecteur est dans cette collection. J'ai essayé des listes combinées avec %in% mais cela ne semble pas fonctionner correctement.

Mon idée suivante était de créer une matrice et rbind vecteurs à elle, mais maintenant je ne sais pas comment vérifier si un vecteur est contenu dans une matrice. %in semble comparer les ensembles et non les lignes exactes. La même chose semble s'appliquer à l'intersection.

Aide très appréciée!

+0

Et quelle est la s'il vous plaît langage de programmation? – kellogs

+0

La langue est R. – dmkc

Répondre

7

Voulez-vous dire comme ceci:

wantVec <- c(3,1,2) 
myList <- list(A = c(1:3), B = c(3,1,2), C = c(2,3,1)) 
sapply(myList, function(x, want) isTRUE(all.equal(x, want)), wantVec) 
## or, is the vector in the set? 
any(sapply(myList, function(x, want) isTRUE(all.equal(x, want)), wantVec)) 

Nous pouvons faire la même chose avec une matrice:

myMat <- matrix(unlist(myList), ncol = 3, byrow = TRUE) 
## As the vectors are now in the rows, we use apply over the rows 
apply(myMat, 1, function(x, want) isTRUE(all.equal(x, want)), wantVec) 
## or 
any(apply(myMat, 1, function(x, want) isTRUE(all.equal(x, want)), wantVec)) 

Ou par des colonnes:

myMat2 <- matrix(unlist(myList), ncol = 3) 
## As the vectors are now in the cols, we use apply over the cols 
apply(myMat, 2, function(x, want) isTRUE(all.equal(x, want)), wantVec) 
## or 
any(apply(myMat, 2, function(x, want) isTRUE(all.equal(x, want)), wantVec)) 

Si vous devez faire cela beaucoup, écrivez votre propre fonction

vecMatch <- function(x, want) { 
    isTRUE(all.equal(x, want)) 
} 

Ensuite, utilisez-le, par ex. sur la liste myList:

> sapply(myList, vecMatch, wantVec) 
    A  B  C 
FALSE TRUE FALSE 
> any(sapply(myList, vecMatch, wantVec)) 
[1] TRUE 

Ou même envelopper le tout:

vecMatch <- function(x, want) { 
    out <- sapply(x, function(x, want) isTRUE(all.equal(x, want)), want) 
    any(out) 
} 

> vecMatch(myList, wantVec) 
[1] TRUE 
> vecMatch(myList, 5:3) 
[1] FALSE 

EDIT: commentaire rapide pourquoi je isTRUE() enroulé autour des all.equal() appels. Cela est dû au fait que lorsque les deux arguments sont pas égale, all.equal() ne renvoie pas une valeur logique (FALSE):

> all.equal(1:3, c(3,2,1)) 
[1] "Mean relative difference: 1" 

isTRUE() est ici utile, car elle retourne TRUE ssi il est l'argument est TRUE, alors qu'il renvoie FALSE si c'est autre chose.

0
> M 
    [,1] [,2] [,3] 
[1,] 1 4 7 
[2,] 2 5 8 
[3,] 3 6 9 


v <- c(2, 5, 8) 

vérifier chaque colonne:

c1 <- which(M[, 1] == v[1]) 
c2 <- which(M[, 2] == v[2]) 
c3 <- which(M[, 3] == v[3]) 

Voici un moyen d'utiliser encore Intersection() sur plus de 2 éléments

> intersect(intersect(c1, c2), c3) 

[1] 2