如何使用sf按物种自动构建并绘制基于观测点的凸包?
用sf包自动化批量构建物种分布凸包
当然可行!而且用sf包完全能实现你想要的自动化批量处理,不用再手动复制代码逐个处理物种了。我来帮你把整个流程改成纯sf的实现方式,逻辑和你设想的几乎一致,而且更简洁统一:
步骤1:加载依赖包并读取数据
首先只加载需要的包,我们全程用sf处理空间操作,配合tidyverse做数据分组:
library(tidyverse) library(sf) library(maps) library(ggplot2) # 读取你的物种出现数据 fd <- read_csv("occurrence.csv")
步骤2:转换为sf点对象并批量构建凸包+缓冲区
核心是用group_by()按物种分组,然后通过summarize()对每组的点进行空间操作:
# 先把数据转换成sf点对象,指定经纬度字段和坐标系(这里用WGS84,EPSG:4326) fd_sf <- fd %>% st_as_sf(coords = c("lon", "lat"), crs = 4326) # 按物种分组,批量生成凸包和缓冲区 species_hulls <- fd_sf %>% group_by(species) %>% summarize( # 1. 把同物种的所有点合并成一个「多点几何对象」 geometry = st_union(geometry), # 2. 基于多点构建凸包 geometry = st_convex_hull(geometry), # 3. 给凸包添加缓冲区(这里dist单位是度,因为当前是地理坐标系;如果要米为单位,看后面的说明) geometry = st_buffer(geometry, dist = 1) ) %>% ungroup() # 可选:取消分组,方便后续操作
关键细节解释:
st_as_sf(coords = c("lon", "lat")):把普通的经纬度列转换成sf的空间几何字段,这是sf处理空间数据的基础。st_union(geometry):必须先把同物种的所有点合并成一个单一的几何对象,否则st_convex_hull()会给每个点单独生成凸包(毫无意义)。st_buffer():这里的dist=1单位是度(因为我们用的是WGS84地理坐标系)。如果需要更准确的距离(比如10公里),建议先转换到投影坐标系(比如UTM)处理,再转回来:# 示例:转换到UTM投影(需根据你的数据范围选择合适的UTM带,比如EPSG:32615对应北半球15带) fd_utm <- fd_sf %>% st_transform(crs = 32615) species_hulls_utm <- fd_utm %>% group_by(species) %>% summarize( geometry = st_union(geometry), geometry = st_convex_hull(geometry), geometry = st_buffer(geometry, dist = 10000) # 这里dist单位是米,代表10公里 ) %>% st_transform(crs = 4326) # 转换回WGS84用于绘图
步骤3:可视化物种分布区域
现在直接用sf的geom_sf()绘图,不用再像之前那样转换sp对象,更简洁:
# 读取世界地图数据并转换为sf对象 wrld2 <- st_as_sf(map('world2', plot = FALSE, fill = TRUE)) # 绘图 ggplot() + # 绘制世界底图 geom_sf(data = wrld2, fill = 'gray20', color = "lightgrey", size = 0.07) + # 绘制每个物种的凸包缓冲区,按物种区分颜色 geom_sf(data = species_hulls, aes(color = species), fill = NA, size = 1) + # 设置坐标范围,和你原来的一致 coord_sf(xlim = c(100, 300), ylim = c(-60, 60)) + # 自定义物种颜色(可选) scale_color_manual(values = c("sp.A" = "red", "sp.B" = "blue")) + theme_minimal()
这样不管你有多少个物种,代码都能自动批量处理,完全不用手动复制修改每个物种的代码~
内容的提问来源于stack exchange,提问作者Luther Blissett
相关产品推荐
相关产品推荐

