You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义函数在lidR包部分函数中失效,pixel_metrics报错找不到函数

lidR中catalog_apply与pixel_metrics对自定义公式函数的解析差异问题

问题背景

个人开发的R包中包含适配lidR的自定义函数,参考lidR作者的写法,将my_metrics封装为公式形式的简写.my_metrics,定义如下:

#' @rdname my_metrics
#' @export
.my_metrics = ~my_metrics(X, Y, Z, ReturnNumber, Classification, ScanAngleRank, ht_slice=1, ht_max=NULL, min_pts=0, sar_thr=NULL)

使用catalog_apply调用cloud_metrics时该函数正常工作:

ads = clip_roi(ctg, shp, radius=shp$plot_rad)
opt_chunk_buffer(ads) <- 0
opt_chunk_size(ads) <- 0
opt_output_files(ads) <- ""

metrics = catalog_apply(ads, cloud_metrics, func = .my_metrics)

但调用pixel_metrics时却报错cannot find function "my_metrics",只有将my_metrics手动加载到全局环境才能正常执行:

r = pixel_metrics(ctg, .my_metrics, res = gridRes)
# 错误: cannot find function "my_metrics"

已在包的DESCRIPTION文件的Depends部分添加lidR、terra、sf等依赖包。

原因分析

确实是catalog_apply与pixel_metrics的自定义函数解析机制存在差异:

  • catalog_apply执行时会继承调用时的环境(即你的R包命名空间环境),因此能正确找到包内定义的my_metrics函数。
  • pixel_metrics处理公式形式的参数时,默认会在全局环境中查找公式内引用的函数,而非包的命名空间环境。当my_metrics仅存在于包内部时,全局环境无法定位到该函数,从而触发报错。

解决方案

方法1:显式指定函数的命名空间

修改.my_metrics的定义,在my_metrics前加上你的包名,强制公式从包的命名空间中查找函数:

#' @rdname my_metrics
#' @export
.my_metrics = ~你的包名::my_metrics(X, Y, Z, ReturnNumber, Classification, ScanAngleRank, ht_slice=1, ht_max=NULL, min_pts=0, sar_thr=NULL)

这种方式直接且不会污染全局环境,是推荐的解决方案。

方法2:绑定公式的执行环境

创建公式时明确指定其执行环境为你的包命名空间,确保pixel_metrics能在正确环境中查找函数:

#' @rdname my_metrics
#' @export
.my_metrics = as.formula(
  "~my_metrics(X, Y, Z, ReturnNumber, Classification, ScanAngleRank, ht_slice=1, ht_max=NULL, min_pts=0, sar_thr=NULL)",
  env = asNamespace("你的包名")
)

该方式让公式的执行环境绑定到包的命名空间,避免依赖全局环境查找。

内容的提问来源于stack exchange,提问作者Nico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:53:16