【问题标题】:Using loops to run multiple functions and save output separately使用循环运行多个函数并分别保存输出
【发布时间】:2019-10-23 20:26:06
【问题描述】:

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

我有由标记动物的一系列点组成的空间数据。我正在使用包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


    【解决方案1】:

    我会在你的情况下使用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(不可见)。这使得它易于使用 管道。

    【讨论】:

      【解决方案2】:

      Slavas 方法也是我的解决方案。但是,由于 OP 要求使用 for 循环,这应该以 1:1 反映您的代码(尽管性能不是最好的):

      for(i in c(100, 90, 50)){
        assign(paste0("mcp_est", i),
               value = mcp(df[, 2], percent = i))
      
        writeOGR(obj=get(paste0("mcp_est", i)),
                 dsn=site,
                 layer=paste(id, '_', date, '_', i, sep=''), 
                 driver='ESRI Shapefile', overwrite_layer=TRUE)
      }
      

      【讨论】:

      • 也可以完美运行,但我将 Slavas 的回答标记为优雅的解决方案。
      猜你喜欢
      • 2022-01-16
      • 2022-12-19
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 2020-09-03
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      相关资源
      最近更新 更多