使用amt包嵌套GPS数据时遇atan2参数缺失错误求助
背景
使用2019-2022年哈德逊湾西部北极熊GPS位置数据集,按照amt包官方vignette流程处理GPS追踪数据时,示例数据可正常运行,但自有数据在嵌套步骤后调用amt函数出现错误。非嵌套子集可正常运行,怀疑amt函数列识别存在问题。
运行代码
# 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") # Create the track with WGS 84 CRS trk1 <- make_track( polarBear_GPS, .x = Longitude, .y = Latitude, .t = Datetime, id = Bear, crs = st_crs(4326) ) # Calculate day/night trk1 <- trk1 %>% time_of_day() # Transform coordinates (此处CRS未变化,可省略) trk1 <- transform_coords(trk1, crs_from = 4326, crs_to =4326 ) # Nest data by individual trk2 <- trk1 %>% nest(data = -id) # Attempt to calculate movement metrics (报错代码) 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))
数据结构
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 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
中文翻译
在
mutate()中出错:
ℹ 出错参数:dir_abs = purrr:::map(data, direction_abs, full_circle = TRUE, zero = "N")。
由purrr:::map()引发错误:
ℹ 出错索引:1。
由h()引发错误:
! 为函数atan2选择方法时,计算参数'y'出错:参数"y"缺失,无默认值
解决方案
问题出在两个点:
- 使用了
purrr:::map(三个冒号)调用purrr的内部未导出函数,这是非标准用法,容易引发参数传递问题; - 直接将
direction_abs等amt函数传入map时,参数传递逻辑不符合amt函数的要求,需要显式将嵌套的track对象传递给函数。
修改后的代码如下:
# 使用标准的purrr::map,并通过公式语法显式传递track对象 trk3 <- trk2 %>% mutate( dir_abs = purrr::map(data, ~direction_abs(.x, full_circle = TRUE, zero = "N")), dir_rel = purrr::map(data, ~direction_rel(.x)), sl = purrr::map(data, ~step_lengths(.x)), nsd_ = purrr::map(data, ~nsd(.x)) )
另外,也可以使用amt包提供的更简洁方式,无需手动嵌套后调用purrr:
# 直接按id分组计算所有指标 trk_metrics <- trk1 %>% group_by(id) %>% mutate( dir_abs = direction_abs(full_circle = TRUE, zero = "N"), dir_rel = direction_rel(), sl = step_lengths(), nsd_ = nsd() ) %>% ungroup()
内容的提问来源于stack exchange,提问作者Ellery Vincent

