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
Dplyr: How to Apply Do() on Result of Group_By
How to Draw Half-Filled Points in R (Preferably Using Ggplot)
Find Elements Not in Smaller Character Vector List But in Big List
R 3.5 Is Not Available for Linux
Use Csl-File for PDF-Output in Bookdown
R: Faceted Bar Chart with Percentages Labels Independent for Each Plot
Using Rvest to Scrape a Website W/ a Login Page
Rmarkdown Setting the Position of Kable
Ggplot Set Scale_Color_Gradientn Manually
Ggplot: Combining Size and Color in Legend
Determine If Data Frame Is Empty
How to Plot a Combined Bar and Line Plot in Ggplot2
How to Measure Area Between 2 Distribution Curves in R/Ggplot2