Home > Enterprise >  Calculate a bearing in a data.table of points (lead) / calculate between rows of the same table
Calculate a bearing in a data.table of points (lead) / calculate between rows of the same table

Time:06-26

I have trouble to understand how to apply lead on a data.table I would like to calculate bearing between the current point and the next point. So basically calculate bearing between current and the next row in the data.table.

Here what i have tried:

I have the route data.table

library(geosphere)
library(data.table)
route<-structure(list(counter = 1:6, lon = c(11.829711, 11.8336202, 
11.8333238, 11.8341994, 11.8336198, 11.8337213), lat = c(48.1091400999115, 
48.1153102999101, 48.1269571999072, 48.1273386999071, 48.1297995999066, 
48.1309630999063)), row.names = c(NA, -6L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x55b3b7da26f0>)

next I create the "lead" data.table for (next) rows

  lead_route_dt<-route[, data.table::shift(.SD, 1, NA, "lead", TRUE), ]

And try to apply bearingRhumb on both data.tables:

 apply(data.frame(route$lon,route$lat), 1, FUN = function(x) bearingRhumb(x,cbind(lead_route_dt$lon_lead_1,lead_route_dt$lat_lead_1)))

but sadly as result i get an error:

 Error in if (sum(keep) == 0) { : missing value where TRUE/FALSE needed

What am i doing wrong?

CodePudding user response:

The error is due to bearingRhumb not handling NA:

bearingRhumb(c(NA,NA),c(11,42))
#Error in if (sum(keep) == 0) { : missing value where TRUE/FALSE needed

You need to exclude first row (containing NA) from calculation:

route[,`:=`(prev_lon = shift(lon,1),prev_lat = shift(lat,1))]
route[!(is.na(prev_lon)),bearing:=bearingRhumb(cbind(prev_lon,prev_lat),cbind(lon,lat))]
route

   counter      lon      lat prev_lon prev_lat    bearing
1:       1 11.82971 48.10914       NA       NA         NA
2:       2 11.83362 48.11531 11.82971 48.10914  22.928957
3:       3 11.83332 48.12696 11.83362 48.11531 359.026720
4:       4 11.83420 48.12734 11.83332 48.12696  56.865278
5:       5 11.83362 48.12980 11.83420 48.12734 351.066053
6:       6 11.83372 48.13096 11.83362 48.12980   3.332292
  • Related