8
votes

Comment vérifier efficacement si une matrice est sous forme binaire (par exemple, tous les 1 ou 0's)?

J'ai une fonction qui prend une matrice binaire M x N (potentiellement) en entrée, et j'aimerais retourner une manipulation d'erreur si la matrice contient un chiffre qui n'est pas 0 ou 1, ou est Na. Comment puis-je vérifier cela efficacement?

Par exemple, en générant des données pour un 10 x 10: p>

for(i in 1:nrow(mat))
{
    for(j in 1:ncol(mat))
    {
      if(is.na(mat[i,j])|(!(mat[i,j] == 1 | mat[i,j] == 0)))
      {
        stop("Data must be only 0s, 1s")
      }
    }
}


2 commentaires

Une façon garantie de demander beaucoup de réponses est de demander que quelque chose soit fait plus vite dans R;)


@ Señoro "'parce qu'il va la la distance , il va pour vitesse , ..." :-)


5 Réponses :


3
votes

Un moyen assez efficace (et lisible ) pourrait être xxx

Cependant, comme indiqué, il peut ne pas être le plus rapide, si par rapport à d'autres solutions. < / p>

mais, pour ajouter quelques-uns, si efficacité est un must (par exemple, vous faites ce test beaucoup de fois) un beaucoup de gain est donné en travaillant avec entier matrice ( Double S avoir plus d'octets) et vérifiez contre les valeurs INTEGER . Ce gain pourrait également s'appliquer à d'autres solutions également. Quelques tests avec % en% Suivre: xxx

de 3,70 à 1,32 est pas ce mauvais :)


0 commentaires

5
votes

Voici des horaires pour quelques options (y compris les options suggérées dans d'autres réponses):

stopifnot(sum(mat==0) + sum(mat==1) == length(mat))


3 commentaires

Le premier et le troisième pourrait être déraillé par NAS


En effet, la première est facilement corrigée en ajoutant na.rm = t comme argument sur les fonctions Somme , et semble toujours être le plus rapide des trois avec ce une addition. Merci pour la solution!


Les trois options fonctionnent correctement dans R 3.0.1 lorsqu'un Na est inséré dans la matrice.



4
votes

J'aime ajouter une version légèrement modifiée de la comparaison basée sur la somme plus rapide que la version de @ Jamestrimble. J'espère que toutes mes hypothèses sont correctes: xxx

ici la référence: xxx


0 commentaires

5
votes

J'ai immédiatement pensé à identique (tapis, matrice (AS.numérique (AS.Logical (Tapis), NR = NROW (MAT)))) >

Ce laisse NA Comme NA code> Donc, si vous souhaitez identifier l'existence d'une telle, vous aurez juste besoin d'un rapide tout (is.na (mat)) code> ou test similaire. p>

EDIT: TRIME ESSAI P>

notfun <- function(mat) try(stopifnot(sum(mat==0) + sum(mat==1) == length(mat)))
 microbenchmark(fun1(mfoo),notfun(mfoo),is.binary.sum2(mfoo),times=10)
Error : sum(mat == 0) + sum(mat == 1) == length(mat) is not TRUE
##error repeated 10x for the 10 trials
Unit: milliseconds
                 expr       min        lq    median        uq
           fun1(mfoo)  4.870653  4.978414  5.057524  5.268344
         notfun(mfoo) 18.149273 18.685942 18.942518 19.241856
 is.binary.sum2(mfoo) 11.428713 12.145842 12.516165 12.605111
       max neval
  5.438111    10
 34.826230    10
 13.090465    10


4 commentaires

IMHO ça ne marche pas: identique (C (1L, 0L), as.logique (C (1L, 0L))) (Pour convertir la matrice en un vecteur entier crée de faux positifs: identique (AS.Integer (C (1.1, 0)), AS.Integer (AS.Logical (C (1.1, 0)))) )


@SGIBB - Attendez, je pense que je l'ai réparé: as.numeric (as.logical (tapis)) semble être ok pour moi.


@Carl excellent! Ceci est clair, concis, efficace et semble fonctionner correctement dans tous les cas. Merci!


@Carlwitthoft: Oui, génial! J'aime vraiment cette solution simple et claire!



1
votes

Remarque, j'ai changé quelques éléments afin qu'il fonctionne dans octave , mais il devrait être assez similaire à matlab .

générer la matrice: xxx

Nous faisons maintenant quelque chose de simple, nous savons que 1 * 2-1 rendrait le 1 égal à 1 , alors qu'il fait 0 égal à -1 . Ainsi, ABS fait tout de même. Pour toute autre valeur, dites -1 , -1 * 2-1 = -3 Ce n'est pas le cas. Ensuite, nous soustrayons 1 et nous devrions rester avec une matrice avec seulement des zéros. Cela peut être facilement vérifié dans matlab / octave avec tout : xxx

vérifier sa vitesse: xxx

Dans l'ordre Total , utilisateur et système heure.

assez décent sous 0,18 < / code> secondes avec la plupart d'entre eux en mode utilisateur. Avec 10.000 * 10.000 Entrées, il est toujours sous une seconde, climatisant à 0,86 secondes sur mon système.

oh, diable, je ne vois que maintenant Il est en fait demandé à r , pas matlab . J'espère que quelqu'un aime la comparaison cependant.

Gestion NaN est facile dans octave / MATLAB avec ISNAN (MAT) , éventuellement sous la forme de tout (tout (ISNAN (tapis))) si vous le souhaitez. Cela inclut les valeurs NA . Manipulation uniquement NA Valeurs passe par iSNA (tapis) .


2 commentaires

Comment cette poignée na est-elle?


@Carlwitthoft, désolé Carl, je l'ai ajouté