Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a simple for loop on spatial data

Tags:

for-loop

r

sp

I'm sorry this is going to be a for loop 101 question. I am struggling to write a simple for loop to generate a table of distances between cities based upon longitude-latitude data

locations <-read.csv("distances.csv")

locations returns the following table:

       City Type       long      lat
1 Sheffield  EUR  -1.470085 53.38113
2        HK WRLD 114.109497 22.39643
3    Venice  EUR  12.315515 45.44085
4  New York WRLD -74.005941 40.71278

My goal in this particular part of the task is to produce a table of the distances (in kilometres) between each of the cities in the nature of a correlation matrix, with the diagonal being 0 (ie all cities are zero distance from themselves).

To do this I am using the sp package, which requires a matrix of long-lat values, so I can remove the text as follows:

datmax <- data.matrix(locations)
datmax2 <- datmax[,-1:-2]

The tool spDistsN1 allows me to get this information by comparing the distance all cities in the matrix are from one individual city. Clearly, I can use the following expression to obtain the distances of all cities from Sheffield (city or row# 1):

km <- spDistsN1(datmax2, datmax2[1,], longlat=TRUE)

This correctly gives:

[1]    0.000 9591.009 1329.882 5436.133

However, to achieve my desired correlation matrix style output, I want to achieve this for each of the cities, so I tried to write a for loop:

for (i in 1:nrow(datmax2)){
  kmnew <- spDistsN1(datmax2, datmax2[i,], longlat=TRUE)
}

This gives me the correct values for NY:

[1]  5436.133 12967.023  6697.541     0.000

So I presume I have overwritten one city by another throughout the loop. I appreciate the help in showing me where I am going wrong. Many thanks.

like image 653
RichS Avatar asked Mar 17 '23 13:03

RichS


1 Answers

First declare a matrix and use your iterator i to indicate the row to be filled in:

kmnew <- matrix(NA, nrow=4, ncol=4)
for (i in 1:nrow(datmax2)){
  kmnew[i,] <- spDistsN1(datmax2, datmax2[i,], longlat=TRUE)
}

colnames(kmnew) <- locations$City
rownames(kmnew) <- locations$City

Results

> kmnew

          Sheffield        HK   Venice  New York
Sheffield     0.000  9591.009 1329.882  5436.134
HK         9591.009     0.000 9134.698 12967.024
Venice     1329.882  9134.698    0.000  6697.541
New York   5436.134 12967.024 6697.541     0.000
like image 152
Dominic Comtois Avatar answered Mar 29 '23 02:03

Dominic Comtois