I have an old ado (nearest6.ado) to solve this problem. It assumes that you
have latitudes and longitudes and calculates the distance on the globe (not
euclidian) in miles. It is version 6 and seems to run fine in ver 8. I
can't vouch for it completely, but I think it works. The syntax for your
problem would be (all on one line):
nearest6 xp yp using stata_qrad_140403, idvar(radpc) latref(rdx)
lonref(rdy) genid(radid)
gendist(dist2rad)
You would issue this command after you use stata_qp_140403. It will create
radid which is radpc from the lookup file, and dist2rad which is the
distance in miles to the radpc closest.
Anyway, here it is (hoping line wrapping isn't too bad and you can get by
without a help file):
* cut here and name nearest6.ado****
program define nearest6
version 6.0
*! version 2.0.1 M Blasnik 10/11/99
* finds geo nearest neighbor in using file for
* each obs in current file
syntax varlist (min=2 max=2) using [if] [in] , IDvar(str) /*
*/ [LATref(str) LONref(str) GENID(str) GENDist(str)]
tokenize `varlist'
local latv `1'
local lonv `2'
* degrees to radians
scalar d2r=_pi/180
quietly {
if "`gendist'"!="" {
conf new var `gendist'
gen `gendist'=.
}
if "`genid'"!="" {confirm new var `genid'}
tempvar dist touse order grpcnt
gen `dist'=.
tempfile work
marksample touse
local obs=_N
local near=`obs'+1
count if `touse'
local start=`obs'-r(N)+1
sort `touse' `latv' `lonv'
by `touse' `latv' `lonv': gen long `grpcnt'=_N if `touse'
gen long `order'=_n
preserve
use `idvar' `latref' `lonref' `using', replace
if "`latref'"!="" {
rename `latref' `latv'
}
if "`lonref'"!="" {
rename `lonref' `lonv'
}
save `work'
restore
append using `work'
sort `order'
local i=`start'
while `i'<=`obs' {
local j=`i'+`grpcnt'[`i']-1
local lat=`latv'[`i']
local lon=`lonv'[`i']
replace `dist'=acos(sin(`lat'*d2r)*sin(`latv'*d2r)+/*
*/ cos(`latv'*d2r)*cos(`lat'*d2r)*cos(/*
*/ abs(`lon'-`lonv')*d2r))
replace `dist'=abs(`dist'*3958.754)
sort `order' `dist'
replace `idvar'=`idvar'[`near'] in `i'/`j'
if "`gendist'"!="" {
replace `gendist'=`dist'[`near'] in `i'/`j'
}
local i=`j'+1
}
drop if `touse'==. | `order'==.
if "`genid'"!="" {
rename `idvar' `genid'
}
}
end
**end of ado file
If line wrapping proves difficult, email me directly and I will send it as
an attachment
Michael Blasnik
[email protected]
----- Original Message -----
From: "Graeme Inglis" <[email protected]>
To: "Stata List (E-mail)" <[email protected]>
Sent: Tuesday, April 15, 2003 7:04 PM
Subject: st: Calculating distance
> Hi
> I would like some help from the StataList with a problem calculating the
> distance between a patients residential post code and the postcode of the
> nearest treatment centre.
>
> I have assembled a two data files. The first file contains the patients
> postcodes and the X & Y (px, py) coordinates of these post codes. The
> second file has the radiotherapy centres with their post codes and the X
&
> Y (rdx, rdy) coordinates of their post codes.
> By subtracting the X's and the Y's and applying pythagoras's theorem the
> distance in km can be calculated, but the difficulty is to select the
> shortest distance and write the location and shortest distance into a new
> variable for each patient.
>
> Now I envisage the shortest distance would be determined by taking the
first
> patient and calculating the distance to each treatment centre (13 centres
> in this case), then selecting the shortest distance among the centres then
> writing this distance and the centres post code into two new variables
> 'pradpc' and 'praddist' for that patient in the patient dataset. So that
the
> patient data set would progressively have values written into the post
code
> 'pradpc' of the nearest centre and the distance 'praddist' to this centre.
>
> I can calculate the distance OK but I can't get an iterative process
working
> that calculates then writes the values for 'pradpc' and 'praddist'.
>
> I have attached two sample files for the patient data and the treatment
> centre data to assist.
>
> <<stata_qp_140403.dta>> <<stata_qrad_140403.dta>>
>
> Now the process may be simplified by considering those patients who live
in
> the same post code as a treatment centre in which case pradpc=patpc and
> the distance would be zero.
>
> In addition if the patient file is sorted by post code duplicate values of
> the same post code would have the same pradpc and distance.
>
> I will be very grateful for help in this problem.
> I'm still using Stata 7.
> Thankyou in anticipation
> Cheers
>
>
> Graeme Inglis.
> Research Officer.
> Cancer Control Research Institute.
> Centre for Behavioural Research in Cancer.
> The Cancer Council of Victoria.
> Telephone: 61(0)3 9635 5203.
>
*
* For searches and help try:
* http://www.stata.com/support/faqs/res/findit.html
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/