首页 > 解决方案 > 使用循环运行多个函数并分别保存输出

问题描述

为可怕的描述道歉。我确信这是一个非常容易解决的问题,但我对循环很陌生,无法弄清楚。我也不知道如何提供可重现的空间数据,所以....

我有由标记动物的一系列点组成的空间数据。我正在使用该包adehabitat来创建包含可变百分比点的最小凸多边形。然后,我将每个多边形保存为一个 .shp 文件,以一个唯一的动物 ID、日期范围和百分比命名,并根据它来自哪个站点将其保存到不同的目录中。这是我经常执行的操作,所以我想尽可能地自动化它。

这就是我现在正在使用的:

library(sp)
library(adehabitatHR)
library(rgdal)

df <- read.csv('data.csv', stringsAsFactors=FALSE)

site <- 'SiteName'
date <- '2019-06-22_2019-07-20'
id <- 'HAR04'

# The adehabitat packages requires data to be in a spatial format.
coordinates(df) <- df[, c('lon', 'lat')]
proj4string(df) = CRS("+init=epsg:4326")

# Create the polygons for each percentage point.
# The column specified just refers to the id, which adehabitat requires
mcp_est100 <- mcp(df[, 2], percent = 100)
mcp_est90 <- mcp(df[, 2], percent = 90)
mcp_est50 <- mcp(df[, 2], percent = 50)

# Save the polygons as shapefiles.
writeOGR(obj=mcp_est100,
         dsn=site,
         layer=paste(id, '_', date, '_100', sep=''), 
         driver='ESRI Shapefile', overwrite_layer=TRUE)

writeOGR(obj=mcp_est90,
         dsn=site,
         layer=paste(id, '_', date, '_90', sep=''), 
         driver='ESRI Shapefile', overwrite_layer=TRUE)

writeOGR(obj=mcp_est50,
         dsn=site,
         layer=paste(id, '_', date, '_50', sep=''), 
         driver='ESRI Shapefile', overwrite_layer=TRUE)

您可以看到代码高度重复,如果有任何变化(即,如果我想要 80% 的多边形而不是 50%),我需要在多个位置进行更改。有没有办法让我使用for循环或某种apply函数来简化它?提前致谢。

标签: r

解决方案


我会purrr::walk在你的情况下使用。for这是循环的一个很好的替代品。您需要定义一个函数和一系列需要运行的值:

library(sp)
library(adehabitatHR)
library(rgdal)

df <- read.csv('data.csv', stringsAsFactors=FALSE)

site <- 'SiteName'
date <- '2019-06-22_2019-07-20'
id <- 'HAR04'

# The adehabitat packages requires data to be in a spatial format.
coordinates(df) <- df[, c('lon', 'lat')]
proj4string(df) = CRS("+init=epsg:4326")

purrr::walk(c(100, 90, 50), function(x){
  writeOGR(obj=mcp(df[, 2], percent = x),
           dsn=site,
           layer=paste(id, '_', date, '_', as.character(x), sep=''), 
           driver='ESRI Shapefile', overwrite_layer=TRUE)
})

从参考:

walk() 返回输入 .x(不可见)。这使其易于在管道中使用。


推荐阅读