Reputation: 1661
I am trying to get a matrix that contains the distances between the points in two lists.
The vector of points contain the latitude and longitude, and the distance can be calculated between any two points using the function distCosine in the geosphere package.
> Points_a
lon lat
1 -77.69271 45.52428
2 -79.60968 43.82496
3 -79.30113 43.72304
> Points_b
lon lat
1 -77.67886 45.48214
2 -77.67886 45.48214
3 -77.67886 45.48214
4 -79.60874 43.82486
I would like to get a matrix out that would look like:
d_11 d_12 d_13
d_21 d_22 d_23
d_31 d_32 d_33
d_41 d_42 d_43
I am struggling to think of a way to generate the matrix without just looping over Points_a and Points_b and calculating each combination, can anyone suggest a more elegant solution?
Upvotes: 2
Views: 1277
Reputation: 12819
You can use this:
outer(seq(nrow(Points_a)),
seq(nrow(Points_b)),
Vectorize(function(i, j) distCosine(Points_a[i,], Points_b[j,]))
)
(based on tip by @CarlWitthoft)
According to the desired output you post, maybe you'll want the transpose t()
of this, or simply replace _a
with _b
above.
EDIT: some explanation:
seq(nrow(Points_x))
: creates a sequence from 1 to the number of rows of Points_x
;distCosine(Points_a[i,], Points_b[j,])
: expression to compute the distance between points given by row i
of Points_a
and row j
of Points_b
;function(i, j)
: makes the above an unnamed function in two parameters;Vectorize(...)
: ensure that, given inputs i
and j
of length greater than one, the unnamed function above is called only once for each element of the vectors (see this for more info);outer(x, y, f)
: creates "expanded" vectors x
and y
such that all combinations of its elements are present, and calls f
using this input (see link above). The result is then reassembled into a nice matrix.Upvotes: 4