banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Pour sa 21ème année, l’association GeoRezo a toujours besoin de vous !

10€ = 1 mois de frais bancaires ; 15€ = 12 mois de nom de domaine ; 30€ = 1 semaine de location des serveurs …

Faire un don 

Retrouver nos membres bienfaiteurs

#1 Wed 20 March 2002 11:48

Guillaume OLLIVIER
Invité

Synthese requete BDD : recherche des dominantes multiples

Bonjour et merci a tous ceux qui ont repondu a la question posee :

>>Je travaille sur un tableau de donnees de recouvrement avec les sp en
>colonne et les releves (facies de vegetation) en ligne, soit
>
>        spA | SpB| ...|Spn
>FaciesA  0.01 |  0 | ...| 0.2
>FaciesB    0 | 0.5 | ... | 0
>....        ... | ...  | ... | ...
>FaciesN   0.5 | 0.01|...| 0
>
>J'aimerai pouvoir connaitre pour chaque facies l'espece la plus
>abondante (voire les 3 premieres) de maniere automatique et que le code de
>cette ou ces especes apparaissent dans la ligne
>correspondant au facies, soit :
>
>        Sp la plus abondante
>FaciesA       Spn
>FaciesB       SpB
>...
>FaciesN      SpA
>
>Une telle requete est elle possible sous Access et avec quelle demarche ?
Et
>avec Excell ?? d'autres outils ???
>Faut il passer par du VB ...?

VOICI LA SOLUTION QUE J'AI MISE EN OEUVRE (SIMPLICITE, PAS DE
PROGRAMMATION...) :

>Claude MONTEIL
Sous Excel, les fonctions GRANDE.VALEUR, EQUIV et INDEX peuvent apporter une
reponse :

1/ calcul de la valeur la plus grande pour une ligne :
=GRANDE.VALEUR(:;1)
renvoie la valeur la plus grande de la ligne courante pour les colonnes B a
Z

2/ calcul de la position de cette valeur (indice) :
=EQUIV(;:;0)
renvoie la position de la valeur en colonne AA (valeur calculee en 1/)
au sein de la plage s'etendant sur les colonnes B a Z de la ligne courante

3/ calcul du nom de l'espece correspondante :
=INDEX(:wink
renvoie l'element de position indiquee dans le second parametre (valeur
calculee en 2/)
au sein de la plage specifiee comme 1er parametre (la liste des noms est
supposee etre sur la 1ere ligne (colonnes B a Z).

Le cas echeant, on peut chainer ces 3 calculs au sein d'une seule et meme
formule :
=INDEX(:;EQUIV(GRANDE.VALEUR(:;1);:;0)) (ouf:-)

Ces formules peuvent cependant etre plus lisibles si on prend soin de nommer
les plages utilisees, celle de la premiere ligne avec un nom absolu (ex. :
ListeNoms = smile, et celle de la ligne courante avec un nom relatif
(ex. : LigneCourante = :, a supposer qu'on definisse ce nom a partir
de la 2eme ligne) :
=INDEX(ListeNoms;EQUIV(GRANDE.VALEUR(LigneCourante;1);LigneCourante;0))
(ouf:-)

A noter que :
- il y a un ecueil si une valeur apparait PLUSIEURS FOIS, auquel cas on ne
recuperera la position (et le nom d'espece) que de la 1ere d'entre elles ...
- le second parametre de la fonction GRANDE.VALEUR permet d'atteindre la
seconde plus grande valeur de la plage (et ainsi de suite)

>>>RESTE A SAVOIR SI LA SUITE DE FONCTION NE PEUT PAS ETRE AMELIOREE POUR
AFFICHER LES ESPECES CO-DOMINANTES ????
______________

Les tableaux croises ne semblent pas etre la solution, il ne s'agit pas non
plus d'un regroupement simple sous un SGDB (cf retourner un nom de colonne
dans un enregistrement) au moins en l'etat de la structure de table
(restructuration souvent proposee :
Facies | sp | releve
A | A | 0.01
A | B | 0
A | n | 0.2
B | A | 0
mais difficile a mettre en oeuvre avec une table de 350x350)

AUTRES SOLUTIONS PROPOSEES MAIS NON TESTEES :

>>Daniel Chessel (Liste ADE) :
On peut faire ce que veut Guillaume OLLIVIER dans R :

avec une toute petite fonction :

fp_function(X) {
fun_function(x) {
x_unlist(x)
x1_which(x==max(x))[1]
x[x1]_-999
x2_which(x==max(x))[1]
x[x2]_-999
x3_which(x==max(x))[1]
return(names(X)[c(x1,x2,x3)])
}
z_t(apply(X,1,fun))
z_data.frame(z)
names(z)_c( Esp1 , Esp2 , Esp3 )
return(z)
}

Un tableau de donnees :
> X
Eda Bsp Brh Bni Bpu Cen Ecd Rhi Hla Hab Par Cae Eig
sp_1 4 7 10 9 0 0 0 5 9 0 4 0 0
sp_2 0 0 8 0 0 0 0 0 4 0 0 0 0
sp_3 0 5 5 0 0 0 0 2 5 0 0 0 0
sp_4 0 3 6 0 0 0 0 3 6 0 0 0 0
sp_5 0 5 6 0 0 0 5 0 4 0 0 0 4
su_1 6 7 10 0 10 0 0 2 7 0 0 0 2
su_2 0 0 9 0 0 0 0 0 0 0 0 0 0
su_3 0 6 8 0 0 2 0 0 0 0 0 0 0
su_4 0 7 11 0 0 2 0 0 2 0 0 5 5
su_5 0 6 9 2 3 0 4 0 0 0 0 2 7
au_1 4 5 8 0 9 6 0 5 9 0 7 0 0
au_2 0 0 1 0 0 0 0 0 0 0 0 0 0
au_3 0 9 10 0 0 0 0 0 4 0 3 0 0
au_4 0 10 13 0 0 3 0 5 5 1 4 2 4
au_5 2 10 12 0 4 0 8 4 4 2 5 1 6
wi_1 3 6 7 0 6 7 0 4 8 0 4 0 0
wi_2 0 3 6 0 0 5 0 4 3 0 1 0 0
wi_3 0 0 3 0 0 1 0 1 0 0 0 0 0
wi_4 0 6 10 0 0 5 1 3 5 0 2 0 0
wi_5 1 9 11 0 3 6 8 3 5 2 5 0 0

Le resultat :

> fp(X)
Esp1 Esp2 Esp3
sp_1 Brh Bni Hla
sp_2 Brh Hla Eda
sp_3 Bsp Brh Hla
sp_4 Brh Hla Bsp
sp_5 Brh Bsp Ecd
su_1 Brh Bpu Bsp
su_2 Brh Eda Bsp
su_3 Brh Bsp Cen
su_4 Brh Bsp Cae
su_5 Brh Eig Bsp
au_1 Bpu Hla Brh
au_2 Brh Eda Bsp
au_3 Brh Bsp Hla
au_4 Brh Bsp Rhi
au_5 Brh Bsp Ecd
wi_1 Hla Brh Cen
wi_2 Brh Cen Rhi
wi_3 Brh Cen Rhi
wi_4 Brh Bsp Cen
wi_5 Brh Bsp Ecd

___________________
>Agustin Lobo :
In R, given a data matrix x:

> x
s1 s2 s3 s4 s5 s6 s7 s8 s9 s10
F1 119 164 151 64 176 146 157 133 167 150
F2 89 85 136 83 107 104 94 124 106 85
F3 113 82 113 75 92 63 42 87 74 94
F4 198 186 194 192 189 173 197 186 195 182

you would do just:
>
data.frame(dom.sps=dimnames(x)[[2]][apply(x,1,which.max)],abndce=apply(x,1,m
ax))

dom.sps abndce
F1 s5 176
F2 s3 136
F3 s1 113
F4 s1 198
_____________

>Luis Tito

Une solution tres simple consiste a utiliser les fonctions d'excel :

fac spA spB spN Numligne max equiv decaler
FA 0,01 0 0,2 1 0,2 3 spN
FB 0 0,5 0 2 0,5 2 spB
FN 0,5 0,01 0 3 0,5 1 spA

Dans la colonne Numligne je tape seulement le 1 puis je fais une
recopie incrementee jusqu'a la ligne N

Dans la colonne max je tape la formule =max(b2:d2) puis je fais une
recopie incrementee jusqu'a la ligne N

Dans la colonne equiv je tape la formule =equiv(f2;b2:d2;0) puis je
fais une recopie incrementee jusqu'a la ligne N. f2 est la cellule ou
se trouve le max de la ligne, b2:d2 est la ligne de la plage de
donnees, 0 est un code pour indiquer qu'il s'agit de valeurs
numeriques.

Dans la colonne decaler je tape la formule =decaler(a2;-e2;g2) puis
je fais une recopie incrementee jusqu'a la ligne N. a2 est la premiere
cellule de la ligne, e2 est la cellule ou se trouve le numero de ligne,
g2 est la cellule ou se trouve le maximum de la ligne.

Bien entendu, je fais un couper  collage special - valeurs du contenu
de la derniere colonne pour avoir les valeurs et non plus les formules
dans les cellules.

Probleme : cela ne gere pas les ex-aequo et cela ne donne que le max et
pas les trois les plus abondantes. Mais cela a le merite de la
simplicite, surtout si l'on ne connait pas ou que l'on n'a pas R .

J'espere que cela peut aider

Luis Tito

 

Pied de page des forums

Powered by FluxBB