https://alaska.usgs.gov/products/data.php?dataid=612: Link for data, I am using the GPS location dataset.
I am running through the amt package vignette on some other GPS tracking data. I have run through the vignette data as well with no issue. I keep getting stuck at the nesting step, something appears to be wrong with how the data is being nested. I am also very stumped because inspecting the structures of the vignette data, and, my data they look the same. Below is the code I am using, and below that is the structure of my data. I have tried using subsets of the data without nesting and seem to have some luck, but the issue seems to be in the amt functions pulling the correct columns.
#' Load libraries
library(sf)
library(lubridate)
library(raster)
library(move)
library(amt)
library(tibble)
library(dplyr)
#' ### Load data
polarBear_GPS <- polarBear_GPSLocation_westHudsonBay_2019_2022
View(polarBear_GPS)
ind<-complete.cases(polarBear_GPS[,c("Datetime", "Longitude", "Latitude")])
polarBear_GPS<-polarBear_GPS[ind==TRUE,]
# Remove NA values from Datetime
polarBear_GPS <- polarBear_GPS[!is.na(polarBear_GPS$Datetime), ]
# Check for NA values again, should return 0
sum(is.na(polarBear_GPS$Datetime)) # Should return 0
#' Make timestamp a date/time variable
polarBear_GPS$Datetime <- as.POSIXct(polarBear_GPS$Datetime, format="%m/%d/%Y %H:%M:%S", tz="UTC")
#' We can also use lat, long, which will allow us to determine
#' time of day
# Create the track
# Create the track with a different CRS
trk1 <- make_track(
polarBear_GPS,
.x = Longitude,
.y = Latitude,
.t = Datetime,
id = Bear,
crs = st_crs(4326) # WGS 84
)
# Now it is easy to calculate day/night with either movement track
trk1 <- trk1 %>% time_of_day()
#' Now, we can transform back to geographic coordinates
trk1 <- transform_coords(trk1, crs_from = 4326, crs_to =4326 )
#' Or, we can add a columns to each nested column of data using purrr::map
trk2 <- trk1 %>% nest(data = -id)
trk3 = trk2 %>% mutate(dir_abs = purrr:::map(data, direction_abs,full_circle=TRUE, zero="N"),
dir_rel = purrr:::map(data, direction_rel),
sl = purrr:::map(data, step_lengths),
nsd_=purrr:::map(data, nsd))
The error I am getting is after the nesting trying to run the functions on trk2
str(trk1)
Classes ‘track_xyt’, ‘track_xy’, ‘spec_tbl_df’, ‘tbl_df’, ‘tbl’ and 'data.frame': 118858 obs. of 5 variables:
$ x_ : num -93.2 -93.2 -93.2 -93.2 -93.2 ...
$ y_ : num 58.8 58.8 58.8 58.8 58.8 ...
$ t_ : POSIXct, format: "2019-08-26 20:20:11" "2019-08-26 20:25:10" "2019-08-26 20:30:09" ...
$ id : chr "X17517" "X17517" "X17517" "X17517" ...
$ tod_: Factor w/ 2 levels "day","night": 1 1 1 1 1 1 1 1 1 1 ...
- attr(*, "spec")=List of 3
..$ cols :List of 4
.. ..$ Bear : list()
.. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
.. ..$ Datetime : list()
.. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
.. ..$ Latitude : list()
.. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
.. ..$ Longitude: list()
.. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
..$ default: list()
.. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
..$ delim : chr ","
..- attr(*, "class")= chr "col_spec"
- attr(*, "problems")=<externalptr>
- attr(*, "crs_")= num 4326
str(trk2)
nstd_trc [20 × 2] (S3: nested_track/tbl_df/tbl/data.frame)
$ id : chr [1:20] "X17517" "X19911" "X33824" "X33939" ...
$ data:List of 20
..$ : trck_xyt [5,435 × 4] (S3: track_xyt/track_xy/spec_tbl_df/tbl_df/tbl/data.frame)
.. ..$ x_ : num [1:5435] -93.2 -93.2 -93.2 -93.2 -93.2 ...
.. ..$ y_ : num [1:5435] 58.8 58.8 58.8 58.8 58.8 ...
.. ..$ t_ : POSIXct[1:5435], format: "2019-08-26 20:20:11" "2019-08-26 20:25:10" "2019-08-26 20:30:09" "2019-08-26 20:35:09" ...
.. ..$ tod_: Factor w/ 2 levels "day","night": 1 1 1 1 1 1 1 1 1 1 ...
.. ..- attr(*, "spec")=List of 3
.. .. ..$ cols :List of 4
.. .. .. ..$ Bear : list()
.. .. .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
.. .. .. ..$ Datetime : list()
.. .. .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
.. .. .. ..$ Latitude : list()
.. .. .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
.. .. .. ..$ Longitude: list()
.. .. .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
.. .. ..$ default: list()
.. .. .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
.. .. ..$ delim : chr ","
.. .. ..- attr(*, "class")= chr "col_spec"
.. ..- attr(*, "problems")=<externalptr>
.. ..- attr(*, "crs_")= num 4326
Error code is: Error in
mutate()
: ℹ In argument:dir_abs = purrr:::map(data, direction_abs, full_circle = TRUE, zero = "N")
. Caused by error inpurrr:::map()
: ℹ In index: 1. Caused by error inh()
: ! error in evaluating the argument 'y' in selecting a method for function 'atan2': argument "y" is missing, with no default
Couple of issues that might be causing your issue:
transform_coords()
on data that are already have the target CRS e.g. WGS84/EPSG:4326. See the metadata at the Alaska Science Center download linkThese issues were not/could not be tested, so cannot confirm. These stated issues are unlikely to be causing a problem (except issue 3 potentially). However, to rule out as many causes as possible, start from a fresh R sessions and run the below code verbatim (including not loading any other packages other than those stated).
Note also that the code you posted does not include a step to check for duplicate timestamps (which need to be removed if they exist). Code to check and remove duplicates is included in this reprex. None were found, and no NAs were present either, so the source data are clean.
library(sf)
library(amt)
library(dplyr)
library(purrr)
# Load data from working directory, previously unzipped and downloaded from
# https://alaska.usgs.gov/data1/polarBear/polarBear_onLand_westHudsonBay_pagano/polarBear_GPSLocation_westHudsonBay_2019-2022.zip
polarBear_GPS <- read.csv("polarBear_GPSLocation_westHudsonBay_2019-2022.csv")
# Check for NA values, 0 == no NA values in df
sum(is.na(polarBear_GPS))
# [1] 0
### Skip following if previous step returns 0
# ind <- complete.cases(polarBear_GPS[, c("Datetime", "Longitude", "Latitude")])
#
# polarBear_GPS <- polarBear_GPS[ind == TRUE, ]
#
# # Remove NA values from Datetime
# polarBear_GPS <- polarBear_GPS[!is.na(polarBear_GPS$Datetime), ]
###
# Make Datetime a date/time variable
polarBear_GPS$Datetime <- as.POSIXct(polarBear_GPS$Datetime, format="%m/%d/%Y %H:%M:%S", tz = "UTC")
# Check for duplicated timestamps per bear
polarBear_GPS |>
summarise(ts_dupes = any(duplicated(Datetime)), .by = Bear)
# Bear ts_dupes
# 1 X17517 FALSE
# 2 X19911 FALSE
# 3 X33823 FALSE
# 4 X33824 FALSE
# 5 X33935 FALSE
# 6 X33939 FALSE
# 7 X33653 FALSE
# 8 X33934 FALSE
# 9 X33928 FALSE
# 10 X33936 FALSE
# 11 X33938 FALSE
# 12 X33991 FALSE
# 13 X33954 FALSE
# 14 X33851 FALSE
# 15 X32415 FALSE
# 16 X33410 FALSE
# 17 X33712 FALSE
# 18 X19842 FALSE
# 19 X33302 FALSE
# 20 X32422 FALSE
# If any return true, run following step, else skip
polarBear_GPS <- polarBear_GPS |>
distinct(Datetime, .keep_all = TRUE, .by = Bear)
# Create the track with correct CRS (see metadata at download link above)
trk1 <- make_track(
polarBear_GPS,
.x = Longitude,
.y = Latitude,
.t = Datetime,
id = Bear,
crs = st_crs(4326) # WGS 84
)
# Calculate day/night
trk1 <- trk1 |> time_of_day()
# Add columns to each nested column of data using purrr::map()
trk2 <- trk1 |> nest(data = -id)
trk3 <- trk2 |>
mutate(dir_abs = map(data, direction_abs, full_circle = TRUE, zero = "N"),
dir_rel = map(data, direction_rel),
sl = map(data, step_lengths),
nsd_ = map(data, nsd))
trk3
# A tibble: 20 × 6
# id data dir_abs dir_rel sl nsd_
# <chr> <list> <list> <list> <list> <list>
# 1 X17517 <trck_xyt [5,435 × 4]> <dbl [5,435]> <dbl [5,435]> <dbl [5,435]> <dbl [5,435]>
# 2 X19911 <trck_xyt [5,381 × 4]> <dbl [5,381]> <dbl [5,381]> <dbl [5,381]> <dbl [5,381]>
# 3 X33824 <trck_xyt [5,818 × 4]> <dbl [5,818]> <dbl [5,818]> <dbl [5,818]> <dbl [5,818]>
# 4 X33939 <trck_xyt [5,468 × 4]> <dbl [5,468]> <dbl [5,468]> <dbl [5,468]> <dbl [5,468]>
# 5 X33823 <trck_xyt [5,688 × 4]> <dbl [5,688]> <dbl [5,688]> <dbl [5,688]> <dbl [5,688]>
# 6 X33934 <trck_xyt [6,080 × 4]> <dbl [6,080]> <dbl [6,080]> <dbl [6,080]> <dbl [6,080]>
# 7 X33935 <trck_xyt [5,690 × 4]> <dbl [5,690]> <dbl [5,690]> <dbl [5,690]> <dbl [5,690]>
# 8 X33928 <trck_xyt [6,040 × 4]> <dbl [6,040]> <dbl [6,040]> <dbl [6,040]> <dbl [6,040]>
# 9 X33936 <trck_xyt [6,037 × 4]> <dbl [6,037]> <dbl [6,037]> <dbl [6,037]> <dbl [6,037]>
# 10 X33653 <trck_xyt [6,025 × 4]> <dbl [6,025]> <dbl [6,025]> <dbl [6,025]> <dbl [6,025]>
# 11 X33938 <trck_xyt [5,977 × 4]> <dbl [5,977]> <dbl [5,977]> <dbl [5,977]> <dbl [5,977]>
# 12 X33991 <trck_xyt [6,002 × 4]> <dbl [6,002]> <dbl [6,002]> <dbl [6,002]> <dbl [6,002]>
# 13 X33954 <trck_xyt [6,301 × 4]> <dbl [6,301]> <dbl [6,301]> <dbl [6,301]> <dbl [6,301]>
# 14 X33851 <trck_xyt [5,985 × 4]> <dbl [5,985]> <dbl [5,985]> <dbl [5,985]> <dbl [5,985]>
# 15 X32415 <trck_xyt [5,969 × 4]> <dbl [5,969]> <dbl [5,969]> <dbl [5,969]> <dbl [5,969]>
# 16 X33410 <trck_xyt [6,050 × 4]> <dbl [6,050]> <dbl [6,050]> <dbl [6,050]> <dbl [6,050]>
# 17 X33712 <trck_xyt [6,581 × 4]> <dbl [6,581]> <dbl [6,581]> <dbl [6,581]> <dbl [6,581]>
# 18 X19842 <trck_xyt [6,464 × 4]> <dbl [6,464]> <dbl [6,464]> <dbl [6,464]> <dbl [6,464]>
# 19 X33302 <trck_xyt [5,889 × 4]> <dbl [5,889]> <dbl [5,889]> <dbl [5,889]> <dbl [5,889]>
# 20 X32422 <trck_xyt [5,978 × 4]> <dbl [5,978]> <dbl [5,978]> <dbl [5,978]> <dbl [5,978]>