# Finding location points where travel angle changes using R?

I want to use R to find out the point locations at which my vehicle (equiped with GPS) started to turn. The data contains coordinates and time information. I have sort my data based on time sequence:

`````` time_stamp <- as.POSIXct(paste(field\$Date, field\$Time), format="%d/%m/%Y %H:%M:%S")
field <- data.frame(field,time_stamp)
field <- field[order(field\$time_stamp),]
``````

Then I borrow the codes from post below to calculate the angles of each three sequential points: https://stackoverflow.com/questions/11184381/calculating-angle-from-latitude-and-longitude

And modified it a little bit.

``````# define coordinates

coordinates(field) <- c("Longitude", "Latitude")
proj4string(field) <- CRS("+init=epsg:4326")

# calculate angles

trackAngle <- function(xy) {
angles <- abs(c(trackAzimuth(xy), 0) -
c(0, rev(trackAzimuth(xy[nrow(xy):1, ]))))
angles <- ifelse(angles > 180, 360 - angles, angles)
angles[is.na(angles)] <- 180
angles[-c(1, length(angles))]
}

ang <- trackAngle(field@coords)

# Just to make it the same length as my dataset
# I inserted the first and the last angles to the vector

ang <- c(ang[1],ang,ang[1])
``````

Now I am thinking to use if-else statement, says if at this point the angle is bigger than 20 degree compared the last point, then this point will be classified as the point of turning.

``````new_df <- data.frame(field,ang1)
new_column <- 1:nrow(new_df)

for(i in 1:nrow(new_df))
{
angle_changes <- ang1[i+1]-ang1[i]
if (angle_changes>20)
{new_column[i] <- 'turn'}
else
{new_column[i] <- 'not_turn'}
}
Error in if (angle_changes > 20) { :
missing value where TRUE/FALSE needed
``````

Is there a simpler and faster way of achieving this, without calculating all angles first?

For reproducible example, I selected the first 20 rows. The raw dataset has ~63,000 obs.

``````     field1
Longitude  Latitude
49221   175.723 -37.82931
49222   175.723 -37.82931
49223   175.723 -37.82931
49230   175.723 -37.82931
49248   175.723 -37.82931
49272   175.723 -37.82931
49309   175.723 -37.82932
49324   175.723 -37.82932
49337   175.723 -37.82932
49347   175.723 -37.82932
49357   175.723 -37.82932
49367   175.723 -37.82932
49380   175.723 -37.82932
49389   175.723 -37.82932
49393   175.723 -37.82932
49400   175.723 -37.82932
49411   175.723 -37.82932
49417   175.723 -37.82932
49430   175.723 -37.82932
49434   175.723 -37.82932
``````

I compared `trip` package `trackAngle` with the defined `trackAngle`. The former output 18 results `NA NA 172.0851 174.9314 179.6634 172.2936 170.6603 178.0629 176.5133 178.0556 178.0443 173.4078 177.9946 179.6743 178.1043 178.5513 177.2740 177.2740`,

the later output `180.0000 180.0000 172.0851 174.9314 179.6634 172.2936 170.6603 178.0629 176.5133 178.0556 178.0443 173.4078 177.9946 179.6743 178.1043 178.5513 177.2740 177.2740`.

• You can use diff(ang) to avoid looping, and fwiw there is an equivalent trip::trackAngle function – mdsumner Sep 10 '16 at 12:08
• thanks, I wonder why `trip::trackAngle` generates 2429 NA's for my dataset while the defined trackAngle function doesn't. @mdsumner – Gorden Jiang Sep 11 '16 at 23:10
• reproducible example? – mdsumner Sep 12 '16 at 4:27
• Please find my edited question @mdsumner – Gorden Jiang Sep 13 '16 at 2:54