如何正确将函数结果传入另一函数(MCP家域计算场景)
解决年度遥测数据的MCP家域计算问题
原代码核心问题分析
- 函数依赖全局变量而非输入参数:原
MCP函数直接调用全局的buffalo.sp_list,未利用传入的参数,导致无法针对每个年度的个体数据精准计算。 - 循环次数逻辑错误:原循环使用
length(buffalo.sp_list)(即年度数量2)作为循环次数,而非每个年度内的个体数量,因此每个年度仅输出2个结果,而非实际个体数。 - 坐标提取方式脆弱:原
buffalo.sp函数用固定索引[[5]]/[[6]]提取坐标,若遥测对象结构变化会直接出错,应改用列名提取。
修正后的完整代码及说明
1. 优化个体空间点数据生成函数
library(ctmm) library(ggplot2) library(dplyr) library(stringr) library(lubridate) library(sf) library(tidyverse) library(sp) library(scales) library(tidyr) library(tibble) library(adehabitatHR) # 加载数据 data("buffalo") # 合并个体数据并处理时间列 buffalo2 <- bind_rows( as.data.frame(buffalo$Cilla) %>% mutate(id = "Cilla"), as.data.frame(buffalo$Gabs) %>% mutate(id = "Gabs"), as.data.frame(buffalo$Mvubu) %>% mutate(id = "Mvubu"), as.data.frame(buffalo$Pepper) %>% mutate(id = "Pepper"), as.data.frame(buffalo$Queen) %>% mutate(id = "Queen"), as.data.frame(buffalo$Toni) %>% mutate(id = "Toni") ) %>% mutate( timestamp = ymd_hms(timestamp), Year = factor(year(timestamp)), UTM.zone = "12 +datum=NAD27", date = date(timestamp), time = hms::as_hms(timestamp) ) %>% select(id, Year, longitude, latitude, UTM.zone, date, time, timestamp) # 按年份拆分数据并转换为遥测对象 Tdata <- list( Tdata2005 = as.telemetry(filter(buffalo2, Year == 2005), timeformat="auto", timezone="UTC", timeout=Inf, datum="NAD27", na.rm="row", mark.rm=FALSE), Tdata2006 = as.telemetry(filter(buffalo2, Year == 2006), timeformat="auto", timezone="UTC", timeout=Inf, datum="NAD27", na.rm="row", mark.rm=FALSE) )
2. 生成个体空间点数据列表
buffalo.sp <- function(telemetry_data) { buffalo.sp_data <- list() # 遍历每个个体的遥测数据 for (i in seq_along(telemetry_data)) { coords <- data.frame( ID = names(telemetry_data)[i], X = telemetry_data[[i]]$longitude, Y = telemetry_data[[i]]$latitude ) coordinates(coords) <- c("X", "Y") proj4string(coords) <- proj4string(telemetry_data[[i]]) buffalo.sp_data[[i]] <- coords } names(buffalo.sp_data) <- names(telemetry_data) return(buffalo.sp_data) } # 生成年度空间点数据列表 buffalo.sp_list <- lapply(Tdata, buffalo.sp)
3. 计算MCP家域
calculate_MCP <- function(spatial_points_list, percent = 95) { mcp_results <- list() # 遍历每个个体计算MCP for (i in seq_along(spatial_points_list)) { mcp_results[[i]] <- mcp(spatial_points_list[[i]], percent = percent) } names(mcp_results) <- names(spatial_points_list) return(mcp_results) } # 生成年度MCP结果列表 MCP_list <- lapply(buffalo.sp_list, calculate_MCP)
4. 验证结果
# 查看2005年MCP结果数量(应为4) length(MCP_list$Tdata2005) # 查看2006年MCP结果数量(应为2) length(MCP_list$Tdata2006)
内容的提问来源于stack exchange,提问作者Jason Edelkind
相关产品推荐
相关产品推荐

