[Réglé] Comparaison de valeur de deux fichiers

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

Vincent BONNAL
Messages : 12
Enregistré le : 17 Déc 2004, 10:07
Contact :

[Réglé] Comparaison de valeur de deux fichiers

Messagepar Vincent BONNAL » 22 Mar 2007, 08:24

Bonjour,

J'essaye de faire une comparaison du contenu de deux fichiers.

Le premier est ValBornage.txt qui contient le nom et les bornes min/max de n variables (ici 3, une ligne par variable, séparateur tabulation, colonne 4 et 5 correspondant aux valeurs min et max).

Le second fichier ValBornageSim.txt contient les valeurs simulées que je souhaite comparer aux bornes pour savoir si les valeur simulées sont ou non dans les bornes mentionnées dans Valbornage.txt.

J'ai écris un petit script R, mais je pense me planter quelque part dans les transtypage (l'exemple donné ne concerne que la borne min, mais c'est mauvais aussi pour mon test de borne max).

Voici le résultat sous R de mon script. J'affiche les résultats intermédiaires pour plus d'aisance dans la compréhension.

Code : Tout sélectionner

> # récupération des bornes du fichier ValBornage.txt
> bornes<-read.table("ValBornage.txt", dec="," ,sep="\t", header = FALSE )
> bornes<-as.matrix(bornes[,4:5])
> bornes<-t(matrix(as.double(bornes),ncol=2))
> bornes
     [,1] [,2] [,3]
[1,]    0    2    1
[2,] 1500   15    3
>
> # on compte et adapte le nombre de variables du fichier
> nbvar <-3+length(bornes[1,])
>
> # on récupère les valeurs de simulation du fichier ValBornageSim.txt
> valBornageSim<-as.matrix(read.table("ValBornageSim.txt", dec="," ,sep="\t", header = FALSE))[,4:nbvar]
> valBornageSim<-matrix(as.double(valBornageSim),ncol=nbvar-3)
> valBornageSim
          [,1] [,2] [,3]
 [1,] 3515.664    0    9
 [2,] 2613.000   16    0
 [3,] 4888.900    0    0
 [4,]       NA    0    0
 [5,] 7637.800    0    7
 [6,]  -10.000    0    0
 [7,] 6197.700    0    0
 [8,] 2532.190    5    0
 [9,] 2182.580    0   NA
[10,]  604.530    0    0
[11,] 2117.000    0   -5
[12,] 3873.700    0    0
>
> # Les bornes min sont sur la première ligne de bornes (car transposée au début)
> valBornageSim >= bornes[1,]
       [,1]  [,2]  [,3]
 [1,]  TRUE  TRUE  TRUE
 [2,]  TRUE  TRUE FALSE
 [3,]  TRUE FALSE FALSE
 [4,]    NA  TRUE  TRUE
 [5,]  TRUE FALSE  TRUE
 [6,] FALSE FALSE FALSE
 [7,]  TRUE  TRUE  TRUE
 [8,]  TRUE  TRUE FALSE
 [9,]  TRUE FALSE    NA
[10,]  TRUE  TRUE  TRUE
[11,]  TRUE FALSE FALSE
[12,]  TRUE FALSE FALSE


Là, dès ma première ligne, c'est incorrect. En effet, lors de la comparaison valBornageSim >= bornes[1,] à la valeur [1,2], je devrais avoir FALSE car 0 est inférieur à 2... enfin.. je crois.

Y'a t'il une bonne âme charitable qui pourrait m'éclairer sur le biais de ce script?

Merci d'avance...
Vincent BONNAL
CIRAD Bios - UPR 59 Ecotrop

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

Messagepar Logez Maxime » 22 Mar 2007, 09:59

Bonjour,

je pense que ceci devrait t'aider :

Code : Tout sélectionner

test <- matrix(rpois(15,3),5,3)
test
     [,1] [,2] [,3]
[1,]    7    4    3
[2,]    6    2    4
[3,]    2    4    4
[4,]    2    2    4
[5,]    4    3    2
borne <- matrix(c(3,5,0,7,1,2),2,3)
borne
     [,1] [,2] [,3]
[1,]    3    0    1
[2,]    5    7    2
ted <- NULL
for (i in 1:ncol(test)){
   ted <- cbind(ted,test[,i]>=borne[1,i] & test[,i]<=borne[2,i])
   }
ted
      [,1] [,2]  [,3]
[1,] FALSE TRUE FALSE
[2,] FALSE TRUE FALSE
[3,] FALSE TRUE FALSE
[4,] FALSE TRUE FALSE
[5,]  TRUE TRUE  TRUE

Si borne reprsénte en colonne les valeurs minimales et maximales (première ligne les min, deuxième ligne les max), le premier biais vient de >= car la tu vas chercher à savoir si tes valeurs sont supérieures à tes bornes, alors que si tu veux savoir si elles sont comprises ou non dans un intervalle il faut qu'elle soit supérieure à la minimale et inférieure à la maximale. Et ce qu'il faut savoir c'est que ici tu vas comparer toutes tes valeurs de valBornageSim avec trois valeurs donc tu compares 36 valeurs à 3 valeurs et R le fait de façon séquentielle donc il va recycler tes valeurs : il compare la 1ère valeure de valBornageSim à la 1ère valeur de bornes[1,], la 2ème de valBornageSim à la 2ème de bornes[1,], la 3ème de valBornageSim à la 3ème de bornes[1,], mais la comme la il n'a pas 4 valeurs dans bornes[1,] il va comparer la 4ème de valBornageSim avec la 1ère de bornes[1,] etc ...
Pour corriger ça tu peux procéder comme ceci :

Code : Tout sélectionner

sweep(test,2,borne[1,],">=") # correction sweep et non pas swepp
      [,1] [,2] [,3]
[1,]  TRUE TRUE TRUE
[2,]  TRUE TRUE TRUE
[3,] FALSE TRUE TRUE
[4,] FALSE TRUE TRUE
[5,]  TRUE TRUE TRUE

Et la tu vas comparer les valeurs de ta première colonne de valBornageSim avec la première valeurs de bornes[1,], etc. Tu peux faire la même chose avec les bornes supérieures et regarder si tes valeurs par colonne sont inférieures à ces bones.

Maxime

Vincent BONNAL
Messages : 12
Enregistré le : 17 Déc 2004, 10:07
Contact :

Messagepar Vincent BONNAL » 23 Mar 2007, 12:09

Logez Maxime a écrit :il va recycler tes valeurs : il compare la 1ère valeure de valBornageSim à la 1ère valeur de bornes[1,], la 2ème de valBornageSim à la 2ème de bornes[1,], la 3ème de valBornageSim à la 3ème de bornes[1,], mais la comme la il n'a pas 4 valeurs dans bornes[1,] il va comparer la 4ème de valBornageSim avec la 1ère de bornes[1,] etc

Ah... en effet, c'est surtout ça le problème... (je ne le savais pas...)

Bon, je regarde (j'essaye de comprendre surtout) ton code et les fonctions utilisées. Je te tiens au courant.

Merci.
Vincent BONNAL

CIRAD Bios - UPR 59 Ecotrop

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

Messagepar Logez Maxime » 26 Mar 2007, 09:48

Bonjour,


Juste un petit code un peu plus "rapide" que la boucle et qui parvient au même résultat :

Code : Tout sélectionner

tedinf <- sweep(test,2,borne[1,],">=") # on regarde si les valeus sont supérieures à la valeur minimale
tedsup <- sweep(test,2,borne[2,],"<=") # regarde si les valeurs sont inférieures à la valeur maximale
tedint <- tedinf & tedsup # les valeurs sont dans l'intervale si elles sont vraies pour les deux conditions
tedsup
     [,1] [,2]  [,3]
[1,] TRUE TRUE  TRUE
[2,] TRUE TRUE FALSE
[3,] TRUE TRUE  TRUE
[4,] TRUE TRUE FALSE
[5,] TRUE TRUE  TRUE
tedinf
      [,1] [,2] [,3]
[1,] FALSE TRUE TRUE
[2,] FALSE TRUE TRUE
[3,]  TRUE TRUE TRUE
[4,]  TRUE TRUE TRUE
[5,]  TRUE TRUE TRUE
tedint
tedint
      [,1] [,2]  [,3]
[1,] FALSE TRUE  TRUE
[2,] FALSE TRUE FALSE
[3,]  TRUE TRUE  TRUE
[4,]  TRUE TRUE FALSE
[5,]  TRUE TRUE  TRUE
# le résultat provient du fait suivant :
FALSE & FALSE
[1] FALSE
FALSE & TRUE
[1] FALSE
TRUE & FALSE
[1] FALSE
TRUE & TRUE
[1] TRUE

Le temps de calcul sera moins important que dans le cas de la boucle, même si cette différence sera visible uniquement sur de très grosses matrices.

Maxime

Vincent BONNAL
Messages : 12
Enregistré le : 17 Déc 2004, 10:07
Contact :

Messagepar Vincent BONNAL » 27 Mar 2007, 08:27

Et bien c'est parfait.
Voilà mon code final pour tester qu'une matrice issue de ValBornageSim.txt soit dans les bornes de ValBornage.txt
ValBornage.txt a écrit :96 BiomasseAerienne Resjour 530,540467 6000
97 BiomasseFeuilles Resjour 200 900
109 Rdt Resjour 0 1330

ValBornageSim.txt a écrit :NA NA 18/07/1996 NA NA NA
NA NA 19/07/1996 0 0 0
NA NA 20/07/1996 0 0 0
NA NA 21/07/1996 0 0 0
NA NA 22/07/1996 0,092595 0,05092725 0
NA NA 23/07/1996 0,117533001772278 10 0
NA NA 24/07/1996 7,0044424758087 10 0
NA NA 25/07/1996 13,2403944843402 10 0
NA NA 26/07/1996 21,1319442672686 11,5928264452192 0
NA NA 27/07/1996 28,6307724879616 15,6923579643787 0
NA NA 28/07/1996 35,6595611161554 19,5281549659083 0
NA NA 29/07/1996 45,3955742938564 24,8305562487769 0
NA NA 30/07/1996 57,2134916652196 31,2499796472417 0
NA NA 31/07/1996 66,4192865181179 36,2377634064112 0
NA NA 01/08/1996 80,9697215823929 44,0986105316304 0


et le code de ma fonction:

Code : Tout sélectionner

VerificationBornageSim <- function()
  {
  # récupération des bornes du fichier ValBornage.txt
  bornes<-t(as.matrix(read.table("ValBornage.txt", dec="," ,sep="\t", header = FALSE)[,4:5]))
  # récupération des bornes du fichier ValBornageSim.txt
  ValSim<-matrix(as.matrix(read.table("ValBornageSim.txt", dec="," ,sep="\t", header = FALSE)[4:(3+ncol(bornes))]),ncol=ncol(bornes))
  # comparaison du bornage via la fonction sweep (min:ligne 1, max:ligne 2)
  bornage<-sweep(ValSim,2,bornes[1,],">=") & sweep(ValSim,2,bornes[2,],"<=")
  # s'il existe une valeur à FALSE, on renvoi FALSE
  if (any(bornage==FALSE)) return(FALSE) else return(TRUE)
  }

# Utilisation de la fonction (qui renvoie TRUE ou FALSE)
VerificationBornageSim()

Bon, je pense qu'on pourrait améliorer encore (notament le if (any()...), mais c'est déjà très bien, le résultat est celui qu'il me faut.

Merci à vous deux pour cette superbe fonction sweep !
Vincent BONNAL

CIRAD Bios - UPR 59 Ecotrop

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

Messagepar Logez Maxime » 27 Mar 2007, 11:45

Bonjour,

Juste un petit truc concernant la dernière commande de ta fonction, tu peux remplacer if (any(bornage==FALSE)) return(FALSE) else return(TRUE) par return(all(test)) :

Code : Tout sélectionner

test
      [,1]  [,2]
[1,] FALSE  TRUE
[2,]  TRUE FALSE
if (any(test==FALSE)) print(FALSE) else print(TRUE)
[1] FALSE
all(test)
[1] FALSE
# si toutes les valeurs sont TRUE :
test
     [,1] [,2]
[1,] TRUE TRUE
[2,] TRUE TRUE
if (any(test==FALSE)) print(FALSE) else print(TRUE)
[1] TRUE
all(test)
[1] TRUE


Maxime

Vincent BONNAL
Messages : 12
Enregistré le : 17 Déc 2004, 10:07
Contact :

Messagepar Vincent BONNAL » 03 Avr 2007, 10:15

merci !

C'est ce qu'il y a de frustrant dans R quand on débute: écrire 10 lignes (au minimum) alors qu'on sait pertinemment que d’autre savent faire la même chose en une ligne…
Vincent BONNAL

CIRAD Bios - UPR 59 Ecotrop


Retourner vers « Questions en cours »

Qui est en ligne

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