gpt4 book ai didi

r - 避免在 R 中的 foreach 循环中增加内存

转载 作者:行者123 更新时间:2023-12-03 17:37:43 25 4
gpt4 key购买 nike

我尝试创建结合两个不同空间数据集的汇总统计数据:一个大栅格文件和一个多边形文件。这个想法是获取每个多边形内栅格值的汇总统计信息。

由于栅格太大而无法立即处理,我尝试创建子任务并并行处理它们,即处理 SpatialPolgyonsDataframe 中的每个多边形。立刻。

代码运行良好,但是经过大约 100 次交互后,我遇到了内存问题。这是我的代码以及我打算做什么:

# session setup
library("raster")
library("rgdal")

# multicore processing.
library("foreach")
library("doSNOW")
# assign three clusters to be used for current R session
cluster = makeCluster(3, type = "SOCK",outfile="")
registerDoSNOW(cluster)
getDoParWorkers()# check if it worked

# load base data
r.terra.2008<-raster("~/terra.tif")
spodf.malha.2007<-readOGR("~/,"composed")

# bring both data-sets to a common CRS
proj4string(r.terra.2008)
proj4string(spodf.malha.2007)
spodf.malha.2007<-spTransform(spodf.malha.2007,CRSobj = CRS(projargs = proj4string(r.terra.2008)))
proj4string(r.terra.2008)==proj4string(spodf.malha.2007) # should be TRUE

# create a function to extract areas
function.landcover.sum<-function(r.landuse,spodf.pol){
return(table(extract(r.landuse,spodf.pol)))}

# apply it one one subset to see if it is working
function.landcover.sum(r.terra.2008,spodf.malha.2007[1,])

## parallel loop
# define package(s) to be use in the parallel loop
l.packages<-c("raster","sp")

# try a parallel loop for the first 6 polygons
l.results<-foreach(i=1:6,
.packages = l.packages) %dopar% {
print(paste("Processing Polygon ",i, ".",sep=""))
return(function.landcover.sum(r.terra.2008,spodf.malha.2007[i,]))
}

这里的输出是一个看起来像这样的列表。

l.results


[[1]]

9 10
193159 2567

[[2]]

7 9 10 12 14 16
17 256 1084 494 67 15

[[3]]

3 5 6 7 9 10 11 12
2199 1327 8840 8579 194437 1061 1073 1834
14 16
222 1395

[[4]]

3 6 7 9 10 12 16
287 102 728 329057 1004 1057 31

[[5]]

3 5 6 7 9 12 16
21 6 20 495 184261 4765 28

[[6]]

6 7 9 10 12 14
161 161 386 943 205 1515

所以结果相当小,不应该是内存分配问题的根源。因此,在具有 >32.000 行的整个多边形数据集上的以下循环创建了大约 100 次迭代后超过 8GB 的​​内存分配。
# apply the parallel loop on the whole dataset
l.results<-foreach(i=1:nrow(spodf.malha.2007),
.packages = l.packages) %dopar% {
print(paste("Processing Polygon ",i, ".",sep=""))
return(function.landcover.sum(r.terra.2008,spodf.malha.2007[i,]))
# gc(reset=TRUE) # does not resolve the problem
# closeAllConnections() # does not resolve the problem
}

我究竟做错了什么?

编辑:
我尝试(如评论中建议的那样)在内部循环中的每次迭代后删除对象,但它没有解决问题。我还尝试通过首先将对象传递给环境来解决多个数据导入的最终问题:
clusterExport(cl = cluster,
varlist = c("r.terra.2008","function.landcover.sum","spodf.malha.2007"))

没有大的变化。我的 R 版本在 linux 平台上是 3.4,所以据说第一条评论中的链接补丁也应该已经包含在这个版本中。我也试过 parallel第一条评论中建议的包,但没有出现差异。

最佳答案

你可以试试exact_extractexactextractr包裹。是从栅格中提取值的最快且内存更安全的函数。 main 函数是用 C++ 实现的,通常不需要并行化。由于您没有提供任何示例数据,我发布了一个包含真实数据的示例:

library(raster)
library(sf)
library(exactextractr)


# Pull municipal boundaries for Brazil
brazil <- st_as_sf(getData('GADM', country='BRA', level=2))

# Pull gridded precipitation data
prec <- getData('worldclim', var='prec', res=10)
#transform precipitation data in a dummy land use map
lu <- prec[[1]]
values(lu) <- sample(1:10,ncell(lu),replace = T)
plot(lu)

#extract land uses class for each pixel inside each polygon
ex <- exact_extract(lu, brazil)
#apply table to the resulting list. Here I use just the first 5 elements to avoid long output

lapply(ex[1:5],function(x){
table(x[,1])#note that I use x[,1] because by default exact_extract provide in the second column the coverage fraction of each pixel by each polygon
})
这里的示例输出:
[[1]]

1 2 4 6 7 9 10
1 1 1 2 3 1 1

[[2]]

2 3 4 5 6 7 8 10
2 4 3 2 1 2 2 2

[[3]]

1 2 4 6 7 8 9 10
4 5 1 1 4 2 5 5

[[4]]

1 2 3 4 5 6 7 8 9 10
2 2 4 2 2 4 1 4 1 2

[[5]]

3 4 5 6 8 10
2 3 1 1 2 3

关于r - 避免在 R 中的 foreach 循环中增加内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44507456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com