使用terra包时如何解决for循环中的bad:alloc内存错误?
栅格提取时的内存分配错误(bad:alloc)问题
我使用terra包编写代码,从一组多边形中提取栅格值。该栅格被划分为约20个分块(tile),通过for循环逐个处理。但程序总会触发bad:alloc错误(推测是内存不足导致),处理完约6个分块(跳过约3个与多边形无重叠的分块)后就会终止。
已尝试的解决方法
- 每次迭代后清理R生成的临时文件,同时设置terra的临时目录参数:
terraOptions(tempdir=tempdir, steps = 10) unlink(file.path(tempdir, "*"), recursive = TRUE) # 清理临时文件目录 - 将每个分块的结果数据表(含数千行)保存为RDS文件,避免内存堆积:
其中saveRDS(result, file=paste("./Cropped/HansenCover2000/Extract/", tileNumber, ".rds", sep=""))tileNumber随每次迭代自增1。 - 处理完当前分块后,从R环境中移除当前栅格对象和结果表,并手动触发垃圾回收:
rm(result, tile) gc() - 每个分块已提前根据多边形完成掩膜和裁剪,裁剪后的栅格大小在4MB到229MB之间。程序终止时并非处理最大的分块,且此前已成功处理过190MB的分块。
单独运行单个分块的代码可以正常执行,但放入for循环后就会出现错误。原本计划在terra::extract中添加exact=TRUE参数,但该操作会让内存问题更严重。
代码示例
cropCover2000 <- list.files("./Cropped/HansenCover2000", pattern="\\.tif$") # 获取裁剪后栅格的路径 dirCreate("./Cropped/HansenCover2000/Extract") tileNumber <-1 for(coverTiles in cropCover2000) # 遍历所有分块 { unlink(file.path(tempdir, "*"), recursive = TRUE) # 清理临时文件目录 tile <- rast(paste("./Cropped/HansenCover2000", coverTiles, sep="/")) # 读取分块栅格 result <- terra::extract(tile, species, na.rm=TRUE) colnames(result) <- c("ID", "Cover2000") result <- group_by(result, ID, Cover2000) %>% reframe(count=length(Cover2000), .groups="keep") saveRDS(result, file=paste("./Cropped/HansenCover2000/Extract/", tileNumber, ".rds", sep="")) tileNumber <- tileNumber +1 rm(result, tile) gc() }
循环完成后(目前尚未成功执行完毕),我会对生成的RDS文件进行后续处理。
内容的提问来源于stack exchange,提问作者Jacob Cummings
相关产品推荐
相关产品推荐

