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

R语言栅格处理临时文件占C盘,如何指定自定义临时目录?

问题解决:强制R/terra使用指定临时目录避免C盘空间耗尽

问题背景

编写了自定义函数处理CHIRPS、Modis、ERA5栅格堆栈(重采样、裁剪、写入),已将工作目录和自定义临时目录设为剩余空间充足的E盘路径E:/KLHK/KHG/1_Riau/R,但执行两次后C盘空间从172GB骤降至15GB。排查发现R仍在使用默认C盘临时目录(C://Users/.../AppData/Local/Temp)存储栅格临时文件,未使用指定目录。

核心原因

原代码中仅调用tempdir(tempdir_custom),但该函数仅用于获取临时目录路径,无法修改R或terra的临时目录配置。terra包有独立的临时目录管理机制,需同时配置R全局环境变量和terra专属选项。

解决方案

1. 全局设置R临时目录环境变量

在脚本开头通过Sys.setenv()设置TMPDIR环境变量,让R及依赖包优先使用该目录:

Sys.setenv(TMPDIR = tempdir_custom)

2. 设置terra包专属临时目录

terra包不会自动读取R的TMPDIR,需用terraOptions()单独配置:

terra::terraOptions(tempdir = tempdir_custom)

3. 提前设置临时目录

在加载terra包之后、处理栅格之前就完成上述配置,避免部分初始化操作已使用默认目录。

4. 可选:主动清理临时文件

处理完成后,可主动清理terra生成的临时文件,避免占用空间:

# 清理所有未使用的terra临时文件
terra::tmpFiles(remove = TRUE)

修改后的完整代码

# Load necessary libraries
library(terra)
library(progress)

setwd("E:/KLHK/KHG/1_Riau/R")

# Set the temporary directory for R's file usage
tempdir_custom <- "E:/KLHK/KHG/1_Riau/R"
# Ensure the temporary directory exists
if (!dir.exists(tempdir_custom)) {
  dir.create(tempdir_custom, recursive = TRUE)
}

# 关键修改:配置R全局临时环境变量和terra专属临时目录
Sys.setenv(TMPDIR = tempdir_custom)
terra::terraOptions(tempdir = tempdir_custom)
message("Temporary directory configured to:", tempdir_custom)

# Sequential resampling function with memory management and flexible resolution
sequential_resample <- function(raster, final_resolution = 10, method = "cubicspline") {
  current_res <- res(raster)
  resampled_raster <- raster  
  # Halve the resolution until the largest side reaches <= 2x final resolution
  while (max(current_res) > 2 * final_resolution) {
    target_res <- current_res / 2
    temp_target <- rast(ext(raster), res = target_res, crs = crs(raster))
    resampled_raster <- resample(resampled_raster, temp_target, method = method)
    current_res <- res(resampled_raster)
  }    
  # Final resampling to the exact final_resolution value
  final_target <- rast(ext(raster), res = c(final_resolution, final_resolution), crs = crs(raster))
  resampled_raster <- resample(resampled_raster, final_target, method = method)    
  return(resampled_raster)
}

# Function to resample, clip, stack, and write raster data
resample_clip_stack_write <- function(
  raster_data, 
  output_directory, 
  final_resolution = 10, 
  extent = NULL, 
  method = "cubicspline",
  stack_name = NULL
) {
  # Ensure the output directory exists
  if (!dir.exists(output_directory)) {
    dir.create(output_directory, recursive = TRUE)
    message("Created directory:", output_directory)
  } else {
    message("Directory already exists:", output_directory)
  }  

  # Initialize an empty list to store resampled and clipped raster layers
  resampled_layers <- list()  
  # Iterate over each layer in the raster stack
  for (i in 1:nlyr(raster_data)) {
    message(paste("Processing layer", i, "of", nlyr(raster_data)))    
    # Access the layer by index
    raster_layer <- raster_data[[i]]    
    # Apply sequential resampling
    resampled_layer <- sequential_resample(raster_layer, final_resolution, method)    
    # Clip the resampled layer if an extent is provided
    if (!is.null(extent)) {
      message("Clipping layer to extent...")
      if (inherits(extent, "SpatVector")) {
        resampled_layer <- crop(resampled_layer, extent)
      } else if (inherits(extent, "SpatRaster")) {
        resampled_layer <- mask(resampled_layer, extent)
      }
      message("Clipping complete.")
    }    
    # Store the processed layer
    resampled_layers[[i]] <- resampled_layer
  }  
  # Combine all processed layers into a single SpatRaster stack
  stacked_raster <- rast(resampled_layers)
  message("All layers combined into a single SpatRaster stack.")  
  # Determine the output file name
  output_file <- file.path(
    output_directory, 
    ifelse(is.null(stack_name), "Processed_Stack.tif", paste0(stack_name, ".tif"))
  )  
  # Write the resulting stack to disk
  writeRaster(stacked_raster, output_file, overwrite = TRUE)
  message("Stacked raster written to:", output_file)  

  # 可选:清理临时文件
  terra::tmpFiles(remove = TRUE)
  
  # Return the stacked raster as an in-memory SpatRaster object
  return(stacked_raster)
}

# Define AOI or raster for clipping
aoi_Riau <- vect("E:/KLHK/KHG/1_Riau/1_input/AOI/PHU_bound_10km.shp")  # Vector extent (AOI)

# Set the output directory and other parameters
output_res_riau <- "E:/KLHK/KHG/1_Riau/3_olah2/1_CHRIPS"

# Call the function to process rasters
res_Riau_precip_2021 <- resample_clip_stack_write(
  raster_data = Riau_precip_2021,
  output_directory = output_res_riau,
  final_resolution = 10,  # Target resolution
  extent = aoi_Riau,  # Shapefile AOI or raster for clipping
  method = "cubicspline",
  stack_name = "Riau_Precip_2021_Stack"  # Optional name for the resulting stack
)

验证方法

执行脚本后,可通过以下代码检查临时目录是否生效:

# 查看R全局临时目录
Sys.getenv("TMPDIR")
# 查看terra临时目录
terra::terraOptions("tempdir")

返回结果应均为指定的E盘路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 08:17:02