Использование циклов для запуска нескольких функций и сохранения результатов отдельно - PullRequest
0 голосов
/ 22 октября 2019

Извиняюсь за ужасное описание. Я уверен, что это очень простая проблема, но я очень плохо знаком с циклами и не смог разобраться. Я также не знаю, как предоставить воспроизводимые пространственные данные, так что ...

У меня есть пространственные данные, состоящие из серии точек от помеченного животного. Я использую пакет adehabitat для создания минимальных выпуклых многоугольников, содержащих переменные проценты точек. Затем я сохраняю каждый полигон в виде файла .shp с уникальным идентификатором животного, диапазоном дат и процентами и сохраняю его в другой каталог, в зависимости от того, с какого сайта он пришел. Это операция, которую я много выполняю, поэтому я хотел бы максимально автоматизировать ее.

Это то, что я сейчас использую:

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? Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 22 октября 2019

Я бы использовал 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 (незаметно)). Это облегчает использование в трубе.

1 голос
/ 22 октября 2019

Славянский подход был бы и моим решением. Однако, поскольку 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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...