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

使用自定义函数调用terra::aggregate时出现“类型不兼容”错误

问题诊断与解决方案

错误原因

报错Not compatible with requested type: [type=list; target=double]的核心问题是:你的自定义聚合函数lc_aggr在部分分组中返回了列表类型,但terra::aggregate要求函数必须返回单个标量数值(double/整数类型)。内置的"modal"函数能正常运行,是因为它严格保证返回单个值,且处理了空分组、NA等边界情况。

修正后的自定义聚合函数

结合你的需求(水体值占比超75%才保留,否则返回次常见值),以下是修正后的lc_aggr函数:

lc_aggr <- function(x, drop = 0, threshold = 0.75) {
  # 过滤NA值
  x <- x[!is.na(x)]
  # 处理全NA的空分组
  if (length(x) == 0) return(NA_real_)
  
  # 统计值的频次并按降序排序
  freq <- table(x)
  freq_df <- as.data.frame(freq, stringsAsFactors = FALSE)
  freq_df$Var1 <- as.numeric(freq_df$Var1)
  freq_df <- freq_df[order(-freq_df$Freq), ]
  
  # 计算最高频值的占比
  total <- sum(freq_df$Freq)
  top_ratio <- freq_df$Freq[1] / total
  
  # 判断是否返回水体值
  if (freq_df$Var1[1] == drop && top_ratio > threshold) {
    return(freq_df$Var1[1])
  } else {
    # 只有一种值时返回该值,否则返回次常见值
    return(ifelse(nrow(freq_df) >=2, freq_df$Var1[2], freq_df$Var1[1]))
  }
}

关键修正点

  • 明确过滤NA值,避免空分组引发的异常
  • 将table返回的结果转换为数值型DataFrame,杜绝列表结构输出
  • 所有分支均返回单个标量(NA_real_或单个数值),符合terra的要求
  • 处理分组内仅有一种值的边界情况

测试运行

将上述函数加入你的代码,替换原lc_aggr后执行:

devtools::install_github("bcknr/rlandfire")
library(rlandfire)
library(terra)

aoi <- c(-79.94116,  40.41411, -71.39884,  45.03770)
products <- "130EVC"
resolution <- 30
  
resp <- landfireAPI(products = products,
                    aoi = aoi, 
                    resolution = resolution)
  
dir.create(paste0(tempdir(),"/lf"))
utils::unzip(resp$path, exdir = paste0(tempdir(),"/lf"))
evc <- rast(paste0(tempdir(),"/lf/", resp$request$job_id,".tif"))
  
values(evc)[values(evc) != 11] <- 1
values(evc)[values(evc) == 11] <- 0

# 加载修正后的聚合函数
lc_aggr <- function(x, drop = 0, threshold = 0.75) {
  x <- x[!is.na(x)]
  if (length(x) == 0) return(NA_real_)
  
  freq <- table(x)
  freq_df <- as.data.frame(freq, stringsAsFactors = FALSE)
  freq_df$Var1 <- as.numeric(freq_df$Var1)
  freq_df <- freq_df[order(-freq_df$Freq), ]
  
  total <- sum(freq_df$Freq)
  top_ratio <- freq_df$Freq[1] / total
  
  if (freq_df$Var1[1] == drop && top_ratio > threshold) {
    return(freq_df$Var1[1])
  } else {
    return(ifelse(nrow(freq_df) >=2, freq_df$Var1[2], freq_df$Var1[1]))
  }
}
  
evc_aggr <- terra::aggregate(evc, fact = 33, fun = lc_aggr)

额外说明

  • 若水体值不是0,可通过terra::aggregate的...参数传递,例如:terra::aggregate(evc, fact=33, fun=lc_aggr, drop=11)
  • 调整占比阈值只需修改threshold参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:32:49