在spatstat中基于自定义Bounding Box删除重叠点的技术问询
关于spatstat中基于点外接矩形的重叠判定与点筛选问题
我正在使用R语言的spatstat包处理带标记的点模式数据,标记变量包含Name、boxA、boxB,其中boxA和boxB是每个点对应的外接矩形(bounding boxes)的尺寸。数据按Name拆分后的结果如下:
> split(u) # splits pattern in two classes of cells accord. to Name Point pattern split by factor negat: Marked planar point pattern: 843917 points Mark variables: Name, boxA, boxB window: rectangle = [3164, 66924] x [25085, 84325] units posit: Marked planar point pattern: 93569 points Mark variables: Name, boxA, boxB window: rectangle = [3164, 66924] x [25085, 84325] units
此前我通过固定半径的closepairs和crosspairs函数删除落在其他点外接矩形内的点,代码如下:
for (i in 1:length(names(u))) { if (names(u)[i] == "posit"){ R <- 20 }else{R <- 13} close_list = closepairs(u[[i]], rmax = R, twice = FALSE) close_index <- close_list$j if(is.empty(close_index) == F){ u[[i]] <- u[[i]][-close_index] } } close_list <- NULL close_list = crosspairs(u$negat, u$posit, 13) close_index <- close_list$i if(is.empty(close_index) == F){u$negat <- u$negat[-close_index]}
但由于同类别内各点的外接矩形尺寸差异较大,固定半径的判定方式不够精准,因此提出以下两个问题:
spatstat是否有内置函数可根据每个点的boxA或boxB单独确定判定半径?spatstat是否支持直接使用每个点的矩形尺寸(而非圆形区域)进行重叠判定?
另外,我基于Adrian Baddeley提供的思路实现了小样本测试代码,用于找出被其他点外接矩形包含的点,该代码在小测试集上运行正常,接下来会在真实数据中验证:
# pattern X<-as.ppp(cbind(c(1,2.5,2,3),c(1,1,3,3)),c(0,5,0,5)) # marks (size of the bounding boxes (BB) around points) M<-cbind("boxA"=c(1.5,2,4,3),"boxB"=c(1.5,2,4,3)) M<-as.data.frame(M) X$marks<-M # find and delete points inside BB of other points df <- as.data.frame(X) dx <- with(df, outer(x, x, "-")) dy <- with(df, outer(y,y,"-")) conflict <- (abs(dx) < df$boxA/2) & (abs(dy) < df$boxB/2) diag(conflict) <- FALSE conflict[upper.tri(conflict)] <- FALSE index<-c() for(i in 1:dim(conflict)[1]){ for(j in 1:dim(conflict)[2]){ if(conflict[i,j] == TRUE){ index <- c(index, i)} } } X<-X[-index]
问题解答与优化建议
1. 个性化判定半径的实现
spatstat的closepairs和crosspairs函数目前不支持直接传入每个点的个性化半径,但可以通过以下方式实现类似逻辑:
- 先为每个点计算对应的判定半径(例如取
boxA/2、boxB/2或两者的最大值),并添加到点标记中; - 使用
pairdist(同类别点对)或crossdist(跨类别点对)计算点间距离,再结合每个点的半径筛选出满足条件的点对。
2. 基于矩形的重叠判定优化
spatstat没有专门的内置函数直接处理这种点外接矩形的重叠判定,但可以通过向量化运算替代嵌套循环来大幅提升大样本数据的处理效率,优化后的代码如下:
# 优化后的外接矩形包含判定 df <- as.data.frame(X) # 计算所有点对的x、y坐标差 dx <- outer(df$x, df$x, "-") dy <- outer(df$y, df$y, "-") # 判定点i是否被点j的外接矩形完全包含 conflict <- (abs(dx) < df$boxA/2) & (abs(dy) < df$boxB/2) # 排除自身对比 diag(conflict) <- FALSE # 只保留下三角矩阵避免重复判定 conflict[upper.tri(conflict)] <- FALSE # 直接筛选出被包含的点索引 index <- which(rowSums(conflict) > 0) # 删除目标点 X <- X[-index]
3. 大样本数据处理补充建议
针对你真实数据中百万级别的点,outer函数可能会占用较多内存,此时可以考虑:
- 使用
spatstat的空间分块工具(如split.ppp结合象限划分),将数据拆分为小区域分别处理,再合并结果; - 如果需要判断矩形部分重叠而非完全包含,可以基于
spatstat.geom的owin对象创建每个点的外接矩形,再使用overlap.owin函数判断矩形间的重叠关系。
内容的提问来源于stack exchange,提问作者Sergej S
相关产品推荐
相关产品推荐

