Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: st: spatial analysis - DISTANCE


From   Roy Wada <roywada@hotmail.com>
To   <statalist@hsphsun2.harvard.edu>
Subject   RE: st: spatial analysis - DISTANCE
Date   Sun, 30 Aug 2009 10:58:28 -0700

> This is in reference to e.g.
> http://stata.com/statalist/archive/2009-07/msg00083.html
> http://stata.com/statalist/archive/2007-01/msg00098.html
>
>> ... a better choice for returning multiple distances and the ids
>> attached to the point the distance to which is being calculated?
>>
>> David Torres

This question comes up fairly often. A program like this is 
potentially valuable considering what people are willing to put 
up with things like ArcGIS. 

The problem is writing codes that will finish running in a reasonable 
amount of time. This is more difficult than most people realize.
 
I happen to have several that will do something like this, and 
promised someone else that I would clean one up. I'll send it 
to Kit after the help file is finished.
 
Roy
 
 
To run this, you need to -append- your dataset. Assisn unique/distinct 
id. Let id to be missing (replace id=.) if you want them to be 
non-donor, meaning the neighbors will be found for them but they 
will not be anyone's neighbor. less( ) is in miles.
 
distmatch [varlist], id(id) lat(latitude) lon(longitude) near(3) less(50)
 
 
*! distmatch version 0.9 29aug2009 roywada@hotmail.com
*! matches locations based on coordiante distance
prog define distmatch, sortpreserve
syntax [varlist(default=none)], id(string) LATitude(string) /*
 */ LONgitude(string) [dist(string) NEARmax(integer 3) SUFfix(string) less(numlist max=1>=0) /*
 */ more(numlist max=1) ]
qui {
if "`dist'"=="" {
 local dist "dist"
}
if "`suffix'"=="" {
 local _near "_n"
}
if "`less'"=="" {
 local less .
}
if "`more'"=="" {
 local more -1
}
if `less'1 {
 noi di in red `"observations not uniquely identified by "`id'""'
 exit 198
}
* push the missing id to the bottom
sort `id'
* does it sideways by creating variables
foreach var in `id' {
 forval num=1/`nearmax' {
  gen `var'`_near'`num'=`var'
  cap replace `var'`_near'`num'=""
  cap replace `var'`_near'`num'=.
  label var `var'`_near'`num' "nearest `var' `num'"
 }
}
foreach var in `dist' {
 forval num=1/`nearmax' {
  gen `var'`_near'`num'=.
  label var `var'`_near'`num' "nearest `var' `num'"
 }
}
foreach var in `group' `varlist' {
 forval num=1/`nearmax' {
  gen `var'`_near'`num'=`var'
  cap replace `var'`_near'`num'=""
  cap replace `var'`_near'`num'=.
  label var `var'`_near'`num' "nearest `var' `num'"
 }
}
sort `group', stable
sum `group'
local max `r(max)'
* place holders
foreach var in `group' `id' `varlist' `latitude' `longitude' {
 tempvar `var'New
 gen ``var'New'=`var'
}
foreach var in `dist' {
 tempvar `var'New
 gen double ``dist'New'=.
}
tempvar reject
gen `reject'=0
local N=_N
forval candidate=1/`nearmax' {
 if `N'>100 {
  noi di in yel "nearest `candidate' of `nearmax'"
 }
 forval place=1/`max' {
  * comarison values
  foreach var in `group' `id' `varlist' `latitude' `longitude' {
   replace ``var'New'=`var'[`place']
  }
  
  * Great Circle Distance Formulas
  foreach var in `dist' {
   replace ``dist'New'=3963 * acos(sin(``latitude'New'/57.2958) * sin(`latitude'/57.2958) + cos(``latitude'New'/57.2958) * cos(`latitude'/57.2958) * cos(``longitude'New'/57.2958-`longitude'/57.2958))
   replace ``dist'New'=. if ``dist'New'>`less'
   replace ``dist'New'=. if ``dist'New'
_________________________________________________________________
With Windows Live, you can organize, edit, and share your photos.
http://www.windowslive.com/Desktop/PhotoGallery
*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index