Comparaison de plusieurs matrices contenues dans une liste

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Chloé Magnin
Messages : 16
Enregistré le : 24 Avr 2017, 06:45

Comparaison de plusieurs matrices contenues dans une liste

Messagepar Chloé Magnin » 17 Mai 2017, 07:14

Bonjour,

Je souhaiterais comparer chaque élément de plusieurs matrices de même dimension d'une même liste.
Le but étant de simuler aléatoirement (avec sample()) une matrice(i) si celle-ci a un élément positionner au même endroit que cet élément dans la matrice (i+1).

Pour être plus clair, je démarre avec un vecteur de type :

Code : Tout sélectionner

Var<-factor(Variety)
V1  V2  V3  V4  V5  V6  V7  V8  V9  V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20

Je créer ensuite la liste suivante:

Code : Tout sélectionner

list_mat<-vector("list",length(file2$Repetition))
for (i in 1:length(list_mat)){
  list_mat[[i]]<-matrix(sample(Var),nrow=5,ncol=4)
  }


qui donne:

Code : Tout sélectionner

[[1]]
     [,1]  [,2]  [,3]  [,4]
[1,] "V4"  "V13" "V20" "V19"
[2,] "V18" "V11" "V14" "V10"
[3,] "V7"  "V1"  "V3"  "V12"
[4,] "V15" "V5"  "V9"  "V6"
[5,] "V2"  "V17" "V8"  "V16"

[[2]]
     [,1]  [,2]  [,3]  [,4]
[1,] "V12" "V20" "V11" "V18"
[2,] "V13" "V9"  "V19" "V16"
[3,] "V17" "V1"  "V15" "V6"
[4,] "V2"  "V3"  "V8"  "V5"
[5,] "V10" "V4"  "V14" "V7"

[[3]]
     [,1]  [,2]  [,3]  [,4]
[1,] "V3"  "V16" "V11" "V5"
[2,] "V12" "V20" "V1"  "V17"
[3,] "V7"  "V6"  "V14" "V8"
[4,] "V9"  "V18" "V2"  "V15"
[5,] "V13" "V10" "V19" "V4"

[[4]]
     [,1]  [,2]  [,3]  [,4]
[1,] "V11" "V14" "V4"  "V13"
[2,] "V8"  "V2"  "V7"  "V17"
[3,] "V20" "V5"  "V12" "V3"
[4,] "V10" "V16" "V18" "V1"
[5,] "V6"  "V19" "V9"  "V15"


Je voudrait comparer chaque élément de chaque matrice.
Si, par exemple, "V4" de list_mat[[1]] a les mêmes coordonées que le "V4" de list_mat[[2]], ou de list_mat[[3]], ou de list_mat[[4]], alors list_mat[[1]] doit être de nouveau simuler. Cela pour chaque élément de chaque matrice.

J'espère avoir été assez claire et que vous pourrez m'aider.

Merci d'avance pour votre aide!

Cordialement,

Chloé

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Gabriel Terraz » 17 Mai 2017, 07:40

Bonjour,

Sous réserve d'avoir tout compris, je te propose ceci :

On simule les matrice :

Code : Tout sélectionner

mats <- replicate(3, matrix(sample(vec, 20), nrow =4), simplify = F)


On teste deux à deux toutes les matrices, si une seule des 20 positions est identique, la fonction renvoie TRUE

Code : Tout sélectionner

test <- combn(1:3,2, function(x) any(mats[[x[1]]] == mats[[x[2]]]))


Si une seule des valeurs de test est TRUE, on se lance dans la boucle suivante pour changer les matrices correspondantes

Code : Tout sélectionner

while(any(test)){
 newmats <- replicate(sum(test), matrix(sample(vec, 20), nrow =4), simplify = F)
mats[test] <- newmats

test <- combn(1:3,2, function(x) any(mats[[x[1]]] == mats[[x[2]]]))
 }


Sauf erreur de ma part, cela fonctionne mais je ne suis pas sûr que cela soit la meilleure stratégie...

Chloé Magnin
Messages : 16
Enregistré le : 24 Avr 2017, 06:45

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Chloé Magnin » 17 Mai 2017, 08:48

Merci Gabriel !

Même si ce n'est peut-être pas la meilleurs stratégie, ça fonctionne.

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Gabriel Terraz » 17 Mai 2017, 12:57

Resalut,
Je viens de me rendre compte qu'il a un petit souci dans mon code.
L'objet test contient les résultats des comparaisons des matrices deux à deux :

Code : Tout sélectionner

combn(1:3,2)
     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    3    3

Or, dans mon code je ne remplace pas forcément les bonnes matrices. Par exemple si les matrices 1 et 3 ont une valeur en commun, test aura pour valeur :

Code : Tout sélectionner

FALSE TRUE FALSE


Le code va donc remplacer la matrice 2 et non pas les matrices 1 et 3. Il faut donc rajouter un petit quelque chose !

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Gabriel Terraz » 17 Mai 2017, 13:04

Voici donc une nouvelle version :

Code : Tout sélectionner

vec <- 1:20
mats <- replicate(3, matrix(sample(vec, 20), nrow =4), simplify = F)
comparaisons <- combn(1:3,2)
test <- apply(comparaisons, 2, function(x) any(mats[[x[1]]] == mats[[x[2]]]))

while(any(test)){
newmatsindex <- unique(comparaisons[1, test])
newmats <- replicate(length(newmatsindex), matrix(sample(vec, 20), nrow =4), simplify = F)
mats[newmatsindex] <- newmats

test <- combn(1:3,2, function(x) any(mats[[x[1]]] == mats[[x[2]]]))
 }

Chloé Magnin
Messages : 16
Enregistré le : 24 Avr 2017, 06:45

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Chloé Magnin » 17 Mai 2017, 15:46

Merci pour la correction.
La longueur du vecteur test correspondait bien aux nombre de comparaisons à réaliser, et j'avoue avoir seulement vérifier si les commandes marchaient pour deux matrices, d'où le "loupage" du problème que tu as relevé...

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Logez Maxime » 18 Mai 2017, 08:15

Bonjour,

pour savoir si les valeurs de la première matrice correspondent à au moins une des autres matrices alors tu peux faire comme ça :

Code : Tout sélectionner

# avec l1 la liste qui contient les matrices
# toutes les comparaisons d'un seul coup
any(rowSums(c(l1[[1]]) == sapply(l1[-1], c))==1)
Cordialement,
Maxime

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Pierre-Yves Berrard » 18 Mai 2017, 09:01

Ingénieux ! (je mettrais juste > 0 au lieu de == 1)
PY

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Gabriel Terraz » 18 Mai 2017, 09:20

Par contre, si je ne me trompe pas, tu ne compares pas la 2 à la 3, etc. Seulement la 1 à toute les autres ?

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Logez Maxime » 18 Mai 2017, 09:56

re,

tout à fait ! en plus on peut s'éviter le rowSums :

Code : Tout sélectionner

l2 <- unlist(l1)
dim(l2) <- c(length(l1[[1]]), length(l1))
nc <- ncol(l2)
res <- logical(nc-1)
for (i in 1:(ncol(l2)-1)) res[i] <- any(l2[,i] == l2[,(i+1):nc])
Normalement c'est encore mieux. Ici on ne teste pas à chaque fois la ième colonne contre toutes les autres mais la ième colonne contre les suivantes. En considérant que la 5ème matrice n'a pas besoin d'être changé. Donc on ne doit changer que les 3 premières et conserver les 2 dernières.

Cordialement,
Maxime

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Mickael Canouil » 19 Mai 2017, 09:16

Bonjour,

voici ma proposition (pas forcément optimale, notamment quand le nombre de matrices dans "l1" augmente)

Code : Tout sélectionner

vec <- 1:20
l1 <- replicate(3, matrix(sample(vec, 20), nrow = 4), simplify = FALSE)

l1.tmp <- do.call("cbind", lapply(l1, as.vector))
iter <- 0
while(any((cond <- rowSums(apply(l1.tmp, 1, duplicated)))!=0) & iter<=200) {
  l1.tmp[, which.max(cond)] <- sample(l1.tmp[, which.max(cond)])
  iter <- iter+1
}
l1.unique <- lapply(seq_len(ncol(l1.tmp)), function (icol) {
  matrix(l1.tmp[, icol], nrow = 4)
})
Mickaël
mickael.canouil.fr | rlille.fr

Chloé Magnin
Messages : 16
Enregistré le : 24 Avr 2017, 06:45

Re: Comparaison de plusieurs matrices contenues dans une liste

Messagepar Chloé Magnin » 22 Mai 2017, 07:24

Bonjour,

Merci à vous tous, vous m'avez été d'une grande aide!!

Chloé


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité