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

使用raster::calc自定义函数时遇错误的技术求助

问题描述

我生成了包含175个栅格的class.stack,每个栅格单元取值为0-3的整数或NA,且所有栅格的NA位置完全一致(代表未采样区域)。我需要基于该栅格栈计算一个新栅格:若0为多数类别则取0,否则取1-3的整数均值。

最初编写了如下自定义函数用于calc:

class.cond <- function(x){
if (sum(x == 0) > sum(x != 0)) {0}
else {round(mean(x != 0))}
}

了解到该函数无法正常运行,因为calc采用分块处理数据。随后尝试统计各类别的出现次数,代码如下:

count.zero <- calc(class.stack, na.rm=TRUE, fun=function(x){sum(x == 0)})

执行时出现错误:

Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) :
cannot use this function. Perhaps add '...' or 'na.rm' to the function arguments?

尝试通过忽略NA修改函数:

count.zero <- calc(class.stack, na.rm=TRUE, fun=function(x){
                     y <- as.numeric(na.omit(x))
                     sum(y == 0)})

但仍报相同错误。不过相同逻辑在向量测试中可正常运行:

test.vec <- c(NA, NA, 0, 0, 1, 2, 2, 3, 0, NA, 0, 1, 2)
mod.vec <- as.numeric(na.omit(test.vec))
print(mod.vec)
[1] 0 0 1 2 2 3 0 0 1 2
print(sum(mod.vec == 0))
[1] 4
print(sum(mod.vec == 2))
[1] 3

请问我哪里出错了?


问题原因与解决办法

报错的核心原因是:当你在calc中设置na.rm=TRUE时,这个参数会被传递给自定义函数,但你的函数并没有定义na.rm参数(也没通过...接收额外参数),导致calc无法完成参数传递,进而报错。

1. 修正统计0出现次数的代码

给自定义函数添加na.rm参数,或者用...接收额外参数,同时利用na.rm处理NA,不用手动na.omit:

# 方式1:显式定义na.rm参数
count.zero <- calc(class.stack, na.rm=TRUE, fun=function(x, na.rm){
  sum(x == 0, na.rm = na.rm)
})

# 方式2:用...接收额外参数
count.zero <- calc(class.stack, na.rm=TRUE, fun=function(x, ...){
  sum(x == 0, ...)
})

2. 直接完成最终需求的修正函数

写一个能处理NA、接收na.rm参数的函数,一次性实现你的需求:

class.cond <- function(x, na.rm = FALSE){
  # 统计0的出现次数(忽略NA)
  n_zero <- sum(x == 0, na.rm = na.rm)
  # 统计1-3的出现次数(忽略NA)
  n_nonzero <- sum(x %in% 1:3, na.rm = na.rm)
  
  if(n_zero > n_nonzero){
    return(0)
  } else {
    # 提取1-3的值,计算均值后取整
    mean_val <- mean(x[x %in% 1:3], na.rm = na.rm)
    return(round(mean_val))
  }
}

# 调用calc生成结果栅格
result_raster <- calc(class.stack, fun = class.cond, na.rm = TRUE)

补充说明

因为所有栅格的NA位置完全一致,na.rm=TRUE会自动忽略这些未采样区域,不需要手动na.omit,这样既符合calc的分块处理逻辑,效率也更高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:56:00