R使用foreach循环提取栅格数据时报NULL value passed as symbol address错误求助
错误原因
- 并行子进程无法访问主进程的特殊对象:你创建的
bi_2021是terra包的SpatRaster对象,底层绑定了C层面的指针,这类对象无法被foreach默认的导出机制正确传递到子进程,子进程拿到的是空指针,就会触发NULL value passed as symbol address报错。 - 子进程缺失必要依赖包:你在foreach的
.packages参数中仅声明了tidyverse和lubridate,操作SpatRaster所需的terra包没有被加载到子进程环境中,无法识别对应的索引操作语法。 - 代码存在隐性笔误:你代码中读取数据赋值给
data_df后,切片筛选用的是未定义的data对象,最终写入时用的final_df也没有定义,虽然你说单线程运行正常,大概率是复制代码时的疏漏,并行时会额外放大这类变量作用域问题。
解决方法
直接调整并行逻辑,避免跨进程传递SpatRaster指针,同时补全依赖,修改后的参考代码如下:
# 主进程仅定义公共参数,不要传递SpatRaster到子进程 cl <- makeCluster(2) registerDoParallel(cl) foreach (r=1:10, .packages = c('tidyverse','lubridate','terra')) %dopar% { # 子进程内部单独读取栅格文件,避免指针传递问题 bi_2021 <- rast('G:/GridMet_Yearly/bi_2021.nc') rc <- row_char[r] cc <- col_char[r] ce <- cell_char[r] rn <- row_num[r] cn <- col_num[r] fname <- paste0('G:/GridMet_Cells_RawData/row',rc,'_col',cc,'_cell',ce,'.csv') data_df <- data.frame(read_csv(fname, show_col_types = FALSE)) # 修正笔误:把data改成data_df data_df <- data_df[which(year(data_df$Date) < 2021),] # 追加2021年数据 data_df[15342:15673,] <- NA data_df$Date[15342:15673] <- seq(as.Date('2021-01-01'),as.Date('2021-11-28'),'days') data_df$bi[15342:15673] <- as.numeric(bi_2021[rn,cn,][1:332]) # 修正笔误:把final_df改成data_df write_csv(data_df,paste0('G:/GridMet_Cells_RawData2/row',rc,'_col',cc,'_cell',ce,'.csv')) rm(data_df,cc,ce,cn,fname,rc,rn,bi_2021) } stopCluster(cl)
如果你的栅格文件过大,子进程重复读取开销太高,可以先把需要提取的rn、cn对应的值在主进程批量提取成普通向量,再把向量传递到子进程使用,性能会更高。
内容的提问来源于stack exchange,提问作者user8229029
相关产品推荐
相关产品推荐

