在自定义terra::extract函数中实现进度输出与结果存储(大栅格文件)
解决terra::extract自定义函数中打印多边形ID与输出CSV的问题
核心问题分析
原代码的自定义函数无法直接获取多边形ID,且CSV写入方式会导致格式混乱。以下是针对两个目标的具体解决方案:
一、打印多边形ID追踪处理进度
terra::extract的默认自定义函数仅能拿到当前多边形对应的栅格值矩阵,无法直接获取ID。通过遍历每个多边形的方式,可以直接拿到当前处理的ID,实现实时进度打印。
二、结构化输出至CSV文件
原代码用cat拼接数值的方式会丢失表头、格式混乱。建议将每个多边形的结果整理为数据框,再按规范写入CSV,保证可读性和可校验性。
修改后的完整可运行代码
library(terra) # 模拟基础数据(补充原代码中未定义的对象) r <- rast(ncol=100, nrow=100) # 创建基础栅格 v <- vect(randomPoints(r, 10), "polygons", radius=5) # 创建10个模拟多边形 # 构建带NA值的多波段栅格(保留原代码逻辑) x1 <- r vals <- sample(10, ncell(r), replace = TRUE) x <- sort(sample(ncell(r), 200)) x <- c(x, x + 1) vals[x] <- NA values(x1) <- vals x1 <- ifelse(is.na(r), NA, x1) names(x1) <- "testvals" rr <- c(r, x1) # 合并为2波段栅格 # 输出文件路径 of <- "tmp.csv" # 初始化结果存储列表 result_list <- list() # 遍历每个多边形处理 for (poly_id in 1:nrow(v)) { # 打印当前处理的多边形ID cat("正在处理多边形ID:", poly_id, "\n") # 提取当前多边形的栅格值 poly_vals <- terra::extract(rr, v[poly_id, ], ID = FALSE) # 计算自定义统计量(适配多波段栅格) sums <- colSums(poly_vals, na.rm = TRUE) pxlscount <- colSums(!is.na(poly_vals)) # 整理为结构化数据框 result_row <- data.frame( 多边形ID = poly_id, 波段r求和 = sums[1], 波段testvals求和 = sums[2], 波段r有效像素数 = pxlscount[1], 波段testvals有效像素数 = pxlscount[2] ) # 加入结果列表 result_list[[poly_id]] <- result_row # 边处理边写入CSV(避免大内存占用) if (poly_id == 1) { write.csv(result_row, file = of, row.names = FALSE) # 第一行写入表头 } else { write.table(result_row, file = of, row.names = FALSE, col.names = FALSE, append = TRUE, sep = ",") # 后续行追加 } } # 合并所有结果到内存(可选,用于后续分析) out <- do.call(rbind, result_list)
关键修改说明
- 进度追踪:通过
for循环直接获取poly_id,实时打印当前处理的多边形编号,清晰追踪大型数据集的处理进度。 - CSV输出优化:
- 用
data.frame结构化存储结果,自定义列名便于校验 - 第一行写入表头,后续行仅追加数据,保证CSV格式规范
- 用
- 多波段适配:用
colSums同时处理多波段栅格的统计量,避免重复代码。
内容的提问来源于stack exchange,提问作者herry
相关产品推荐
相关产品推荐

