I am working with tracking data and stumbled upon the functions from the package "adehabitatLT", which I find quite handy for obtaining the descriptive parameters of my trajectories.
All strings of my code work properly, but unfortunately, I do not understand what's wrong to end up with unusual extremely low outputs (I am working with flying birds so I expect the results for velocity/speed and distance to be around 1-100 km/h and 2-3000 km max, respectively).
Here's a snippet and the structure of the relevant columns from my df called springsub:
> head(springsub)
X DateTime id lat lon
1 1 2022-05-03 19:39:00 N34246@096AFE12 45.7309083 13.3009833
2 2 2022-05-03 21:39:00 N34246@096AFE12 46.3943317 14.9383667
3 3 2022-05-03 23:39:00 N34246@096AFE12 47.3849317 16.5986833
4 4 2022-05-04 01:39:00 N34246@096AFE12 48.44073 18.0876833
5 5 2022-05-04 03:39:00 N34246@096AFE12 48.73939 18.5627
6 6 2022-05-04 05:39:00 N34246@096AFE12 48.739305 18.5627
> str(springsub)
'data.frame': 21053 obs. of 12 variables:
$ X : int 1 2 3 4 5 6 7 8 9 10 ...
$ DateTime : POSIXct, format: "2022-05-03 19:39:00" "2022-05-03 21:39:00" "2022-05-03 23:39:00" "2022-05-04 01:39:00" ...
$ id : chr "N34246@096AFE12" "N34246@096AFE12" "N34246@096AFE12" "N34246@096AFE12" ...
$ lat : chr "45.7309083" "46.3943317" "47.3849317" "48.44073" ...
$ lon : chr "13.3009833" "14.9383667" "16.5986833" "18.0876833" ...
Here's my code so far:
library(adehabitatLT)
library(sp)
library(sf)
spring_sf <- st_as_sf(springsub, coords = c("lon", "lat"), crs = 4326)
individual_ids <- unique(springsub$id) # get unique individual IDs
ltraj_list <- list() # stores ltraj obj for each id
# loop plus some debugging that was needed for it to work properly
for (id in individual_ids) {
cat("Processing individual:", id, "\n")
individual_data <- spring_sf[spring_sf$id == id, ]
cat("Number of unique dates:", length(unique(individual_data$DateTime)), "\n")
if (anyDuplicated(individual_data$DateTime) > 0) {
individual_data$DateTime <- individual_data$DateTime + seq(0, length.out = nrow(individual_data), by = 1)
}
individual_coords <- st_coordinates(individual_data)
tryCatch({
individual_ltraj <- as.ltraj(individual_coords, date = individual_data$DateTime, id = individual_data$id, typeII = TRUE)
ltraj_list[[id]] <- individual_ltraj},
error = function(e)
{
cat("Error for individual:", id, "\n")
print(e)
})
}
ld_results <- list()
for (i in seq_along(ltraj_list)) {
individual_ltraj <- ltraj_list[[i]]
ld_result <- ld(individual_ltraj)
ld_results[[i]] <- ld_result
}
ltraj_metrics <- do.call(rbind, ld_results)
# adding relevant metrics
# velocity
ltraj_metrics$velocity <- ltraj_metrics$dist / ltraj_metrics$dt
# euclidean distance and total distance
euclidean_distance <- aggregate(dist ~ id, data = ltraj_metrics, FUN = sum)
total_distance <- aggregate(dist ~ id, data = ltraj_metrics, FUN = sum)
# straightness
sum_R2n_per_ID <- aggregate(R2n ~ id, data = ltraj_metrics, FUN = sum)
sum_R2n_per_ID <- aggregate(R2n ~ id, data = ltraj_metrics, FUN = sum)
R2n_data <- merge(sum_R2n_per_ID, total_distance, by = "id")
R2n_data$straightness <- R2n_data$R2n / R2n_data$dist
# turning angle on x (abs.angle)
ltraj_metrics$turning_angle_x <- c(NA, diff(ltraj_metrics$abs.angle))
# turning angle on y (rel.angle)
ltraj_metrics$turning_angle_y <- c(NA, diff(ltraj_metrics$rel.angle))
And here's an example of the very odd outputs I get:
> head(ltraj_metrics)
x y date dx dy dist dt R2n abs.angle rel.angle id
1 13.30098 45.73091 2022-05-03 19:39:00 1.6373834 0.6634234 1.7666790898 7200 0.000000 0.3849578 NA N34246@096AFE12
2 14.93837 46.39433 2022-05-03 21:39:00 1.6603166 0.9906000 1.9333751763 7200 3.121155 0.5379402 0.15298242 N34246@096AFE12
3 16.59868 47.38493 2022-05-03 23:39:00 1.4890000 1.0557983 1.8253303948 7200 13.610619 0.6167842 0.07884398 N34246@096AFE12
4 18.08768 48.44073 2022-05-04 01:39:00 0.4750167 0.2986600 0.5611048573 7200 30.255631 0.5612812 -0.05550300 N34246@096AFE12
5 18.56270 48.73939 2022-05-04 03:39:00 0.0000000 -0.0000850 0.0000850000 7200 36.736625 -1.5707963 -2.13207754 N34246@096AFE12
6 18.56270 48.73931 2022-05-04 05:39:00 0.0000833 0.0001100 0.0001379815 7200 36.736113 0.9226569 2.49345322 N34246@096AFE12
burst pkey velocity turning_angle_x turning_angle_y
1 N34246@096AFE12 N34246@096AFE12.2022-05-03 19:39:00 2.453721e-04 NA NA
2 N34246@096AFE12 N34246@096AFE12.2022-05-03 21:39:00 2.685243e-04 0.15298242 NA
3 N34246@096AFE12 N34246@096AFE12.2022-05-03 23:39:00 2.535181e-04 0.07884398 -0.07413844
4 N34246@096AFE12 N34246@096AFE12.2022-05-04 01:39:00 7.793123e-05 -0.05550300 -0.13434698
5 N34246@096AFE12 N34246@096AFE12.2022-05-04 03:39:00 1.180556e-08 -2.13207754 -2.07657455
6 N34246@096AFE12 N34246@096AFE12.2022-05-04 05:39:00 1.916410e-08 2.49345322 4.62553077
For reference, the dist between 1 and 2 should be roughly 2099000 m. The dist values are automatically calculated by the adehabitatLT functions.
What am I doing wrong?
Any help is highly appreciated :)
I believe the issue is you are using lat long instead of UTM for your coordinates. "adehabitatLT" dosen't automatically convert lat long into meters.