diff --git a/.Rbuildignore b/.Rbuildignore index a7db44d..89469e1 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -4,3 +4,10 @@ ^\.github$ ^codecov\.yml$ ^LICENSE\.md$ + +^_targets$ +^_targets_r$ +^_targets\.R$ +^_targets_packages\.R$ +^_targets\.Rmd$ +^_targets\.yaml$ diff --git a/.gitignore b/.gitignore index 7c794aa..4ade709 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,11 @@ .httr-oauth .DS_Store .quarto +.Rprofile + +_targets_packages.R +_targets +_targets.R +_targets.Rmd +_targets_r +_targets.yaml diff --git a/DESCRIPTION b/DESCRIPTION index 1eb5ef7..ab2f53d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -14,6 +14,12 @@ Authors@R: c( family = "Scott", role = c("aut"), comment = c(ORCID = "0000-0002-7430-7879") + ), + person( + given = "Andrew", + family = "Brown", + role = c("aut"), + comment = c(ORCID = "0000-0002-4565-533X") ) ) Description: Provides extensions for various geospatial file formats, @@ -30,6 +36,8 @@ Imports: terra Suggests: testthat (>= 3.0.0) +Depends: + R (>= 4.1.0) Config/testthat/edition: 3 URL: https://github.com/njtierney/geotargets BugReports: https://github.com/njtierney/geotargets/issues diff --git a/NAMESPACE b/NAMESPACE index 17876de..822d790 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,3 +1,5 @@ # Generated by roxygen2: do not edit by hand +export(tar_terra_rast) +export(tar_terra_vect) importFrom(utils,globalVariables) diff --git a/R/tar-geotiff.R b/R/tar-geotiff.R deleted file mode 100644 index 3afdb7a..0000000 --- a/R/tar-geotiff.R +++ /dev/null @@ -1,65 +0,0 @@ -tar_geotiff <- function(name, - command, - pattern = NULL, - tidy_eval = targets::tar_option_get("tidy_eval"), - library = targets::tar_option_get("library"), - repository = targets::tar_option_get("repository"), - iteration = targets::tar_option_get("iteration"), - error = targets::tar_option_get("error"), - memory = targets::tar_option_get("memory"), - garbage_collection = targets::tar_option_get("garbage_collection"), - deployment = targets::tar_option_get("deployment"), - priority = targets::tar_option_get("priority"), - resources = targets::tar_option_get("resources"), - storage = targets::tar_option_get("storage"), - retrieval = targets::tar_option_get("retrieval"), - cue = targets::tar_option_get("cue")) { - name <- targets::tar_deparse_language(substitute(name)) - - envir <- targets::tar_option_get("envir") - - command <- targets::tar_tidy_eval( - expr = as.expression(substitute(command)), - envir = envir, - tidy_eval = tidy_eval - ) - pattern <- targets::tar_tidy_eval( - expr = as.expression(substitute(pattern)), - envir = envir, - tidy_eval = tidy_eval - ) - - format_geotiff <- targets::tar_format( - read = function(path) terra::rast(path), - write = function(object, path) { - terra::writeRaster( - x = object, - filename = path, - filetype = "GTiff", - overwrite = TRUE - ) - }, - marshal = function(object) terra::wrap(object), - unmarshal = function(object) terra::unwrap(object) - ) - - targets::tar_target_raw( - name = name, - command = command, - pattern = pattern, - packages = packages, - library = library, - format = format_geotiff, - repository = repository, - iteration = iteration, - error = error, - memory = memory, - garbage_collection = garbage_collection, - deployment = deployment, - priority = priority, - resources = resources, - storage = storage, - retrieval = retrieval, - cue = cue - ) -} diff --git a/R/tar-shapefile.R b/R/tar-shapefile.R deleted file mode 100644 index fdb8bba..0000000 --- a/R/tar-shapefile.R +++ /dev/null @@ -1,86 +0,0 @@ -format_shapefile <- targets::tar_format( - read = function(path) { - terra::vect( - paste0( - "/vsizip/", - file.path( - path, - replace_dot_zip_with_shp(path) - ) - ) - ) - }, - write = function(object, path) { - terra::writeVector( - x = object, - filename = replace_dot_zip_with_shp(path), - filetype = "ESRI Shapefile", - overwrite = TRUE - ) - zf <- list.files( - pattern = replace_dot_zip( - x = path, - replacement = "" - ) - ) - utils::zip( - zipfile = path, - files = zf - ) - unlink(zf) - }, - marshal = function(object) terra::wrap(object), - unmarshal = function(object) terra::unwrap(object) -) - -tar_shapefile <- function(name, - command, - pattern = NULL, - tidy_eval = targets::tar_option_get("tidy_eval"), - library = targets::tar_option_get("library"), - repository = targets::tar_option_get("repository"), - iteration = targets::tar_option_get("iteration"), - error = targets::tar_option_get("error"), - memory = targets::tar_option_get("memory"), - garbage_collection = targets::tar_option_get("garbage_collection"), - deployment = targets::tar_option_get("deployment"), - priority = targets::tar_option_get("priority"), - resources = targets::tar_option_get("resources"), - storage = targets::tar_option_get("storage"), - retrieval = targets::tar_option_get("retrieval"), - cue = targets::tar_option_get("cue")) { - name <- targets::tar_deparse_language(substitute(name)) - - envir <- targets::tar_option_get("envir") - - command <- targets::tar_tidy_eval( - expr = as.expression(substitute(command)), - envir = envir, - tidy_eval = tidy_eval - ) - pattern <- targets::tar_tidy_eval( - expr = as.expression(substitute(pattern)), - envir = envir, - tidy_eval = tidy_eval - ) - - targets::tar_target_raw( - name = name, - command = command, - pattern = pattern, - packages = packages, - library = library, - format = format_shapefile, - repository = repository, - iteration = iteration, - error = error, - memory = memory, - garbage_collection = garbage_collection, - deployment = deployment, - priority = priority, - resources = resources, - storage = storage, - retrieval = retrieval, - cue = cue - ) -} diff --git a/R/tar-terra-rast.R b/R/tar-terra-rast.R new file mode 100644 index 0000000..c42704a --- /dev/null +++ b/R/tar-terra-rast.R @@ -0,0 +1,135 @@ +#' Create a terra _SpatRaster_ Target +#' +#' Creates a target for a terra _SpatRaster_ object. +#' +#' @param filetype character. File format expressed as GDAL driver names passed to `terra::writeRaster()` +#' @param gdal character. GDAL driver specific datasource creation options passed to `terra::writeRaster()` +#' @param ... Additional arguments not yet used +#' +#' @inheritParams targets::tar_target +#' +#' @seealso [targets::tar_target_raw()] +#' @export +#' @examples +#' if (Sys.getenv("TAR_LONG_EXAMPLES") == "true") { +#' targets::tar_dir({ # tar_dir() runs code from a temporary directory. +#' library(geotargets) +#' targets::tar_script({ +#' list( +#' geotargets::tar_terra_rast( +#' terra_rast_example, +#' system.file("ex/elev.tif", package = "terra") |> terra::rast() +#' ) +#' ) +#' }) +#' targets::tar_make() +#' x <- targets::tar_read(terra_rast_example) +#' }) +#'} +tar_terra_rast <- function(name, + command, + pattern = NULL, + filetype = NULL, + gdal = NULL, + ..., + tidy_eval = targets::tar_option_get("tidy_eval"), + packages = targets::tar_option_get("packages"), + library = targets::tar_option_get("library"), + repository = targets::tar_option_get("repository"), + iteration = targets::tar_option_get("iteration"), + error = targets::tar_option_get("error"), + memory = targets::tar_option_get("memory"), + garbage_collection = targets::tar_option_get("garbage_collection"), + deployment = targets::tar_option_get("deployment"), + priority = targets::tar_option_get("priority"), + resources = targets::tar_option_get("resources"), + storage = targets::tar_option_get("storage"), + retrieval = targets::tar_option_get("retrieval"), + cue = targets::tar_option_get("cue")) { + + name <- targets::tar_deparse_language(substitute(name)) + + envir <- targets::tar_option_get("envir") + + command <- targets::tar_tidy_eval( + expr = as.expression(substitute(command)), + envir = envir, + tidy_eval = tidy_eval + ) + + pattern <- targets::tar_tidy_eval( + expr = as.expression(substitute(pattern)), + envir = envir, + tidy_eval = tidy_eval + ) + + # could pull defaults from geotargets package options + if (is.null(filetype)) { + filetype <- "GTiff" + } + + if (is.null(gdal)) { + gdal <- "ENCODING=UTF-8" + } + + targets::tar_target_raw( + name = name, + command = command, + pattern = pattern, + packages = packages, + library = library, + format = create_format_terra_raster(filetype = filetype, gdal = gdal, ...), + repository = repository, + iteration = iteration, + error = error, + memory = memory, + garbage_collection = garbage_collection, + deployment = deployment, + priority = priority, + resources = resources, + storage = storage, + retrieval = retrieval, + cue = cue + ) +} + +#' @param filetype File format expressed as GDAL driver names passed to `terra::writeRaster()` +#' @param gdal GDAL driver specific datasource creation options passed to `terra::writeRaster()` +#' @param ... Additional arguments not yet used +#' @noRd +create_format_terra_raster <- function(filetype, gdal, ...) { + + if (!requireNamespace("terra")) { + stop("package 'terra' is required", call. = FALSE) + } + + # get list of drivers available for writing depending on what the user's GDAL supports + drv <- terra::gdal(drivers = TRUE) + drv <- drv[drv$type == "raster" & grepl("write", drv$can), ] + + if (is.null(filetype)) { + filetype <- "GTiff" + } + + filetype <- match.arg(filetype, drv$name) + + .write_terra_raster <- function(object, path) { + terra::writeRaster( + object, + path, + filetype = NULL, + overwrite = TRUE, + gdal = NULL + ) + } + body(.write_terra_raster)[[2]][["filetype"]] <- filetype + body(.write_terra_raster)[[2]][["gdal"]] <- gdal + + targets::tar_format( + read = function(path) terra::rast(path), + write = .write_terra_raster, + marshal = function(object) terra::wrap(object), + unmarshal = function(object) terra::unwrap(object) + ) +} + diff --git a/R/tar-terra-vect.R b/R/tar-terra-vect.R new file mode 100644 index 0000000..eadc681 --- /dev/null +++ b/R/tar-terra-vect.R @@ -0,0 +1,131 @@ +# format_terra_vect_shapefile <- targets::tar_format( +# read = function(path) { +# terra::vect( +# paste0( +# "/vsizip/", +# file.path( +# path, +# replace_dot_zip_with_shp(path) +# ) +# ) +# ) +# }, +# write = function(object, path) { +# terra::writeVector( +# x = object, +# filename = replace_dot_zip_with_shp(path), +# filetype = "ESRI Shapefile", +# overwrite = TRUE +# ) +# zf <- list.files( +# pattern = replace_dot_zip( +# x = path, +# replacement = "" +# ) +# ) +# utils::zip( +# zipfile = path, +# files = zf +# ) +# unlink(zf) +# }, +# marshal = function(object) terra::wrap(object), +# unmarshal = function(object) terra::unwrap(object) +# ) + +#' Targets format for terra vectors +#' +#' Provides targets format for `terra::vect` objects +#' +#' @inheritParams targets::tar_target +#' +#' @export +#' @examples +#' if (Sys.getenv("TAR_LONG_EXAMPLES") == "true") { +#' targets::tar_dir({ # tar_dir() runs code from a temporary directory. +#' targets::tar_script({ +#' lux_area <- function(projection = "EPSG:4326") { +#' terra::project( +#' terra::vect(system.file("ex", "lux.shp", +#' package = "terra" +#' )), +#' projection +#' ) +#' } +#' list( +#' geotargets::tar_terra_vect( +#' terra_vect_example, +#' lux_area() +#' ) +#' ) +#' }) +#' targets::tar_make() +#' x <- targets::tar_read(terra_vect_example) +#' }) +#' } +tar_terra_vect <- function(name, + command, + pattern = NULL, + packages = targets::tar_option_get("packages"), + tidy_eval = targets::tar_option_get("tidy_eval"), + library = targets::tar_option_get("library"), + repository = targets::tar_option_get("repository"), + iteration = targets::tar_option_get("iteration"), + error = targets::tar_option_get("error"), + memory = targets::tar_option_get("memory"), + garbage_collection = targets::tar_option_get("garbage_collection"), + deployment = targets::tar_option_get("deployment"), + priority = targets::tar_option_get("priority"), + resources = targets::tar_option_get("resources"), + storage = targets::tar_option_get("storage"), + retrieval = targets::tar_option_get("retrieval"), + cue = targets::tar_option_get("cue")) { + name <- targets::tar_deparse_language(substitute(name)) + + envir <- targets::tar_option_get("envir") + + command <- targets::tar_tidy_eval( + expr = as.expression(substitute(command)), + envir = envir, + tidy_eval = tidy_eval + ) + pattern <- targets::tar_tidy_eval( + expr = as.expression(substitute(pattern)), + envir = envir, + tidy_eval = tidy_eval + ) + + format_terra_shapefile_zip <- targets::tar_format( + read = function(path) terra::vect(paste0("/vsizip/{", path, "}")), + write = function(object, path) { + terra::writeVector( + x = object, + filename = paste0(path, ".shz"), + filetype = "ESRI Shapefile" + ) + file.rename(paste0(path, ".shz"), path) + }, + marshal = function(object) terra::wrap(object), + unmarshal = function(object) terra::unwrap(object) + ) + + targets::tar_target_raw( + name = name, + command = command, + pattern = pattern, + packages = packages, + library = library, + format = format_terra_shapefile_zip, + repository = repository, + iteration = iteration, + error = error, + memory = memory, + garbage_collection = garbage_collection, + deployment = deployment, + priority = priority, + resources = resources, + storage = storage, + retrieval = retrieval, + cue = cue + ) +} diff --git a/README.Rmd b/README.Rmd index 63fcfb4..40d895c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -36,7 +36,7 @@ remotes::install_github("njtierney/geotargets") Currently geotargets provides: -- `tar_geotiff` -- `tar_shapefile` +- `tar_terra_rast` +- `tar_terra_vect` -But these are under development. +These are under active development. diff --git a/README.md b/README.md index 0946805..7cb1300 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ remotes::install_github("njtierney/geotargets") Currently geotargets provides: -- `tar_geotiff` -- `tar_shapefile` +- `tar_terra_rast` +- `tar_terra_vect` -But these are under development. +These are under active development. diff --git a/man/geotargets-package.Rd b/man/geotargets-package.Rd index 8838438..ff8d4db 100644 --- a/man/geotargets-package.Rd +++ b/man/geotargets-package.Rd @@ -22,6 +22,7 @@ Useful links: Authors: \itemize{ \item Eric Scott (\href{https://orcid.org/0000-0002-7430-7879}{ORCID}) + \item Andrew Brown (\href{https://orcid.org/0000-0002-4565-533X}{ORCID}) } } diff --git a/man/tar_terra_rast.Rd b/man/tar_terra_rast.Rd new file mode 100644 index 0000000..5b2d452 --- /dev/null +++ b/man/tar_terra_rast.Rd @@ -0,0 +1,234 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tar-terra-rast.R +\name{tar_terra_rast} +\alias{tar_terra_rast} +\title{Create a terra \emph{SpatRaster} Target} +\usage{ +tar_terra_rast( + name, + command, + pattern = NULL, + filetype = NULL, + gdal = NULL, + ..., + tidy_eval = targets::tar_option_get("tidy_eval"), + packages = targets::tar_option_get("packages"), + library = targets::tar_option_get("library"), + repository = targets::tar_option_get("repository"), + iteration = targets::tar_option_get("iteration"), + error = targets::tar_option_get("error"), + memory = targets::tar_option_get("memory"), + garbage_collection = targets::tar_option_get("garbage_collection"), + deployment = targets::tar_option_get("deployment"), + priority = targets::tar_option_get("priority"), + resources = targets::tar_option_get("resources"), + storage = targets::tar_option_get("storage"), + retrieval = targets::tar_option_get("retrieval"), + cue = targets::tar_option_get("cue") +) +} +\arguments{ +\item{name}{Symbol, name of the target. A target +name must be a valid name for a symbol in R, and it +must not start with a dot. Subsequent targets +can refer to this name symbolically to induce a dependency relationship: +e.g. \code{tar_target(downstream_target, f(upstream_target))} is a +target named \code{downstream_target} which depends on a target +\code{upstream_target} and a function \code{f()}. In addition, a target's +name determines its random number generator seed. In this way, +each target runs with a reproducible seed so someone else +running the same pipeline should get the same results, +and no two targets in the same pipeline share the same seed. +(Even dynamic branches have different names and thus different seeds.) +You can recover the seed of a completed target +with \code{tar_meta(your_target, seed)} and run \code{\link[targets:tar_seed_set]{tar_seed_set()}} +on the result to locally recreate the target's initial RNG state.} + +\item{command}{R code to run the target.} + +\item{pattern}{Language to define branching for a target. +For example, in a pipeline with numeric vector targets \code{x} and \code{y}, +\code{tar_target(z, x + y, pattern = map(x, y))} implicitly defines +branches of \code{z} that each compute \code{x[1] + y[1]}, \code{x[2] + y[2]}, +and so on. See the user manual for details.} + +\item{filetype}{character. File format expressed as GDAL driver names passed to \code{terra::writeRaster()}} + +\item{gdal}{character. GDAL driver specific datasource creation options passed to \code{terra::writeRaster()}} + +\item{...}{Additional arguments not yet used} + +\item{tidy_eval}{Logical, whether to enable tidy evaluation +when interpreting \code{command} and \code{pattern}. If \code{TRUE}, you can use the +"bang-bang" operator \verb{!!} to programmatically insert +the values of global objects.} + +\item{packages}{Character vector of packages to load right before +the target runs or the output data is reloaded for +downstream targets. Use \code{tar_option_set()} to set packages +globally for all subsequent targets you define.} + +\item{library}{Character vector of library paths to try +when loading \code{packages}.} + +\item{repository}{Character of length 1, remote repository for target +storage. Choices: +\itemize{ +\item \code{"local"}: file system of the local machine. +\item \code{"aws"}: Amazon Web Services (AWS) S3 bucket. Can be configured +with a non-AWS S3 bucket using the \code{endpoint} argument of +\code{\link[targets:tar_resources_aws]{tar_resources_aws()}}, but versioning capabilities may be lost +in doing so. +See the cloud storage section of +\url{https://books.ropensci.org/targets/data.html} +for details for instructions. +\item \code{"gcp"}: Google Cloud Platform storage bucket. +See the cloud storage section of +\url{https://books.ropensci.org/targets/data.html} +for details for instructions. +} + +Note: if \code{repository} is not \code{"local"} and \code{format} is \code{"file"} +then the target should create a single output file. +That output file is uploaded to the cloud and tracked for changes +where it exists in the cloud. The local file is deleted after +the target runs.} + +\item{iteration}{Character of length 1, name of the iteration mode +of the target. Choices: +\itemize{ +\item \code{"vector"}: branching happens with \code{vctrs::vec_slice()} and +aggregation happens with \code{vctrs::vec_c()}. +\item \code{"list"}, branching happens with \verb{[[]]} and aggregation happens with +\code{list()}. +\item \code{"group"}: \code{dplyr::group_by()}-like functionality to branch over +subsets of a data frame. The target's return value must be a data +frame with a special \code{tar_group} column of consecutive integers +from 1 through the number of groups. Each integer designates a group, +and a branch is created for each collection of rows in a group. +See the \code{\link[targets:tar_group]{tar_group()}} function to see how you can +create the special \code{tar_group} column with \code{dplyr::group_by()}. +}} + +\item{error}{Character of length 1, what to do if the target +stops and throws an error. Options: +\itemize{ +\item \code{"stop"}: the whole pipeline stops and throws an error. +\item \code{"continue"}: the whole pipeline keeps going. +\item \code{"abridge"}: any currently running targets keep running, +but no new targets launch after that. +(Visit \url{https://books.ropensci.org/targets/debugging.html} +to learn how to debug targets using saved workspaces.) +\item \code{"null"}: The errored target continues and returns \code{NULL}. +The data hash is deliberately wrong so the target is not +up to date for the next run of the pipeline. +}} + +\item{memory}{Character of length 1, memory strategy. +If \code{"persistent"}, the target stays in memory +until the end of the pipeline (unless \code{storage} is \code{"worker"}, +in which case \code{targets} unloads the value from memory +right after storing it in order to avoid sending +copious data over a network). +If \code{"transient"}, the target gets unloaded +after every new target completes. +Either way, the target gets automatically loaded into memory +whenever another target needs the value. +For cloud-based dynamic files +(e.g. \code{format = "file"} with \code{repository = "aws"}), +this memory strategy applies to the +temporary local copy of the file: +\code{"persistent"} means it remains until the end of the pipeline +and is then deleted, +and \code{"transient"} means it gets deleted as soon as possible. +The former conserves bandwidth, +and the latter conserves local storage.} + +\item{garbage_collection}{Logical, whether to run \code{base::gc()} +just before the target runs.} + +\item{deployment}{Character of length 1, only relevant to +\code{\link[targets:tar_make_clustermq]{tar_make_clustermq()}} and \code{\link[targets:tar_make_future]{tar_make_future()}}. If \code{"worker"}, +the target runs on a parallel worker. If \code{"main"}, +the target runs on the host machine / process managing the pipeline.} + +\item{priority}{Numeric of length 1 between 0 and 1. Controls which +targets get deployed first when multiple competing targets are ready +simultaneously. Targets with priorities closer to 1 get dispatched earlier +(and polled earlier in \code{\link[targets:tar_make_future]{tar_make_future()}}).} + +\item{resources}{Object returned by \code{tar_resources()} +with optional settings for high-performance computing +functionality, alternative data storage formats, +and other optional capabilities of \code{targets}. +See \code{tar_resources()} for details.} + +\item{storage}{Character of length 1, only relevant to +\code{\link[targets:tar_make_clustermq]{tar_make_clustermq()}} and \code{\link[targets:tar_make_future]{tar_make_future()}}. +Must be one of the following values: +\itemize{ +\item \code{"main"}: the target's return value is sent back to the +host machine and saved/uploaded locally. +\item \code{"worker"}: the worker saves/uploads the value. +\item \code{"none"}: almost never recommended. It is only for +niche situations, e.g. the data needs to be loaded +explicitly from another language. If you do use it, +then the return value of the target is totally ignored +when the target ends, but +each downstream target still attempts to load the data file +(except when \code{retrieval = "none"}). + +If you select \code{storage = "none"}, then +the return value of the target's command is ignored, +and the data is not saved automatically. +As with dynamic files (\code{format = "file"}) it is the +responsibility of the user to write to +the data store from inside the target. + +The distinguishing feature of \code{storage = "none"} +(as opposed to \code{format = "file"}) +is that in the general case, +downstream targets will automatically try to load the data +from the data store as a dependency. As a corollary, \code{storage = "none"} +is completely unnecessary if \code{format} is \code{"file"}. +}} + +\item{retrieval}{Character of length 1, only relevant to +\code{\link[targets:tar_make_clustermq]{tar_make_clustermq()}} and \code{\link[targets:tar_make_future]{tar_make_future()}}. +Must be one of the following values: +\itemize{ +\item \code{"main"}: the target's dependencies are loaded on the host machine +and sent to the worker before the target runs. +\item \code{"worker"}: the worker loads the targets dependencies. +\item \code{"none"}: the dependencies are not loaded at all. +This choice is almost never recommended. It is only for +niche situations, e.g. the data needs to be loaded +explicitly from another language. +}} + +\item{cue}{An optional object from \code{tar_cue()} to customize the +rules that decide whether the target is up to date.} +} +\description{ +Creates a target for a terra \emph{SpatRaster} object. +} +\examples{ +if (Sys.getenv("TAR_LONG_EXAMPLES") == "true") { + targets::tar_dir({ # tar_dir() runs code from a temporary directory. + library(geotargets) + targets::tar_script({ + list( + geotargets::tar_terra_rast( + terra_rast_example, + system.file("ex/elev.tif", package = "terra") |> terra::rast() + ) + ) + }) + targets::tar_make() + x <- targets::tar_read(terra_rast_example) + }) +} +} +\seealso{ +\code{\link[targets:tar_target_raw]{targets::tar_target_raw()}} +} diff --git a/man/tar_terra_vect.Rd b/man/tar_terra_vect.Rd new file mode 100644 index 0000000..3db638f --- /dev/null +++ b/man/tar_terra_vect.Rd @@ -0,0 +1,235 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tar-terra-vect.R +\name{tar_terra_vect} +\alias{tar_terra_vect} +\title{Targets format for terra vectors} +\usage{ +tar_terra_vect( + name, + command, + pattern = NULL, + packages = targets::tar_option_get("packages"), + tidy_eval = targets::tar_option_get("tidy_eval"), + library = targets::tar_option_get("library"), + repository = targets::tar_option_get("repository"), + iteration = targets::tar_option_get("iteration"), + error = targets::tar_option_get("error"), + memory = targets::tar_option_get("memory"), + garbage_collection = targets::tar_option_get("garbage_collection"), + deployment = targets::tar_option_get("deployment"), + priority = targets::tar_option_get("priority"), + resources = targets::tar_option_get("resources"), + storage = targets::tar_option_get("storage"), + retrieval = targets::tar_option_get("retrieval"), + cue = targets::tar_option_get("cue") +) +} +\arguments{ +\item{name}{Symbol, name of the target. A target +name must be a valid name for a symbol in R, and it +must not start with a dot. Subsequent targets +can refer to this name symbolically to induce a dependency relationship: +e.g. \code{tar_target(downstream_target, f(upstream_target))} is a +target named \code{downstream_target} which depends on a target +\code{upstream_target} and a function \code{f()}. In addition, a target's +name determines its random number generator seed. In this way, +each target runs with a reproducible seed so someone else +running the same pipeline should get the same results, +and no two targets in the same pipeline share the same seed. +(Even dynamic branches have different names and thus different seeds.) +You can recover the seed of a completed target +with \code{tar_meta(your_target, seed)} and run \code{\link[targets:tar_seed_set]{tar_seed_set()}} +on the result to locally recreate the target's initial RNG state.} + +\item{command}{R code to run the target.} + +\item{pattern}{Language to define branching for a target. +For example, in a pipeline with numeric vector targets \code{x} and \code{y}, +\code{tar_target(z, x + y, pattern = map(x, y))} implicitly defines +branches of \code{z} that each compute \code{x[1] + y[1]}, \code{x[2] + y[2]}, +and so on. See the user manual for details.} + +\item{packages}{Character vector of packages to load right before +the target runs or the output data is reloaded for +downstream targets. Use \code{tar_option_set()} to set packages +globally for all subsequent targets you define.} + +\item{tidy_eval}{Logical, whether to enable tidy evaluation +when interpreting \code{command} and \code{pattern}. If \code{TRUE}, you can use the +"bang-bang" operator \verb{!!} to programmatically insert +the values of global objects.} + +\item{library}{Character vector of library paths to try +when loading \code{packages}.} + +\item{repository}{Character of length 1, remote repository for target +storage. Choices: +\itemize{ +\item \code{"local"}: file system of the local machine. +\item \code{"aws"}: Amazon Web Services (AWS) S3 bucket. Can be configured +with a non-AWS S3 bucket using the \code{endpoint} argument of +\code{\link[targets:tar_resources_aws]{tar_resources_aws()}}, but versioning capabilities may be lost +in doing so. +See the cloud storage section of +\url{https://books.ropensci.org/targets/data.html} +for details for instructions. +\item \code{"gcp"}: Google Cloud Platform storage bucket. +See the cloud storage section of +\url{https://books.ropensci.org/targets/data.html} +for details for instructions. +} + +Note: if \code{repository} is not \code{"local"} and \code{format} is \code{"file"} +then the target should create a single output file. +That output file is uploaded to the cloud and tracked for changes +where it exists in the cloud. The local file is deleted after +the target runs.} + +\item{iteration}{Character of length 1, name of the iteration mode +of the target. Choices: +\itemize{ +\item \code{"vector"}: branching happens with \code{vctrs::vec_slice()} and +aggregation happens with \code{vctrs::vec_c()}. +\item \code{"list"}, branching happens with \verb{[[]]} and aggregation happens with +\code{list()}. +\item \code{"group"}: \code{dplyr::group_by()}-like functionality to branch over +subsets of a non-dynamic data frame. +For \code{iteration = "group"}, the target must not by dynamic +(the \code{pattern} argument of \code{\link[targets:tar_target]{tar_target()}} must be left \code{NULL}). +The target's return value must be a data +frame with a special \code{tar_group} column of consecutive integers +from 1 through the number of groups. Each integer designates a group, +and a branch is created for each collection of rows in a group. +See the \code{\link[targets:tar_group]{tar_group()}} function to see how you can +create the special \code{tar_group} column with \code{dplyr::group_by()}. +}} + +\item{error}{Character of length 1, what to do if the target +stops and throws an error. Options: +\itemize{ +\item \code{"stop"}: the whole pipeline stops and throws an error. +\item \code{"continue"}: the whole pipeline keeps going. +\item \code{"abridge"}: any currently running targets keep running, +but no new targets launch after that. +(Visit \url{https://books.ropensci.org/targets/debugging.html} +to learn how to debug targets using saved workspaces.) +\item \code{"null"}: The errored target continues and returns \code{NULL}. +The data hash is deliberately wrong so the target is not +up to date for the next run of the pipeline. +}} + +\item{memory}{Character of length 1, memory strategy. +If \code{"persistent"}, the target stays in memory +until the end of the pipeline (unless \code{storage} is \code{"worker"}, +in which case \code{targets} unloads the value from memory +right after storing it in order to avoid sending +copious data over a network). +If \code{"transient"}, the target gets unloaded +after every new target completes. +Either way, the target gets automatically loaded into memory +whenever another target needs the value. +For cloud-based dynamic files +(e.g. \code{format = "file"} with \code{repository = "aws"}), +this memory strategy applies to the +temporary local copy of the file: +\code{"persistent"} means it remains until the end of the pipeline +and is then deleted, +and \code{"transient"} means it gets deleted as soon as possible. +The former conserves bandwidth, +and the latter conserves local storage.} + +\item{garbage_collection}{Logical, whether to run \code{base::gc()} +just before the target runs.} + +\item{deployment}{Character of length 1. If \code{deployment} is +\code{"main"}, then the target will run on the central controlling R process. +Otherwise, if \code{deployment} is \code{"worker"} and you set up the pipeline +with distributed/parallel computing, then +the target runs on a parallel worker. For more on distributed/parallel +computing in \code{targets}, please visit +\url{https://books.ropensci.org/targets/crew.html}.} + +\item{priority}{Numeric of length 1 between 0 and 1. Controls which +targets get deployed first when multiple competing targets are ready +simultaneously. Targets with priorities closer to 1 get dispatched earlier +(and polled earlier in \code{\link[targets:tar_make_future]{tar_make_future()}}).} + +\item{resources}{Object returned by \code{tar_resources()} +with optional settings for high-performance computing +functionality, alternative data storage formats, +and other optional capabilities of \code{targets}. +See \code{tar_resources()} for details.} + +\item{storage}{Character of length 1, only relevant to +\code{\link[targets:tar_make_clustermq]{tar_make_clustermq()}} and \code{\link[targets:tar_make_future]{tar_make_future()}}. +Must be one of the following values: +\itemize{ +\item \code{"main"}: the target's return value is sent back to the +host machine and saved/uploaded locally. +\item \code{"worker"}: the worker saves/uploads the value. +\item \code{"none"}: almost never recommended. It is only for +niche situations, e.g. the data needs to be loaded +explicitly from another language. If you do use it, +then the return value of the target is totally ignored +when the target ends, but +each downstream target still attempts to load the data file +(except when \code{retrieval = "none"}). + +If you select \code{storage = "none"}, then +the return value of the target's command is ignored, +and the data is not saved automatically. +As with dynamic files (\code{format = "file"}) it is the +responsibility of the user to write to +the data store from inside the target. + +The distinguishing feature of \code{storage = "none"} +(as opposed to \code{format = "file"}) +is that in the general case, +downstream targets will automatically try to load the data +from the data store as a dependency. As a corollary, \code{storage = "none"} +is completely unnecessary if \code{format} is \code{"file"}. +}} + +\item{retrieval}{Character of length 1, only relevant to +\code{\link[targets:tar_make_clustermq]{tar_make_clustermq()}} and \code{\link[targets:tar_make_future]{tar_make_future()}}. +Must be one of the following values: +\itemize{ +\item \code{"main"}: the target's dependencies are loaded on the host machine +and sent to the worker before the target runs. +\item \code{"worker"}: the worker loads the targets dependencies. +\item \code{"none"}: the dependencies are not loaded at all. +This choice is almost never recommended. It is only for +niche situations, e.g. the data needs to be loaded +explicitly from another language. +}} + +\item{cue}{An optional object from \code{tar_cue()} to customize the +rules that decide whether the target is up to date.} +} +\description{ +Provides targets format for \code{terra::vect} objects +} +\examples{ +if (Sys.getenv("TAR_LONG_EXAMPLES") == "true") { + targets::tar_dir({ # tar_dir() runs code from a temporary directory. + targets::tar_script({ + lux_area <- function(projection = "EPSG:4326") { + terra::project( + terra::vect(system.file("ex", "lux.shp", + package = "terra" + )), + projection + ) + } + list( + geotargets::tar_terra_vect( + terra_vect_example, + lux_area() + ) + ) + }) + targets::tar_make() + x <- targets::tar_read(terra_vect_example) + }) +} +} diff --git a/tests/testthat/_snaps/tar-terra.md b/tests/testthat/_snaps/tar-terra.md new file mode 100644 index 0000000..02703c2 --- /dev/null +++ b/tests/testthat/_snaps/tar-terra.md @@ -0,0 +1,32 @@ +# tar_terra_rast() works + + Code + x + Output + class : SpatRaster + dimensions : 90, 95, 1 (nrow, ncol, nlyr) + resolution : 0.008333333, 0.008333333 (x, y) + extent : 5.741667, 6.533333, 49.44167, 50.19167 (xmin, xmax, ymin, ymax) + coord. ref. : lon/lat WGS 84 (EPSG:4326) + source : test_terra_rast + name : elevation + min value : 141 + max value : 547 + +# tar_terra_vect() works + + Code + x + Output + class : SpatVector + geometry : polygons + dimensions : 12, 6 (geometries, attributes) + extent : 5.74414, 6.528252, 49.44781, 50.18162 (xmin, xmax, ymin, ymax) + source : test_terra_vect} (test_terra_vect) + coord. ref. : lon/lat WGS 84 (EPSG:4326) + names : ID_1 NAME_1 ID_2 NAME_2 AREA POP + type : + values : 1 Diekirch 1 Clervaux 312 18081 + 1 Diekirch 2 Diekirch 218 32543 + 1 Diekirch 3 Redange 259 18664 + diff --git a/tests/testthat/test-tar-terra.R b/tests/testthat/test-tar-terra.R new file mode 100644 index 0000000..45898e2 --- /dev/null +++ b/tests/testthat/test-tar-terra.R @@ -0,0 +1,42 @@ +# test_that() #Included to make RStudio recognize this file as a test +targets::tar_test("tar_terra_rast() works", { + targets::tar_script({ + list( + geotargets::tar_terra_rast( + test_terra_rast, + system.file("ex/elev.tif", package = "terra") |> terra::rast() + ) + ) + }) + targets::tar_make() + x <- targets::tar_read(test_terra_rast) + expect_s4_class(x, "SpatRaster") + expect_snapshot( + x + ) +}) + +targets::tar_test("tar_terra_vect() works", { + targets::tar_script({ + lux_area <- function(projection = "EPSG:4326") { + terra::project( + terra::vect(system.file("ex", "lux.shp", + package = "terra" + )), + projection + ) + } + list( + geotargets::tar_terra_vect( + test_terra_vect, + lux_area() + ) + ) + }) + targets::tar_make() + x <- targets::tar_read(test_terra_vect) + expect_s4_class(x, "SpatVector") + expect_snapshot( + x + ) +}) diff --git a/tests/testthat/test-tar_geotiff.R b/tests/testthat/test-tar_geotiff.R deleted file mode 100644 index 4cf6dca..0000000 --- a/tests/testthat/test-tar_geotiff.R +++ /dev/null @@ -1,3 +0,0 @@ -test_that("tar_geotiff works", { - expect_equal(2 * 2, 4) -})