英文:
How to loop an entire script in R
问题
我有一个很长的脚本,其中包含许多数据操作,完整地分享可能会太长,但我将分享一些部分以阐明我的目的。
脚本中有一个函数会生成随机点,所以我创建的最终对象总是不同的。我想要做的是将整个脚本循环运行100次,并将许多生成的对象存储在一个列表中。
以下是脚本的一部分:
```R
area <- read_sf("area_erase.shp")
#栅格列表
agrilist <- sprintf('p%s_agriprop.tif', 1:6)
results_agri <- lapply(agrilist, raster)
results_agri <- setNames(results_agri, agrilist)
#第二个栅格列表
poplist <- sprintf('p%s_pop.tif', 1:6)
results_pop <- lapply(poplist, raster)
results_pop <- setNames(results_pop, poplist)
#对其中一个栅格进行重采样
results_agri[[6]] <- resample(results_agri[[6]],results_agri[[5]],method="bilinear")
#堆叠它们
allrasters <- mapply(raster::stack,results_agri,results_pop)
#加载现有点
pointslist <- sprintf('p%s_utm_n.csv', 1:6)
results_points <- lapply(pointslist, read.csv)
results_points <- setNames(results_points, pointslist)
#为提取准备(仅经度和纬度列)
extr <- function(xts.obj){xts.obj[,c(2:3)]}
points_xy <- lapply(results_points, extr)
等等,等等
'随机' 部分,确保每次运行脚本时都会产生不同的结果如下:
#创建随机点
pas[[1]] <- randomPoints(results_agri[[1]],n=1082,p=points_xy[[1]],ext=area)
pas[[2]] <- randomPoints(results_agri[[1]],n=2506,p=points_xy[[2]],ext=area)
pas[[3]] <- randomPoints(results_agri[[1]],n=2326,p=points_xy[[3]],ext=area)
pas[[4]] <- randomPoints(results_agri[[1]],n=3168,p=points_xy[[4]],ext=area)
pas[[5]] <- randomPoints(results_agri[[1]],n=3216,p=points_xy[[5]],ext=area)
pas[[6]] <- randomPoints(results_agri[[1]],n=3176,p=points_xy[[6]],ext=area)
然后脚本的最后一部分:
#最终值
st1 <- cellStats(prediction1>tr1,sum)
st2 <- cellStats(prediction2>tr2,sum)
st3 <- cellStats(prediction3>tr3,sum)
st4 <- cellStats(prediction4>tr4,sum)
st5 <- cellStats(prediction5>tr5,sum)
st6 <- cellStats(prediction6>tr6,sum)
这6个对象每个都是一个单一的数值,每次脚本迭代时会有所不同,所以我想每次迭代结束时运行这些代码100次,并将输出存储在一个列表中。
我该如何做?我考虑过使用 'repeat' 循环,但不确定如何将最终的对象存储在一个列表中,并在完成100次迭代后退出循环。
<details>
<summary>英文:</summary>
I have a long script with a lot of data manipulations, which would be too long to share completely, but I will share some parts as to clarify what I am out for.
There is one function within the script that generates random points, so the final objects I create are always different. What I want to do is loop the entire script 100 times, and store the many resulting objects in a list.
Here is some of the script
area <- read_sf("area_erase.shp")
#List of rasters
agrilist <- sprintf('p%s_agriprop.tif', 1:6)
results_agri <- lapply(agrilist, raster)
results_agri <- setNames(results_agri, agrilist)
#List of second rasters
poplist <- sprintf('p%s_pop.tif', 1:6)
results_pop <- lapply(poplist, raster)
results_pop <- setNames(results_pop, poplist)
#resample one of the rasters
results_agri[[6]] <- resample(results_agri[[6]],results_agri[[5]],method="bilinear")
#stack them
allrasters <- mapply(raster::stack,results_agri,results_pop)
#load in existing points
pointslist <- sprintf('p%s_utm_n.csv', 1:6)
results_points <- lapply(pointslist, read.csv)
results_points <- setNames(results_points, pointslist)
#prepare for extract (lon lat cols only)
extr <- function(xts.obj){xts.obj[,c(2:3)]}
points_xy <- lapply(results_points, extr)
etc, etc
The 'random' part, which ensures a different result each time the script is run is as follows
#create random points
pas[[1]] <- randomPoints(results_agri[[1]],n=1082,p=points_xy[[1]],ext=area)
pas[[2]] <- randomPoints(results_agri[[1]],n=2506,p=points_xy[[2]],ext=area)
pas[[3]] <- randomPoints(results_agri[[1]],n=2326,p=points_xy[[3]],ext=area)
pas[[4]] <- randomPoints(results_agri[[1]],n=3168,p=points_xy[[4]],ext=area)
pas[[5]] <- randomPoints(results_agri[[1]],n=3216,p=points_xy[[5]],ext=area)
pas[[6]] <- randomPoints(results_agri[[1]],n=3176,p=points_xy[[6]],ext=area)
And then the final part of the script,
#Final values
st1 <- cellStats(prediction1>tr1,sum)
st2 <- cellStats(prediction2>tr2,sum)
st3 <- cellStats(prediction3>tr3,sum)
st4 <- cellStats(prediction4>tr4,sum)
st5 <- cellStats(prediction5>tr5,sum)
st6 <- cellStats(prediction6>tr6,sum)
These 6 objects are a single numeric value each, and will differ every iteration the script, so I'd like to run these 100 times too, one time at the end of each iteration, and then store the output in a list
How would I go about this? I was thinking about a 'repeat' loop, but am unsure how to store the final objects in a list and break the loop once there's 100 iterations done.
</details>
# 答案1
**得分**: 1
如果我正确理解问题,您可以使用一个`for()`循环从1到100,每次将结果的六个值保存为列表的元素(可以是列表或向量):
```r
output <- vector(mode="list", length=100)
for(i in 1:100){
## functions to create intermediate objects
st1 <- cellStats(prediction1>tr1,sum)
st2 <- cellStats(prediction2>tr2,sum)
st3 <- cellStats(prediction3>tr3,sum)
st4 <- cellStats(prediction4>tr4,sum)
st5 <- cellStats(prediction5>tr5,sum)
st6 <- cellStats(prediction6>tr6,sum)
output[[i]] <- list(st1=st1, st2=st2,
st3=st3, st4=st4,
st5=st5, st6=st6)
}
或者,如果您希望output
的每个元素是一个向量而不是一个列表,您可以用以下代码替换上面的相关行:
output[[i]] <- c(st1=st1, st2=st2,
st3=st3, st4=st4,
st5=st5, st6=st6)
英文:
If I'm understanding the problem correctly, you could use a for()
loop from 1 to 100 and each time save the resulting six values as an element in a list (could either be a list or vector):
output <- vector(mode="list", length=100)
for(i in 1:100){
## functions to creat intermediate objects
st1 <- cellStats(prediction1>tr1,sum)
st2 <- cellStats(prediction2>tr2,sum)
st3 <- cellStats(prediction3>tr3,sum)
st4 <- cellStats(prediction4>tr4,sum)
st5 <- cellStats(prediction5>tr5,sum)
st6 <- cellStats(prediction6>tr6,sum)
output[[i]] <- list(st1=st1, st2=st2,
st3=st3, st4=st4,
st5=st5, st6=st6)
}
Or, if you wanted to have each element of output
to be a vector rather than a list, you could replace the relevant lines above with this:
output[[i]] <- c(st1=st1, st2=st2,
st3=st3, st4=st4,
st5=st5, st6=st6)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论