使用soap平滑项运行GAM模型报错:数据超出soap边界
我运行了一个带有soap平滑项的GAM模型,代码如下:
mod_aut_X10 <- bam(occurrenceStatus ~ s(x, y, bs = "so", xt = list(bnd = shap_bnd_ls, nmax = 1000)) + s(watertemp) + s(WaterDepth) + s(lunar_day, bs = "cc") + s(hour_of_day, bs = "cc") + s(distAbs) + s(distStInp)+ s(distLPInp)+ s(Abs_Max_ls)+ s(InpSt_Max_ls)+ s(InpLP_Max_ls)+ offset(log(cumulative_count)), data = filter(eel.Agg.70, season == 'Autumn'), family = binomial(link = "logit"), method = "fREML", discrete = TRUE, knots = lake_knots, weights = weight)
运行时出现报错:
Error in smooth.construct.so.smooth.spec(object, dk$data, dk$knots) : data outside soap boundary
我已经在运行模型前通过代码过滤掉shapefile边界外的数据点,这个逻辑在小数据集上运行正常,但此次数据集更大,即使给shapefile添加缓冲区,报错仍存在。请问还有哪些可能导致该报错的原因?
可能的原因如下:
坐标精度与浮点误差:浮点运算的精度差异可能导致部分数据点被误判为在边界外。比如数据集坐标和shapefile边界的精度不一致,微小的数值差触发了
soap平滑的边界判定逻辑。可以尝试给边界加极小缓冲区(如st_buffer(shap_bnd_ls, 0.0001)),或用st_snap将数据点对齐到边界。边界几何有效性问题:
shap_bnd_ls可能存在几何无效情况,比如多边形未闭合、自相交,或包含未正确处理的洞。soap平滑对边界几何要求严格,无效边界会让内部点被误判为外部。用st_is_valid(shap_bnd_ls)检查有效性,再用st_make_valid(shap_bnd_ls)修复。Knots结点超出边界:传入的
lake_knots中可能存在位于边界外的结点。soap平滑不仅要求数据点在边界内,构建平滑的knots也必须在边界范围内。提取lake_knots的坐标,用st_within检查是否都在shap_bnd_ls内部,过滤掉外部结点。过滤逻辑未处理多边形洞:如果shapefile是带洞的多边形(比如湖中有小岛),之前的过滤代码可能只判断了点是否在外部多边形内,未排除洞里的点。而
soap平滑不允许点落在洞区域,这会触发报错。需要修改过滤逻辑,确保点不在任何洞的范围内。离散化参数的副作用:模型使用了
discrete = TRUE,该参数会对数据离散化以提速,但可能在离散化过程中生成的临时点超出边界。先禁用discrete参数测试,若报错消失,说明是离散化导致的问题,再调整nmax等参数。坐标参考系(CRS)不匹配:数据集的
x、y坐标与shap_bnd_ls的CRS可能不一致,导致空间位置判断错误,过滤操作无效。用st_crs检查两者CRS是否一致,若不一致,用st_transform转换其中一方的CRS。
内容的提问来源于stack exchange,提问作者mikejwilliamson

