使用aniMotum包时rep$pdHess错误修复及批量拟合ssm方法
问题1:Error in rep$pdHess 错误修复
这个错误本质是模型拟合过程中返回了原子向量而非预期的列表对象,通常和输入数据问题或模型收敛失败有关,结合你的数据片段,按以下步骤排查修复:
预处理输入数据:
你的数据存在三个明显问题,先处理这些问题:- 重复记录:多个完全相同的时间、位置、定位等级条目会干扰模型拟合,先去重:
Shark3_clean <- dplyr::distinct(Shark3, date, lat, lon, lc, .keep_all = TRUE)- 时间顺序混乱:比如08/11/2016的记录出现在03/19/2016之后,模型要求时间序列有序,先将date转为时间格式并排序:
Shark3_clean$date <- as.POSIXct(Shark3_clean$date, format = "%m/%d/%Y %H:%M:%S") Shark3_clean <- dplyr::arrange(Shark3_clean, id, date)- 定位等级(lc)格式不一致:数据中lc混合字母(A、B)和数字(0、1、2、3),需统一为字符型并过滤非标准值:
Shark3_clean$lc <- as.character(Shark3_clean$lc) Shark3_clean <- dplyr::filter(Shark3_clean, lc %in% c("A", "B", "0", "1", "2", "3"))调整模型拟合参数:
预处理后仍报错的话,大概率是模型收敛问题,尝试:- 增加迭代次数:在
ssm_control中设置maxit = 1000 - 更换优化方法:比如
method = "L-BFGS-B" - 先拟合普通连续随机游走模型(
model = "crw")验证数据可用性,再切换到move persistence模型:
fit_crw <- fit_ssm(Shark3_clean, vmax = 3, model = "crw", time.step = 24, control = ssm_control(verbose = 0, maxit = 1000)) # 若crw模型成功,再尝试mp模型 fit_mp <- fit_ssm(Shark3_clean, vmax = 3, model = "mp", time.step = 24, control = ssm_control(verbose = 0, maxit = 1000))- 增加迭代次数:在
问题2:批量处理60只动物的方法
用dplyr拆分数据+purrr批量拟合是最简便的方式,同时加入错误处理避免单个动物拟合失败中断整个流程:
步骤1:准备全量数据集
确保你的全量数据(包含所有60只动物)是一个数据框,列名包含id、date、lat、lon、lc。
步骤2:定义批量拟合函数
library(dplyr) library(purrr) library(aniMotum) # 定义单个动物的拟合函数,包含预处理和错误捕获 fit_single_shark <- function(shark_data) { # 数据预处理 clean_data <- shark_data %>% distinct(date, lat, lon, lc, .keep_all = TRUE) %>% mutate(date = as.POSIXct(date, format = "%m/%d/%Y %H:%M:%S")) %>% arrange(id, date) %>% mutate(lc = as.character(lc)) %>% filter(lc %in% c("A", "B", "0", "1", "2", "3")) # 尝试拟合模型,失败时返回错误信息并跳过 tryCatch({ fit_ssm(clean_data, vmax = 3, model = "mp", time.step = 24, control = ssm_control(verbose = 0, maxit = 1000)) }, error = function(e) { message(paste("ID", unique(shark_data$id), "拟合失败:", e$message)) return(NULL) }) }
步骤3:批量运行模型
# 按id拆分全量数据为列表 shark_data_list <- split(your_full_data, your_full_data$id) # 批量拟合所有模型 all_fits <- map(shark_data_list, fit_single_shark) # 过滤掉拟合失败的结果,只保留成功的模型 successful_fits <- compact(all_fits)
替代方案:用for循环实现
如果不习惯purrr,也可以用基础for循环:
all_fits <- list() unique_ids <- unique(your_full_data$id) for (id in unique_ids) { current_data <- filter(your_full_data, id == id) clean_data <- current_data %>% distinct(date, lat, lon, lc, .keep_all = TRUE) %>% mutate(date = as.POSIXct(date, format = "%m/%d/%Y %H:%M:%S")) %>% arrange(id, date) %>% mutate(lc = as.character(lc)) %>% filter(lc %in% c("A", "B", "0", "1", "2", "3")) tryCatch({ fit <- fit_ssm(clean_data, vmax = 3, model = "mp", time.step = 24, control = ssm_control(verbose = 0, maxit = 1000)) all_fits[[as.character(id)]] <- fit }, error = function(e) { message(paste("ID", id, "拟合失败:", e$message)) }) }
内容的提问来源于stack exchange,提问作者Sharklady
相关产品推荐
相关产品推荐

