How to Calculate the Distance Between Latitude and Longitude Along Rows of Columns in R

How to calculate the distance between points and a fixed location in R Studio

c(df$longitude,df$latitude) is just one long vector.

In this case you need to pass the columns of the data frame

library(geosphere)    
distGeo((citycenter, df[, c("longitude", "latitude")])

Now the dist() function will compute the distance between the city center location with every row in the data frame.

Distance between coordinates in dataframe sequentially?

df["distance"] <- c(NA,
sapply(seq.int(2,nrow(df)), function(i){
distm(c(df$Longitude[i-1],df$Latitude[i-1]),
c(df$Longitude[i], df$Latitude[i]),
fun = distHaversine)
})
)

This generates a vector beginning with NA for the first row. then it iterates until the last row while calculating the distance and adds those to the vector.

Calculate the distance between 2 coordinates in the same row in R

Check the distm function from geosphere package:

apply(df, 1, function(x)distm(c(x[1],x[2]),c(x[3],x[4]),fun = distGeo))

Calculate distance between multiple latitude and longitude points

distm() returns a distance matrix, which is not what you want; you want the pairwise distances. So use the distance function (distHaversine(), distGeo(), or whatever) directly:

library(tidyverse)

locations <- tibble(
homelong = c(0, 2),
homelat = c(2, 5),
worklong = c(70, 60),
worklat = c(45, 60)
)

locations <- locations %>%
mutate(
dist = geosphere::distHaversine(cbind(homelong, homelat), cbind(worklong, worklat))
)

locations
#> # A tibble: 2 × 5
#> homelong homelat worklong worklat dist
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0 2 70 45 8299015.
#> 2 2 5 60 60 7809933.

Note that geosphere functions want matrices as inputs, so you can cbind() your columns together. Don't c() them; that's creating a single shapeless vector and losing the differentiation between lon and lat. This is the cause of the error, I suspect; the vector only has one dimension, not two like a matrix.

R calculate distance in miles using 2 latitude & 2 longitude vectors in a data frame for 18k rows

library(geodist) is a good & fast library for calculating distances, and the geodist_vec() function is vectorised to work on 'columns' of data

library(geodist)

## calcualte distance in metres using Haversine formula
df$dist_m <- geodist::geodist_vec(
x1 = df$df1_Longitude
, y1 = df$df1_Latitude
, x2 = df$df2_Longitude
, y2 = df$df2_Latitude
, paired = TRUE
, measure = "haversine"
)

## convert to miles
df$dist_miles <- df$dist_m / 1609

# df1_location_number df1_Latitude df1_Longitude df2_location_number df2_Latitude df2_Longitude dist_m dist_miles
# 1 5051 34.71714 -118.9107 3051 34.71714 -118.91073 0.0 0.0000
# 2 5051 34.71714 -118.9107 3085 39.53404 -93.29237 2327593.8 1446.6089
# 3 5051 34.71714 -118.9107 3022 31.62679 -88.33012 2859098.6 1776.9413
# 4 5051 34.71714 -118.9107 3041 35.24798 -84.80412 3095858.6 1924.0886
# 5 5051 34.71714 -118.9107 3104 39.33425 -123.71306 667849.7 415.0713

Calculating distance between coordinates and reference point

points_in_circle() returns the points within a given radius from a reference point. The following returns all points within 1000km from the reference point:


library(spatialrisk)
points_in_circle(df, lat_center = 52.92343, lon_center = 5.04127,
lon = Longitude, lat = Latitude, radius = 1e6)
#> Day Month Year Location.Receiver Transmitter
#> 1095729 26 07 2021 Den Oever Ijsselmeer A69-1602-59776
#> 1072657 17 08 2021 Den Oever Ijsselmeer A69-1602-59776
#> 1092667 18 08 2021 Den Oever Ijsselmeer A69-1602-59776
#> 716601 19 08 2021 Den Oever Ijsselmeer A69-1602-59769
#> 1077415 19 08 2021 Den Oever Ijsselmeer A69-1602-59776
#> 1180267 05 08 2021 Medemblik Ijsselmeer, gemaal A69-1602-59777
#> Batch.location BatchNr Latitude Longitude Date distance_m
#> 1095729 Den Oever 8 52.92343 5.04127 2021-07-26 0.00
#> 1072657 Den Oever 8 52.92343 5.04127 2021-08-17 0.00
#> 1092667 Den Oever 8 52.92343 5.04127 2021-08-18 0.00
#> 716601 Den Oever 1 52.92343 5.04127 2021-08-19 0.00
#> 1077415 Den Oever 8 52.92343 5.04127 2021-08-19 0.00
#> 1180267 Den Oever 9 52.76098 5.12172 2021-08-05 18875.55

Created on 2021-12-02 by the reprex package (v2.0.1)

Calculate the distance between two coordinates columns group by individuals of different ID length in R

mutate(df, Distance=distHaversine(cbind(Lon, Lat),cbind(lag(Lon),lag(Lat))))

Sorry, my bad - forgot distHaversine needs a matrix.

How can I calculate the distance between latitude and longitude along rows of columns in R?

I think you're overcomplicating it a little. I wish geosphere::distHaversine had a slightly more intuitive calling method (similar to, say, diff), but it's not hard to work around it:

dat <- read.table(text = "  bid        ts    latitude  longitude
827566 1999-10-07 42.40944 -88.17822
827566 2013-04-11 41.84740 -87.63126
1902966 2012-05-02 45.52607 -94.20649
1902966 2013-03-25 41.94083 -87.65852
3211972 2012-08-14 43.04786 -87.96618
3211972 2013-08-02 41.88258 -87.63760", header = TRUE, stringsAsFactors = FALSE)
dat$ts <- as.Date(dat$ts)

library(dplyr)
library(geosphere)
group_by(dat, bid) %>%
mutate(
d = c(NA,
distHaversine(cbind(longitude[-n()], latitude[-n()]),
cbind(longitude[ -1], latitude[ -1]))),
dts = c(NA, diff(ts))
) %>%
ungroup() %>%
filter( ! is.na(d) )
# # A tibble: 3 × 6
# bid ts latitude longitude d dts
# <int> <date> <dbl> <dbl> <dbl> <dbl>
# 1 827566 2013-04-11 41.84740 -87.63126 77159.35 4935
# 2 1902966 2013-03-25 41.94083 -87.65852 660457.41 327
# 3 3211972 2013-08-02 41.88258 -87.63760 132494.65 353

Calculate Distance using Latitude and Longitude data in Different Data frames of different lengths with loop

Here's a solution using two packages: sf and tidyverse. The first one is used to convert the data into simple features and calculate the distance; while, the second one is used to put the data in the desired format.

library(tidyverse)
library(sf)

# Transform data into simple features
sfA <- st_as_sf(A, coords = c("long","lat"))
sfB <- st_as_sf(B, coords = c("LON","LAT"))

# Calculate distance between all entries of sf1 and sf2
distances <- st_distance(sfA, sfB, by_element = F)
# Set colnames for distances matrix
colnames(distances) <- paste0("B",1:3)

# Put the results in the desired format
# Transform distances matrix into a tibble
as_tibble(distances) %>%
# Get row names and add them as a column
rownames_to_column() %>%
# Set ID as the column name for the row numbers
rename("ID" = "rowname") %>%
# Transform ID to numeric
mutate_at(vars(ID), as.numeric) %>%
# Join with the original A data frame
right_join(A, by = "ID") %>%
# Change the order of columns
select(ID, long, lat, everything()) %>%
# Put data into long format
pivot_longer(cols = starts_with("B"),
names_to = "B_ID",
names_pattern = "B(\\d)",
values_to = "distance")

Calculate distance longitude latitude of multiple in dataframe R

Instead of distm you can use the distHaversine-function. Further in your mutate call you should not repeat the dataframe and use the $ operator, mutate already nows where to look for the columns. The error occurs because you need to use cbind instead of c, as c creates one long vector, simply stacking the columns together, whereas cbind creates a dataframe with two columns (what you want to have in this case).

library(geosphere)
library(dplyr)

mutate(mydata,
Distance = distHaversine(cbind(Longitude, Latitude),
cbind(lag(Longitude), lag(Latitude))))

# Callsign Altitude Speed Direction Date_Time Latitude Longitude Distance
# 1 A118 18000 110 340 2017-11-06T22:28:09 70.6086 58.2959 NA
# 2 A118 18500 120 339 2017-11-06T22:29:09 72.1508 58.7894 172569.2
# 3 B222 18500 150 350 2017-11-08T07:28:09 71.1689 59.1234 109928.5
# 4 D123 19000 150 110 2018-05-29T15:13:27 69.4523 68.1235 387356.2

With distCosine it is a little bit more tricky, as it doesn't return NA if one of the input latitudes or longitudes is missing. Thus I modified the function a little bit and this solves the problem:

modified_distCosine <- function(Longitude1, Latitude1, Longitude2, Latitude2) {
if (any(is.na(c(Longitude1, Latitude1, Longitude2, Latitude2)))) {
NA
} else {
distCosine(c(Longitude1, Latitude1), c(Longitude2, Latitude2))
}
}

mutate(mydata,
Distance = mapply(modified_distCosine,
Longitude, Latitude, lag(Longitude), lag(Latitude)))

# Callsign Altitude Speed Direction Date_Time Latitude Longitude Distance
# 1 A118 18000 110 340 2017-11-06T22:28:09 70.6086 58.2959 NA
# 2 A118 18500 120 339 2017-11-06T22:29:09 72.1508 58.7894 172569.2
# 3 B222 18500 150 350 2017-11-08T07:28:09 71.1689 59.1234 109928.5
# 4 D123 19000 150 110 2018-05-29T15:13:27 69.4523 68.1235 387356.2

Here I use mapply to apply the modified function with the arguments Longitude, Latitude, lag(Longitude), lag(Latitude).

I'm quite sure there has to be a more elegant way, but at least this works.

Data

mydata <- structure(list(Callsign = c("A118", "A118", "B222", "D123"), 
Altitude = c(18000L, 18500L, 18500L, 19000L),
Speed = c(110L, 120L, 150L, 150L),
Direction = c(340L, 339L, 350L, 110L),
Date_Time = c("2017-11-06T22:28:09", "2017-11-06T22:29:09", "2017-11-08T07:28:09", "2018-05-29T15:13:27"),
Latitude = c(70.6086, 72.1508, 71.1689, 69.4523),
Longitude = c(58.2959, 58.7894, 59.1234, 68.1235)),
.Names = c("Callsign", "Altitude", "Speed", "Direction", "Date_Time", "Latitude", "Longitude"),
class = "data.frame", row.names = c(NA, -4L))


Related Topics



Leave a reply



Submit