# determine whether location of fish is wrong based on boat speed and time of last capture

I have a series of coordinates for fish caught from a boat at different datetimes and different trips. How do I determine whether the coordinates of a fish are likely to be incorrect (e.g. due to transcription error) based on time since last fish caught within that same trip and an assumed boat speed (say 10km/hour).

Here is a simple example dataset with 2 trips and two fish per trip.

``````library(sf)
library(ggplot2)

datetime <- ymd_hms('2017-05-13 14:00:00', tz = "Etc/GMT+8")
df <- data_frame(DateTimeCapture = c(datetime, datetime + minutes(35), datetime + days(2),
datetime + days(2) + minutes(20)),
Trip = c('1', '1', '2', '2'),
Order = c(1, 2, 1, 2),
X = c(648635, 648700, 647778, 658889),
Y = c(5853151, 5853200, 5854292, 5870000))

# if you prefer to work in sf
df_sf <-  st_as_sf(df, coords = c('X', 'Y'), crs = 32610)

# quick plot
ggplot() +
geom_point(data = df, aes(x = X, y = Y, color = Trip))
``````

The distance between the two fish in the second trip is 19km:

``````st_distance(df_sf[3:4, ])
Units: m
[,1]     [,2]
[1,]     0.00 19240.47
[2,] 19240.47     0.00
``````

It is unlikely that a boat could travel 19km in 20 minutes. Thus this should be flagged as a possible error.

My preference is for solutions using sf, but may also accept solutions using sp. It has to be r-based solution.

• looks like you're using library(lubridate) & library(dplyr) too? – jbosq Mar 30 '18 at 19:30

There is undoubtedly an sf solution that is more elegant and better accounts for the CRS, but here are my ugly 4 lines.

### Step 1: Get the elapsed time between trips, and convert that to a max distance

``````fill <- NA
transform(df, elapsedTime = c(fill, diff(as.numeric(DateTimeCapture))) * c(fill, 1))
``````

This works on the example 2 catches per trip, but here are alternatives when that varies. Use the same line to convert time to distance (10km/hr -> 2.77778m/sec)

``````df2 <- transform(df, maxDist = c(fill, (diff(as.numeric(DateTimeCapture)))*2.77778) * c(fill, 1))
``````

### Step 2: Determine catch distance and if that is greater than max distance

c^2 = a^2 + b^2, or distance = sqrt(sum((vector1-vector2)^2))

``````df3 <- transform(df2, dist = c(fill, sqrt(diff(X)^2 + diff(Y)^2)) * c(fill, 1))
#determine if the distance is greater than max dist
df3\$dist>df3\$maxDist
``````