### Stata Code Fragment Computing the Sum Difference Between Two Latitude and Longitude Points using Mata

This code fragment page shows an example using Mata to write functions and loop through a dataset to calculate the sum distance between lattitude and longitude points within particular id groups. We use a built in Stata dataset for convenience even though it is not real lattitude and longitude data. The distance formula used is haversine. The Mata function mhaversine stands for matrix haversine because it takes a matrix as input.

mata
real matrix mhaversine(real matrix x)
/* assumes data matrix with points */
/* lat1 lon1 (from) lat2 lon2 (to) */
{
d2r = pi() / 180
earth_Rmeters = 6372797.560856 /* earth radius in meters */
lat1 = x[, 1]
lat2 = x[, 3]
lon1 = x[, 2]
lon2 = x[, 4]
rdLat = (lat1 - lat2) * d2r
rdLon = (lon1 - lon2) * d2r
latH = sin(rdLat * .5):^2
lonH = sin(rdLon * .5):^2
tmp = cos(lat1 * d2r) :* cos(lat2 * d2r)
tmp = 2 * asin(sqrt(latH :+ tmp :* lonH))
results = earth_Rmeters :* tmp /* distance in meters */
return(results)
}

void foobar(string scalar varlist, ///
string scalar selector, ///
string scalar output) {
x = st_data(., varlist, selector)

results = I(rows(x))

for(i=1; i<=rows(x); i++) {
dat = (J(rows(x), 1, x[i, ]), x)
results[i, ] = mhaversine(dat)'
}

finalresults = rowsum(results)

st_store(., output, selector, finalresults)
}
end

sysuse auto
gen mata_id = .
gen results = .
egen id = group(displacement gear_ratio)
summarize id, meanonly

forvalues ind=1/r(max)' {
replace mata_id = id == ind'
mata foobar("weight length", "mata_id", "results")
}

list results in 1/10

+----------+
|  results |
|----------|
1. |        0 |
2. |        0 |
3. |        0 |
4. |  3360138 |
5. |  7731513 |
|----------|
6. |  5559471 |
7. |        0 |
8. |  3360138 |
9. | 4.60e+07 |
10. | 1.34e+07 |
+----------+


The content of this web site should not be construed as an endorsement of any particular web site, book, or software product by the University of California.