Pages

Affichage des articles dont le libellé est proche. Afficher tous les articles
Affichage des articles dont le libellé est proche. Afficher tous les articles

[PROC] Trouver la valeur la plus proche (deux dimensions) sujet

vendredi 28 mars 2014




Bonjour,

je dispose d'une table d'évenements avec pour chaque évenement un datetime et des coordonnées lat et lon :


Code:


1
2
3
4
5
6
7
8
9
10
11
12


data events;
format dt datetime. ;
input eventid dt datetime18. lat lon;
datalines;
1 07JAN2004:08:07:00 52.268157 -86.923828
2 09JAN2004:03:04:00 32.398516 -19.951172
3 13JAN2004:02:01:00 52.855864 -11.953125
4 01JAN2004:01:04:00 28.998532 -17.666016
;
run;



d'autre part j'ai des stations de mesure pour lesquelles je dispose de certains relevés avec datetime,lat,lon :


Code:


1
2
3
4
5
6
7
8
9
10
11
12


data stations;
format dt datetime. ;
input staid dt datetime18. lat lon mes1;
datalines;
1 07JAN2004:01:07:00 52.968157 -86.923728 11.2
2 09JAN2004:09:04:00 31.398316 -19.951172 4.6
3 13JAN2004:02:01:00 52.955864 -11.953125 7.0
4 01JAN2004:07:04:00 28.998532 -17.616016 -7.1
;
run;


Je cherche à obtenir pour chaque évenement la mesure prise par la station la plus proche au moment le plus proche. (toutes les stations n'ont pas de mesures pour toutes les heures)

actuellement je fais ceci est sql, je retiens pour chaque évenements, les mesures qui ont lieu dans n'importe quelle station avec +/- 3 heures et je garde uniquement la plus proche géographiquement, de ce résultat je garde la plus proche temporellement. je filtre ensuite les doublons pour éliminer les exequos.


Code:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

proc sql;
create table croisement as
select * from (
select t0.*,t1.dt as dtmesure,t1.mes1,geodist(t0.lat,t0.lon,t1.lat,t1.lon) as distanceGeo,abs(t0.dt-t1.dt) as distanceTemps
from events as t0,stations as t1 where abs(t0.dt-t1.dt)<3600*3
group by t0.idEvent
having geodist(t0.lat,t0.lon,t1.lat,t1.lon)=min(geodist(t0.lat,t0.lon,t1.lat,t1.lon))
)
group by t0.idEvent
having distanceTemps=min(distanceTemps);
quit;


proc sort data=croisement nodupkey;
by idEvent;
run;


Ce code fonctionne mais il est très lent pour un grand nombre d'évenements (~500k évenements vs 4M de mesures) et il ne permet pas de préciser des tolérences, pour par exemple
prendre la deuxième station la plus proche si celle ci a une distance temporelle très petite par rapport à la plus proche.
Je me demandais si avec les procédures STAT(tree ? fastclus?) il n'y aurait pas mieux sans se lancer dans des algos d'optimisations compliqués ?
Je suis preneur de vos idées :)