如何在R中循环整个脚本

huangapple go评论95阅读模式
英文:

How to loop an entire script in R

问题

  1. 我有一个很长的脚本其中包含许多数据操作完整地分享可能会太长但我将分享一些部分以阐明我的目的
  2. 脚本中有一个函数会生成随机点所以我创建的最终对象总是不同的我想要做的是将整个脚本循环运行100并将许多生成的对象存储在一个列表中
  3. 以下是脚本的一部分
  4. ```R
  5. area <- read_sf("area_erase.shp")
  6. #栅格列表
  7. agrilist <- sprintf('p%s_agriprop.tif', 1:6)
  8. results_agri <- lapply(agrilist, raster)
  9. results_agri <- setNames(results_agri, agrilist)
  10. #第二个栅格列表
  11. poplist <- sprintf('p%s_pop.tif', 1:6)
  12. results_pop <- lapply(poplist, raster)
  13. results_pop <- setNames(results_pop, poplist)
  14. #对其中一个栅格进行重采样
  15. results_agri[[6]] <- resample(results_agri[[6]],results_agri[[5]],method="bilinear")
  16. #堆叠它们
  17. allrasters <- mapply(raster::stack,results_agri,results_pop)
  18. #加载现有点
  19. pointslist <- sprintf('p%s_utm_n.csv', 1:6)
  20. results_points <- lapply(pointslist, read.csv)
  21. results_points <- setNames(results_points, pointslist)
  22. #为提取准备(仅经度和纬度列)
  23. extr <- function(xts.obj){xts.obj[,c(2:3)]}
  24. points_xy <- lapply(results_points, extr)

等等,等等

'随机' 部分,确保每次运行脚本时都会产生不同的结果如下:

  1. #创建随机点
  2. pas[[1]] <- randomPoints(results_agri[[1]],n=1082,p=points_xy[[1]],ext=area)
  3. pas[[2]] <- randomPoints(results_agri[[1]],n=2506,p=points_xy[[2]],ext=area)
  4. pas[[3]] <- randomPoints(results_agri[[1]],n=2326,p=points_xy[[3]],ext=area)
  5. pas[[4]] <- randomPoints(results_agri[[1]],n=3168,p=points_xy[[4]],ext=area)
  6. pas[[5]] <- randomPoints(results_agri[[1]],n=3216,p=points_xy[[5]],ext=area)
  7. pas[[6]] <- randomPoints(results_agri[[1]],n=3176,p=points_xy[[6]],ext=area)

然后脚本的最后一部分:

  1. #最终值
  2. st1 <- cellStats(prediction1>tr1,sum)
  3. st2 <- cellStats(prediction2>tr2,sum)
  4. st3 <- cellStats(prediction3>tr3,sum)
  5. st4 <- cellStats(prediction4>tr4,sum)
  6. st5 <- cellStats(prediction5>tr5,sum)
  7. st6 <- cellStats(prediction6>tr6,sum)

这6个对象每个都是一个单一的数值,每次脚本迭代时会有所不同,所以我想每次迭代结束时运行这些代码100次,并将输出存储在一个列表中。

我该如何做?我考虑过使用 'repeat' 循环,但不确定如何将最终的对象存储在一个列表中,并在完成100次迭代后退出循环。

  1. <details>
  2. <summary>英文:</summary>
  3. 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.
  4. 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.
  5. 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)

  1. etc, etc
  2. The &#39;random&#39; 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)

  1. 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)

  1. These 6 objects are a single numeric value each, and will differ every iteration the script, so I&#39;d like to run these 100 times too, one time at the end of each iteration, and then store the output in a list
  2. How would I go about this? I was thinking about a &#39;repeat&#39; loop, but am unsure how to store the final objects in a list and break the loop once there&#39;s 100 iterations done.
  3. </details>
  4. # 答案1
  5. **得分**: 1
  6. 如果我正确理解问题,您可以使用一个`for()`循环从1100,每次将结果的六个值保存为列表的元素(可以是列表或向量):
  7. ```r
  8. output <- vector(mode="list", length=100)
  9. for(i in 1:100){
  10. ## functions to create intermediate objects
  11. st1 <- cellStats(prediction1>tr1,sum)
  12. st2 <- cellStats(prediction2>tr2,sum)
  13. st3 <- cellStats(prediction3>tr3,sum)
  14. st4 <- cellStats(prediction4>tr4,sum)
  15. st5 <- cellStats(prediction5>tr5,sum)
  16. st6 <- cellStats(prediction6>tr6,sum)
  17. output[[i]] <- list(st1=st1, st2=st2,
  18. st3=st3, st4=st4,
  19. st5=st5, st6=st6)
  20. }

或者,如果您希望output的每个元素是一个向量而不是一个列表,您可以用以下代码替换上面的相关行:

  1. output[[i]] <- c(st1=st1, st2=st2,
  2. st3=st3, st4=st4,
  3. 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):

  1. output &lt;- vector(mode=&quot;list&quot;, length=100)
  2. for(i in 1:100){
  3. ## functions to creat intermediate objects
  4. st1 &lt;- cellStats(prediction1&gt;tr1,sum)
  5. st2 &lt;- cellStats(prediction2&gt;tr2,sum)
  6. st3 &lt;- cellStats(prediction3&gt;tr3,sum)
  7. st4 &lt;- cellStats(prediction4&gt;tr4,sum)
  8. st5 &lt;- cellStats(prediction5&gt;tr5,sum)
  9. st6 &lt;- cellStats(prediction6&gt;tr6,sum)
  10. output[[i]] &lt;- list(st1=st1, st2=st2,
  11. st3=st3, st4=st4,
  12. st5=st5, st6=st6)
  13. }

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:

  1. output[[i]] &lt;- c(st1=st1, st2=st2,
  2. st3=st3, st4=st4,
  3. st5=st5, st6=st6)

huangapple
  • 本文由 发表于 2023年6月1日 04:18:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76376983.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定