This approcah makes maximum use of in-emory processing to search iteratively through a set and find the closest location in a target list. I developed to find the closest ATM to a given one, but it has other applications.
Scroll down for some explanations.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. <http://www.gnu.org/licenses/>. Developed by Mario Segal
#Create a view with the atms we want to find closest locations to;
data atm_view1 / view=atm_view1;
set sample_atms( where=( x1 ne . or y1 ne .));
keep id1 x1 y1 group;
#Create a view with the atms we want to search into, In my example they are a subset of the same set;
data atm_view2 / view=atm_view2;
set sample_atms( where=( (x1 ne . or y1 ne .) and group ne ‘Offsite’) );
rename id1=id2 x1=x2 y1=y2;
keep id1 x1 y1 ;
*define the variables for hash objects, line only executes at compilation;
if 0 then set atm_view1 atm_view2 ;
*define variables to store best distance and associated ATM ID;
length best_id $ 8 best_distance 8;
*at beginning of execution, load atm_views with dasta into hash objects and also define their iterators;
if _N_ eq 1 then do;
dcl hash list(dataset: “atm_view1”);
dcl hiter hi_list(‘list’);
dcl hash lookup(dataset: “atm_view2”);
dcl hiter hi_lookup(‘lookup’);
*load the atm_data from memory for which we want to find the nearest atm and calculate the distance;
do while (rc=0);
best_distance = 999999; *set best distance to a large value;
best_id=”; *initialize best match ID;
do while (rc1=0);
current = geodist(y1,x1,y2,x2,’DM’);
if current lt best_distance and id1 ne id2 and (x1 ne x2 and y1 ne y2) then do;
*do not set best_distance to distance to self or to a co-located ATM;
best_distance = current;
best_id = id2;
keep id1 group best_id best_distance;
1) I developed 2 views to hold the data, the only thing stored is the code to execute them and I can make changes to the data without impacting the source or making a copy.
2) Then I load them into a hash object and create an iterator each.
3) The we use the iterators to search through all options for each one and select the best
4) The we output the results.
I hope this works for you.