使用geosphere包centroid函数编写For循环计算质心报错求助
问题:按track_ID计算坐标质心并生成汇总数据框
我有一个包含451个唯一track_ID的数据框tow_dat,每个ID对应约125条经纬度观测值。我想生成一个包含所有ID质心经纬度的数据框,于是尝试用For循环实现:先创建空数据框,再循环将每个ID的质心结果存入其中。
我的代码:
forage.central <- as.tibble(data.frame(matrix(ncol = 2, nrow = 451))) for(i in unique(tow_dat$track_ID)){ current_data <- tow_dat %>% filter(track_ID == i) %>% dplyr::select(lon,lat) print(centroid(current_data)) forage.central[i] <- centroid(current_data) }
运行后报错:
lon lat [1,] 151.9351 -27.58116 Error in `[<-`: ! Can't recycle input of size 2 to size 1. Run `rlang::last_trace()` to see where the error occurred.
错误原因
forage.central[i]是选中数据框的第i列,但centroid()返回的是包含经度、纬度的长度为2的向量,试图把长度2的向量塞进长度1的列位置,就会触发维度不匹配的报错。另外,unique(tow_dat$track_ID)的结果可能不是连续的整数(比如ID是字符串或非连续数字),直接用它作为行索引会导致位置错乱。
解决方法
方法1:修复For循环
- 先提取所有唯一的track_ID并存储为向量,用索引循环而非ID值
- 用
forage.central[row_idx, ]选中对应行,存入质心向量 - 给结果数据框命名列名,方便识别
# 提取唯一ID列表 unique_ids <- unique(tow_dat$track_ID) # 创建空数据框,指定列名和行长度 forage.central <- tibble( track_ID = unique_ids, lon = numeric(length(unique_ids)), lat = numeric(length(unique_ids)) ) # 按索引循环处理每个ID for(row_idx in seq_along(unique_ids)){ current_id <- unique_ids[row_idx] current_data <- tow_dat %>% filter(track_ID == current_id) %>% select(lon, lat) # 获取质心并赋值到对应行的经纬度列 current_centroid <- centroid(current_data) forage.central[row_idx, c("lon", "lat")] <- current_centroid }
方法2:用dplyr分组计算(更高效简洁)
R中处理分组统计优先用dplyr的分组函数,代码更简洁且避免循环的效率问题:
library(dplyr) forage.central <- tow_dat %>% group_by(track_ID) %>% summarise( lon = centroid(cbind(lon, lat))[1], # 提取质心的经度值 lat = centroid(cbind(lon, lat))[2], # 提取质心的纬度值 .groups = "drop" # 计算完成后取消分组 )
补充:如果
centroid函数(常见于sp或sf包)要求输入空间对象,可先将经纬度转换为空间点再计算,示例如下:library(sf) forage.central <- tow_dat %>% group_by(track_ID) %>% summarise( # 将当前组的经纬度转为多点对象,再计算质心 centroid = st_sfc(st_centroid(st_multipoint(cbind(lon, lat)))), .groups = "drop" ) %>% # 从空间对象中提取经纬度坐标 st_coordinates(centroid) %>% as_tibble() %>% rename(lon = X, lat = Y) %>% # 关联track_ID bind_cols(tow_dat %>% distinct(track_ID))
内容的提问来源于stack exchange,提问作者Matt-W22
相关产品推荐
相关产品推荐

