使用sf包st_sample函数在多边形内生成随机点的for循环异常问题
问题原因与解决方法
核心问题1:对象类型不兼容
st_sample()是sf包的原生函数,仅支持sf/sfc类空间对象,你当前传入的是terra包的vect类对象,函数无法正确识别要素结构导致返回结果异常。
核心问题2:列表赋值语法错误
使用empty_list[i]对列表槽位赋值时,R会强制将右侧结果压缩为单元素匹配槽位,因此哪怕st_sample返回5个点,最终也只会保留第一个值。正确的列表多元素赋值需要使用双中括号empty_list[[i]]。
修正代码
方案1:修正原for循环逻辑
library(terra) library(sf) # 读取多边形并转为sf对象 v <- vect(system.file("ex/lux.shp", package="terra")) v_sf <- st_as_sf(v[c(1:10)]) # 预定义指定长度的空列表提升性能 empty_list <- vector("list", length(v_sf$ID_1)) # 修正后的for循环 for(i in seq_along(v_sf$ID_1)){ empty_list[[i]] <- st_sample(x = v_sf[i,], size = 5, type = "random", exact = TRUE) } # 合并所有点为单一sf对象 all_points <- st_sfc(unlist(empty_list, recursive = FALSE), crs = st_crs(v_sf))
方案2:无需循环的向量化实现(更简洁)
st_sample本身支持多面要素批量采样,直接指定每个要素的采样数量即可,无需手动写循环:
library(terra) library(sf) v <- vect(system.file("ex/lux.shp", package="terra")) v_sf <- st_as_sf(v[c(1:10)]) # 直接批量采样,每个多边形5个点 all_points <- st_sample(x = v_sf, size = rep(5, nrow(v_sf)), type = "random", exact = TRUE, by_polygon = TRUE)
两种方案最终都能得到10个多边形各5个、共50个随机点的结果。
内容的提问来源于stack exchange,提问作者seak23
相关产品推荐
相关产品推荐

