diff --git a/.Rbuildignore b/.Rbuildignore index a8a3f1dd..faa1d29f 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -19,3 +19,5 @@ CODE_OF_CONDUCT.md ^\vignettes\^junk junk fasterRaster_workspace.code-workspace +^doc$ +^Meta$ diff --git a/.gitignore b/.gitignore index b285dd9a..f397d85d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ docs inst/doc junk /vignettes/junk +/doc/ +/Meta/ diff --git a/DESCRIPTION b/DESCRIPTION index a41d068e..a8dfd961 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: fasterRaster Type: Package Title: Faster Raster and Spatial Vector Processing Using 'GRASS GIS' -Version: 8.3.0.7026 -Date: 2024-09-22 +Version: 8.3.0.7027 +Date: 2024-10-15 Authors@R: c( person( @@ -41,10 +41,10 @@ Suggests: Roxygen: list(markdown = TRUE) License: GPL (>=3) + file LICENSE SystemRequirements: GRASS (>= 8) -URL: http://www.earthSkySea.org, https://adamlilith.github.io/fasterRaster/ +URL: https://github.com/adamlilith/fasterRaster, https://adamlilith.github.io/fasterRaster/ BugReports: https://github.com/adamlilith/fasterRaster/issues VignetteBuilder: knitr Encoding: UTF-8 LazyData: true LazyLoad: yes -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 diff --git a/NAMESPACE b/NAMESPACE index ca98b9d3..46e7b006 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ export(appFuns) export(fastData) export(faster) +export(grassHelp) export(grassInfo) export(grassStarted) export(is.polygons) @@ -32,6 +33,7 @@ exportMethods("addCats<-") exportMethods("addTable<-") exportMethods("levels<-") exportMethods("names<-") +exportMethods(.workDir) exportMethods(Arith) exportMethods(Compare) exportMethods(E) @@ -45,6 +47,8 @@ exportMethods(activeCat) exportMethods(activeCats) exportMethods(addCats) exportMethods(aggregate) +exportMethods(allNA) +exportMethods(anyNA) exportMethods(app) exportMethods(appCheck) exportMethods(as.contour) @@ -73,11 +77,11 @@ exportMethods(classify) exportMethods(clump) exportMethods(clusterPoints) exportMethods(colbind) -exportMethods(combineCats) exportMethods(combineLevels) exportMethods(compareGeom) exportMethods(complete.cases) exportMethods(compositeRGB) +exportMethods(concats) exportMethods(connectors) exportMethods(convHull) exportMethods(cos) @@ -117,13 +121,14 @@ exportMethods(freq) exportMethods(geomorphons) exportMethods(geomtype) exportMethods(global) +exportMethods(grassGUI) exportMethods(grid) exportMethods(head) exportMethods(hexagons) exportMethods(hillshade) exportMethods(hist) exportMethods(horizonHeight) -exportMethods(intercept) +exportMethods(init) exportMethods(interpIDW) exportMethods(interpSplines) exportMethods(intersect) @@ -178,18 +183,18 @@ exportMethods(nrow) exportMethods(nsubgeom) exportMethods(nunique) exportMethods(pairs) -exportMethods(pca) exportMethods(plot) exportMethods(plotRGB) exportMethods(predict) +exportMethods(princomp) exportMethods(project) exportMethods(quantile) -exportMethods(r2) exportMethods(rSpatialDepRast) exportMethods(range) exportMethods(rast) exportMethods(rasterize) exportMethods(rbind) +exportMethods(regress) exportMethods(remove0) exportMethods(removeAngles) exportMethods(removeBridges) @@ -211,13 +216,13 @@ exportMethods(sampleRast) exportMethods(scale) exportMethods(scalepop) exportMethods(sdpop) +exportMethods(segregate) exportMethods(selectRange) exportMethods(show) exportMethods(simplifyGeom) exportMethods(sin) exportMethods(sineRast) exportMethods(skewness) -exportMethods(slope) exportMethods(smoothGeom) exportMethods(snap) exportMethods(sources) @@ -229,6 +234,7 @@ exportMethods(st_crs) exportMethods(stdev) exportMethods(streams) exportMethods(stretch) +exportMethods(subset) exportMethods(subst) exportMethods(sum) exportMethods(summary) @@ -242,7 +248,6 @@ exportMethods(top) exportMethods(topology) exportMethods(trim) exportMethods(trunc) -exportMethods(tvalue) exportMethods(union) exportMethods(unscale) exportMethods(update) @@ -254,7 +259,6 @@ exportMethods(voronoi) exportMethods(wetness) exportMethods(which.max) exportMethods(which.min) -exportMethods(workDir) exportMethods(writeRaster) exportMethods(writeVector) exportMethods(xor) diff --git a/NEWS.md b/NEWS.md index 0b1aa192..681230c1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,42 @@ +# fasterRaster 8.4.0.7027 (2024-10-15) + +### Main task for this version +o Test examples with **GRASS 8.4** and update functions as needed. Upgrade to **fasterRaster** 8.4.X.X. + +### Updates for **GRASS 8.4** +o `addLocationProject()` adds either a `project` or `location` argument to a `list` to be passed to `rgrass::execGRASS()`. +o `project()` work with **GRASS** 8.4. +o `.vAttachDatabase()` no longer has the `"o"` flag when calling `v.db.connect` when running **GRASS** >=8.4. + +### Potentially code-breaking changes +o `aggregate()` no longer has the `dissolve` argument for `GVector`s (polygons will always be dissolved). +o `combineCats()` has been renamed `concats()` to align with **terra**. +o `intercept()`, `slope()`, `r2()`, and `tvalue()` have been replaced by the single function `regress()` to align with **terra**. +o `pca()` has been renamed `princomp()`. + +### Enhanced functionality and new functions +o `extract()` now automatically projects a `GVector` to match the CRS of a `GRaster` from which extraction is being made. +o `grassGUI()` allows users to start the **GRASS** GUI. +o `grassHelp()` shows the manual page for a **GRASS** module. +o `layerIndex()` allows a `negate` argument to get the "opposite" indices of a `GRaster`. +o `init()` assigns to `GRaster` cells the value of their coordinates, rows, columns, or values in a regular or chessboard-like pattern. +o `regress()` replaces individual functions `intercept()`, `slope()`, `r2()`, and `tvalue()`. +o `subset()` subsets layers of a `GRaster` or rows/geometries of a `GVector`. +o `segregate()` creates one layer per unique value in an input `GRaster`, with values in the output coded 1 or 0 depending on whether cells in the input had the unique value or not. + +### Bug and issue fixes +o `appFuns()` succeeds in opening a **shiny** table with `app()` functions. +o `categories()` correctly assigns active category column. +o `crds()` correctly returns coordinates from a "points" `GVector`. +o `distance()` correctly parses distance matrix. +o `simplifyGeom()` works for 2-dimensional `GVector`s. +o `flow()` creates a scratch folder when none is provided. +o `global()` does not fail when multiple values of `fun` and `probs` are used and `fun` includes `quantile`. +o `rasterize()` works when `by` is not `NULL`. +o `.layerIndex()` (called by `categories()` and other functions related to categorical `GRaster`s) does not fail. +o `.vHasDatabase()` correctly detects if a vector has a database attached to it. +o Removed all instances of `sQuote()`. + # fasterRaster 8.3.0.7026 (2024-09-22) o Recompile `pkgdown` diff --git a/R/00b_GSpatial_class.r b/R/00b_GSpatial_class.r index 9f6e18d6..666ea42a 100644 --- a/R/00b_GSpatial_class.r +++ b/R/00b_GSpatial_class.r @@ -29,9 +29,9 @@ methods::setValidity("GSpatial", } else if (length(object@crs) != 1L) { "@crs can only be a single character string." } else if (!all(object@topology %in% c(NA_character_, "2D", "3D"))) { - paste0("@topology can only be a NA, ", sQuote("2D"), ", or ", sQuite("3D"), ".") + paste0("@topology can only be a NA, `2D` or `3D`.") } else if (object@topology == "3D" && any(is.na(object@zextent))) { - paste0("@topology is ", sQuote("3D"), " but @zextent has at least one NA value.") + paste0("@topology is `3D` but @zextent has at least one NA value.") } else if (!anyNA(object@zextent[1L]) & is.na(object@zextent[2L]) | (is.na(object@zextent[1L]) & !is.na(object@zextent[2L]))) { "Both values of @zextent must be NA or must be numeric values." } else if (!anyNA(object@zextent) && object@zextent[2L] < object@zextent[1L]) { diff --git a/R/00c_GRegion_class.r b/R/00c_GRegion_class.r index 04675757..80cb8562 100644 --- a/R/00c_GRegion_class.r +++ b/R/00c_GRegion_class.r @@ -1,4 +1,4 @@ -#' @title Classes for "fasterRaster" locations, rasters, and vectors#' +#' @title Classes for "fasterRaster" locations, rasters, and vectors #' #' @aliases GRegion #' @rdname GLocation diff --git a/R/00d_GRaster_class.r b/R/00d_GRaster_class.r index 167fd060..5ce4e28b 100644 --- a/R/00d_GRaster_class.r +++ b/R/00d_GRaster_class.r @@ -113,7 +113,7 @@ GRaster <- methods::setClass( methods::setValidity("GRaster", function(object) { if (!all(object@datatypeGRASS %in% c("CELL", "FCELL", "DCELL"))) { - paste0("@datatypeGRASS can only be NA, ", sQuote("CELL"), ", ", sQuote("FCELL"), ", or ", sQuote("DCELL"), ".") + paste0("@datatypeGRASS can only be NA, ``CELL`, `FCELL`, or `DCELL`.") } else if (!is.na(object@dimensions[3L]) && object@dimensions[3L] <= 0L) { "Third value in @dimensions must be NA or a positive integer." } else if (!is.na(object@resolution[3L]) && object@resolution[3L] <= 0) { diff --git a/R/00e_GVector_class.r b/R/00e_GVector_class.r index 18f27580..af1143df 100644 --- a/R/00e_GVector_class.r +++ b/R/00e_GVector_class.r @@ -31,9 +31,9 @@ methods::setValidity("GVector", if (!info$catsValid) { "Vector has invalid topology. See the *Details* section in `fast()` on how to correct topology." } else if (!all(object@geometry %in% c(NA_character_, "points", "lines", "polygons"))) { - paste0("@geometry can only be NA, ", sQuote("points"), ", ", sQuote("lines"), ", or ", sQuote("polygons"), ".") + paste0("@geometry can only be NA, `points`, `lines`, or `polygons`.") # } else if (length(unique(.vCats(object)) != object@nGeometries)) { - # "The number of @nGeometries is not the same as the number of unique ", sQuote("cat"), " values in the vector attribute table in GRASS." + # "The number of @nGeometries is not the same as the number of unique `cat` values in the vector attribute table in GRASS." # } else if (object@nGeometries > object@nSubgeometries) { # "The number of sub-geometries in @nSubgeometries must be <= the number of geometries in @nGeometries." } else if (object@nGeometries == 0L) { diff --git a/R/01_generics.r b/R/01_generics.r index c94efd8d..4420a357 100644 --- a/R/01_generics.r +++ b/R/01_generics.r @@ -64,6 +64,8 @@ methods::setGeneric(name = "addCats", package = "terra") methods::setGeneric(name = "addCats<-", def = function(x, ..., value) standardGeneric("addCats<-")) methods::setGeneric(name = "addTable<-", def = function(x, ..., value) standardGeneric("addTable<-")) # methods::setGeneric(name = "andAndAnd", def = function(e1, e2) standardGeneric("andAndAnd")) +methods::setGeneric(name = "allNA", package = "terra") +# anyNA: generic is implicit methods::setGeneric(name = "app", package = "terra") # methods::setGeneric(name = "appFuns", def = function(x, ...) standardGeneric("appFuns")) methods::setGeneric(name = "appCheck", def = function(x, fun, ...) standardGeneric("appCheck")) @@ -102,8 +104,8 @@ methods::setGeneric(name = "clusterPoints", def = function(x, ...) standardGener methods::setGeneric(name = "compareGeom", package = "terra") methods::setGeneric("complete.cases", function(...) standardGeneric("complete.cases"), package = "stats") methods::setGeneric(name = "compositeRGB", def = function(r, ...) standardGeneric("compositeRGB")) -methods::setGeneric(name = "combineCats", def = function(x, ...) standardGeneric("combineCats")) methods::setGeneric(name = "combineLevels", def = function(x, ...) standardGeneric("combineLevels")) +methods::setGeneric(name = "concats", def = function(x, ...) standardGeneric("concats")) methods::setGeneric(name = "connectors", def = function(x, y, ...) standardGeneric("connectors")) methods::setGeneric(name = "convHull", package = "terra") methods::setGeneric(name = "count", def = function(x, ...) standardGeneric("count")) @@ -147,6 +149,7 @@ methods::setGeneric(name = "fragmentation", def = function(x, ...) standardGener methods::setGeneric(name = "geomtype", package = "terra") methods::setGeneric(name = "geomorphons", def = function(x, ...) standardGeneric("geomorphons")) methods::setGeneric(name = "global", package = "terra") +methods::setGeneric(name = "grassGUI", def = function(x, ...) standardGeneric("grassGUI")) methods::setGeneric(name = "grid", def = function(x, ...) standardGeneric("grid")) methods::setGeneric(name = "head", package = "utils") @@ -155,8 +158,8 @@ methods::setGeneric(name = "hillshade", def = function(x, ...) standardGeneric(" methods::setGeneric(name = "hist", package = "terra") methods::setGeneric(name = "horizonHeight", def = function(x, ...) standardGeneric("horizonHeight")) +methods::setGeneric(name = "init", package = "terra") methods::setGeneric(name = "intersect", package = "terra") -methods::setGeneric(name = "intercept", def = function(x, ...) standardGeneric("intercept")) methods::setGeneric(name = "interpIDW", package = "terra") methods::setGeneric(name = "interpSplines", def = function(x, y, ...) standardGeneric("interpSplines")) methods::setGeneric(name = "is.2d", def = function(x) standardGeneric("is.2d")) @@ -218,17 +221,15 @@ methods::setGeneric(name = "nunique", def = function(x, ...) standardGeneric("nu methods::setGeneric(name = "reorient", def = function(x, ...) standardGeneric("reorient")) methods::setGeneric(name = "pairs", package = "terra") -methods::setGeneric(name = "pca", def = function(x, ...) standardGeneric("pca")) methods::setGeneric(name = "plot", package = "terra") methods::setGeneric(name = "plotRGB", package = "terra") methods::setGeneric(name = "predict", package = "terra") -# methods::setGeneric(name = "print", def = function(x, ...) standardGeneric("print")) # base +methods::setGeneric(name = "princomp", package = "terra") methods::setGeneric(name = "print") # base methods::setGeneric(name = "project", package = "terra") methods::setGeneric(name = "quantile", package = "terra") -methods::setGeneric(name = "r2", def = function(x, ...) standardGeneric("r2")) methods::setGeneric(name = "rast", package = "terra") methods::setGeneric(name = "rasterize", package = "terra") # methods::setGeneric(name = "rbind") @@ -237,6 +238,7 @@ methods::setGeneric(name = "rasterize", package = "terra") methods::getGeneric("rbind") methods::setGeneric(name = "rbind", signature = "...") +methods::setGeneric(name = "regress", package = "terra") methods::setGeneric(name = "remove0", def = function(x, ...) standardGeneric("remove0")) methods::setGeneric(name = "removeAngles", def = function(x, ...) standardGeneric("removeAngles")) methods::setGeneric(name = "removeBridges", def = function(x, ...) standardGeneric("removeBridges")) @@ -259,12 +261,12 @@ methods::setGeneric(name = "scale", package = "terra") methods::setGeneric(name = "scalepop", def = function(x, ...) standardGeneric("scalepop")) methods::setGeneric(name = "sdpop", def = function(x, ...) standardGeneric("sdpop")) methods::setGeneric(name = "selectRange", def = function(x, ...) standardGeneric("selectRange")) +methods::setGeneric(name = "segregate", def = function(x, ...) standardGeneric("segregate")) methods::setGeneric(name = "show", package = "methods") methods::setGeneric(name = "simplifyGeom", package = "terra") methods::setGeneric(name = "sineRast", def = function(x, ...) standardGeneric("sineRast")) methods::setGeneric(name = "smoothGeom", def = function(x, ...) standardGeneric("smoothGeom")) methods::setGeneric(name = "skewness", def = function(x, ...) standardGeneric("skewness")) -methods::setGeneric(name = "slope", def = function(x, ...) standardGeneric("slope")) methods::setGeneric(name = "snap", package = "terra") methods::setGeneric(name = "sources", package = "terra") methods::setGeneric(name = "spatSample", package = "terra") @@ -278,6 +280,7 @@ methods::setGeneric(name = "st_buffer", package = "sf") methods::setGeneric(name = "st_crs", package = "sf") # methods::setGeneric(name = "st_distance", package = "sf") methods::setGeneric(name = "stdev", package = "terra") +methods::setGeneric(name = "subset", package = "terra") methods::setGeneric(name = "subst", package = "terra") methods::setGeneric(name = "summary", def = function(object, ...) standardGeneric("summary")) @@ -288,7 +291,6 @@ methods::setGeneric(name = "tiles", def = function(x, ...) standardGeneric("tile methods::setGeneric(name = "top", def = function(x, ...) standardGeneric("top")) methods::setGeneric(name = "topology", def = function(x, ...) standardGeneric("topology")) methods::setGeneric(name = "trim", package = "terra") -methods::setGeneric(name = "tvalue", def = function(x, ...) standardGeneric("tvalue")) methods::setGeneric(name = "update", package = "terra") methods::setGeneric(name = "union", package = "terra") @@ -299,9 +301,9 @@ methods::setGeneric(name = "vegIndex", def = function(x, ...) standardGeneric("v methods::setGeneric(name = "vect", package = "terra") methods::setGeneric(name = "voronoi", package = "terra") +methods::setGeneric(name = ".workDir", def = function(x, ...) standardGeneric(".workDir")) methods::setGeneric(name = "W", def = function(x, ...) standardGeneric("W")) methods::setGeneric(name = "wetness", def = function(x, ...) standardGeneric("wetness")) -methods::setGeneric(name = "workDir", def = function(x, ...) standardGeneric("workDir")) methods::setGeneric(name = "writeRaster", package = "terra") methods::setGeneric(name = "writeVector", package = "terra") diff --git a/R/02_defaults.r b/R/02_defaults.r index b7a6e572..6ee1330b 100644 --- a/R/02_defaults.r +++ b/R/02_defaults.r @@ -3,7 +3,8 @@ # global PUBLIC options .grassDirDefault <- function() NA_character_ .addonsDirDefault <- function() NA_character_ -.workDirDefault <- function() file.path(omnibus::forwardSlash(tempdir())) +# .workDirDefault <- function() file.path(omnibus::forwardSlash(tempdir()), omnibus::rstring(1)) +.workDirDefault <- function() omnibus::forwardSlash(tempdir()) .locationDefault <- function() "default" # .mapsetDefault <- function() "PERMANENT" diff --git a/R/03_options.r b/R/03_options.r index 12cfab58..cfd19548 100644 --- a/R/03_options.r +++ b/R/03_options.r @@ -18,8 +18,8 @@ #' Options include: #' #' * `grassDir` (character): The folder in which **GRASS** is installed on your computer. Typically, this option is set when you run [faster()]. Depending on your operating system, your install directory will look something like this: -#' * Windows: `"C:/Program Files/GRASS GIS 8.3"` -#' * Mac OS: `"/Applications/GRASS-8.3.app/Contents/Resources"` +#' * Windows: `"C:/Program Files/GRASS GIS 8.4"` +#' * Mac OS: `"/Applications/GRASS-8.4.app/Contents/Resources"` #' * Linux: `"/usr/local/grass"` #' #' * `addonsDir` (character): Folder in which **GRASS** addons are stored. If `NA` and `grassDir` is not `NA`, this will be assumed to be `file.path(grassDir, "addons")`. The default values is `NA`. @@ -28,13 +28,13 @@ #' #' * `memory` (integer/numeric): The amount of memory to allocate to a task, in GB, for **GRASS**. The default is 2048 MB (i.e., 2 GB). Some **GRASS** modules can take advantage of more memory. #' -#' * `clean` (logical): If `TRUE` (default), remove temporary files created internally by functions. If not deleted, they can eventually fill up hard drive space, but deleting them takes a little bit of time (usually <1 second for each function). +#' * `clean` (logical): If `TRUE` (default), remove temporary files created internally by functions. If not deleted, they can eventually fill up hard drive space, but deleting them takes a little bit of time (usually <1 second for each function). See also [mow()]. #' #' * `useDataTable` (logical): If `FALSE` (default), functions that return tabular output produce `data.frame`s. If `TRUE`, output will be `data.table`s from the **data.table** package. This can be much faster, but it might require you to know how to use `data.table`s if you want to manipulate them in **R**. You can always convert them to `data.frame`s using [base::as.data.frame()]. #' #' * `verbose` (logical): If `TRUE`, show **GRASS** messages and otherwise hidden slots in classes. This is mainly used for debugging, so most users will want to keep this at its default, `FALSE`. #' -#' * `workDir` (character): The folder in which **GRASS** rasters, vectors, and other objects are created and manipulated. By default, this is given by [tempdir()]. +#' * `workDir` (character): The folder in which **GRASS** rasters, vectors, and other objects are created and manipulated. By default, this is given by [tempdir()]. Note that on some systems, changing the default folder to somewhere else can cause problems with **fasterRaster** being able to find rasters in **GRASS** that have been created. #' #' @param restore Logical: If `TRUE`, the all options will be reset to their default values. The default is `FALSE`. #' diff --git a/R/04_arithmetic.r b/R/04_arithmetic.r index 28fd9fa0..5a1fc93b 100644 --- a/R/04_arithmetic.r +++ b/R/04_arithmetic.r @@ -12,7 +12,7 @@ #' #' @return A `GRaster`. #' -#' @example man/examples/ex_GRaster_arithmetic.r +#' @example man/examples/ex_GRaster_arithmetic_by_layer.r #' #' @aliases Arith #' @rdname Arithmetic diff --git a/R/05_GRaster_functions_byLayer.r b/R/05_GRaster_functions_by_layer.r similarity index 99% rename from R/05_GRaster_functions_byLayer.r rename to R/05_GRaster_functions_by_layer.r index cd75b368..d55f2c8e 100644 --- a/R/05_GRaster_functions_byLayer.r +++ b/R/05_GRaster_functions_by_layer.r @@ -41,7 +41,7 @@ #' #' @returns A `GRaster`. #' -#' @example man/examples/ex_GRaster_arithmetic.r +#' @example man/examples/ex_GRaster_arithmetic_by_layer.r #' #' @aliases is.na #' @rdname math diff --git a/R/06_GRaster_functions_acrossLayers.r b/R/06_GRaster_functions_across_layers.r similarity index 89% rename from R/06_GRaster_functions_acrossLayers.r rename to R/06_GRaster_functions_across_layers.r index c34b7ae5..1dddbdd4 100644 --- a/R/06_GRaster_functions_acrossLayers.r +++ b/R/06_GRaster_functions_across_layers.r @@ -5,7 +5,7 @@ #' * Central tendency: `mean()`, `mmode()` (mode), `median()`. #' * Extremes: `min()`, `max()`, `which.min()` (index of raster with the minimum value), `which.max()` (index of the raster with the maximum value) #' * Dispersion: `range()`, `stdev()` (standard deviation), `var()` (sample variance), `varpop()` (population variance), `nunique()` (number of unique values), `quantile()` (use argument `probs`), `skewness()`, and `kurtosis()`. -#' * Regression: Assuming we calculate a linear regression for each set of cells through all values of the cells, we can calculate its `slope()`, `intercept()`, `r2()`, and `tvalue()`. +#' * `NA`s: `anyNA()` (any cells are `NA`?), `allNA()` (are all cells `NA`?) #' #' @param x A `GRaster`. Typically, this raster will have two or more layers. Values will be calculated within cells across rasters. #' @@ -17,7 +17,7 @@ #' #' @returns A `GRaster`. #' -#' @example man/examples/ex_GRaster_arithmetic.r +#' @example man/examples/ex_GRaster_arithmetic_across_layers.r #' #' @aliases mean #' @rdname functions @@ -357,66 +357,6 @@ setMethod( } # EOF ) -#' @aliases slope -#' @rdname functions -#' @exportMethod slope -setMethod( - "slope", - signature(x = "GRaster"), - function(x, na.rm = FALSE) { - - fx <- "slope" - fxName <- "slope" - .genericMultiLayer(fx = fx, fxName = fxName, x = x, na.rm = na.rm) - - } # EOF -) - -#' @aliases intercept -#' @rdname functions -#' @exportMethod intercept -setMethod( - "intercept", - signature(x = "GRaster"), - function(x, na.rm = FALSE) { - - fx <- "offset" - fxName <- "intercept" - .genericMultiLayer(fx = fx, fxName = fxName, x = x, na.rm = na.rm) - - } # EOF -) - -#' @aliases r2 -#' @rdname functions -#' @exportMethod r2 -setMethod( - "r2", - signature(x = "GRaster"), - function(x, na.rm = FALSE) { - - fx <- "detcoeff" - fxName <- "r2" - .genericMultiLayer(fx = fx, fxName = fxName, x = x, na.rm = na.rm) - - } # EOF -) - -#' @aliases tvalue -#' @rdname functions -#' @exportMethod tvalue -setMethod( - "tvalue", - signature(x = "GRaster"), - function(x, na.rm = FALSE) { - - fx <- "tvalue" - fxName <- "tvalue" - .genericMultiLayer(fx = fx, fxName = fxName, x = x, na.rm = na.rm) - - } # EOF -) - #' @aliases range #' @rdname functions #' @exportMethod range @@ -466,6 +406,54 @@ setMethod( } # EOF ) +#' @aliases anyNA +#' @rdname functions +#' @exportMethod anyNA +setMethod( + "anyNA", + signature(x = "GRaster"), + function(x) { + + .locationRestore(x) + .region(x) + + src <- .makeSourceName("anyNA", "raster") + + nl <- nlyr(x) + ex <- paste0("if(isnull(", sources(x), "))") + ex <- paste(ex, collapse = " | ") + ex <- paste0(src, " = ", ex) + rgrass::execGRASS("r.mapcalc", expression = ex, flags = c(.quiet(), "overwrite")) + .makeGRaster(src, "layer") + + } # EOF +) + + +#' @aliases allNA +#' @rdname functions +#' @exportMethod allNA +setMethod( + "allNA", + signature(x = "GRaster"), + function(x) { + + .locationRestore(x) + .region(x) + + src <- .makeSourceName("anyNA", "raster") + + nl <- nlyr(x) + ex <- paste0("if(isnull(", sources(x), "))") + ex <- paste(ex, collapse = " & ") + ex <- paste0(src, " = ", ex) + rgrass::execGRASS("r.mapcalc", expression = ex, flags = c(.quiet(), "overwrite")) + .makeGRaster(src, "layer") + + } # EOF +) + + # generic function for multi-layer functions # fx: name of GRASS function @@ -503,7 +491,7 @@ setMethod( } else if (return == "source") { out <- src } else { - stop("Invalid value for ", sQuote("return"), ".") + stop("Invalid value for `return`.") } out diff --git a/R/07_comparison.r b/R/07_comparison.r index 70adfd32..c292d883 100644 --- a/R/07_comparison.r +++ b/R/07_comparison.r @@ -13,7 +13,7 @@ #' #' Comparing `GRegion`s: Output is logical. #' -#' @example man/examples/ex_GRaster_arithmetic.r +#' @example man/examples/ex_GRaster_comparison_logic.r #' #' @aliases Compare-methods #' @rdname Compare-methods diff --git a/R/08_logic.r b/R/08_logic.r index d1d692d3..beb49fe4 100644 --- a/R/08_logic.r +++ b/R/08_logic.r @@ -1,6 +1,6 @@ #' Logic-methods operations on GRasters #' -#' @description You can do logical operations on `GRaster`s. Here, a value of 1 is interpreted as `TRUE`, and a value of 0 is interpreted as `FALSE`. You can compare: +#' @description You can do logical operations on `GRaster`s. A cell with a value of 1 is interpreted as `TRUE`, and a value of 0 is interpreted as `FALSE`. You can compare: #' * A `GRaster` to another `GRaster` #' * A `GRaster` to a logical value (`TRUE` or `FALSE`, but not `NA`--see [not.na()]) #' * A `GRaster` to a numeric or integer value that is 0 or 1 @@ -13,7 +13,7 @@ #' #' @returns A binary `GRaster` (1 ==> `TRUE`, 0 ==> `FALSE`, plus `NA` when comparison results in `NA`). #' -#' @example man/examples/ex_GRaster_arithmetic.r +#' @example man/examples/ex_GRaster_comparison_logic.r #' #' @aliases Logic-methods #' @rdname Logic-methods diff --git a/R/addLocationProject.r b/R/addLocationProject.r new file mode 100644 index 00000000..5a7b6e0d --- /dev/null +++ b/R/addLocationProject.r @@ -0,0 +1,21 @@ +#' Add a "project" or "location" argument to an "args" list +#' +#' @description Unhelpfully, starting with **GRASS** 8.4, what were previously called "locations" and now called "projects." These were supposed to be back-compatible, but are not. This function takes a list of arguments that will be passed to [rgrass::execGRASS()] and adds either a "location" or "project" argument, depending on the version of **GRASS** being used. +#' +#' @param args A `list` of arguments to be passed to a **GRASS** module. +#' @param locProj Character: The name of the location or project. +#' +#' @returns A `list`. +#' +#' @keywords internal +.addLocationProject <- function(args, locProj) { + + ver <- grassInfo("versionNumber") + if (ver <= 8.3) { + args$location <- locProj + } else { + args$project <- locProj + } + args + +} diff --git a/R/aggregate.r b/R/aggregate.r index 7e517de9..592b5dbe 100644 --- a/R/aggregate.r +++ b/R/aggregate.r @@ -30,8 +30,6 @@ #' #' @param weight Logical (rasters only): If `FALSE`, each source cell that has its center in the destination cell will be counted equally. If `TRUE`, the value of each source will be weighted the proportion of the destination cell the source cell covers. #' -#' @param dissolve Logical (vectors only): If `TRUE` (default), then aggregated geometries will have their borders dissolved. This is ignored if the input `GVector` is not a "polygons" vector. -#' #' @returns A `GRaster` or `GVector`. #' #' @seealso [stats::aggregate()], [terra::aggregate()], [disagg()], [terra::disagg()] @@ -53,7 +51,7 @@ methods::setMethod( na.rm = FALSE ) { - if (any(fact <= 0)) stop("Values of ", sQuote("fact"), " must be > 0.") + if (any(fact <= 0)) stop("Values of `fact` must be > 0.") funs <- c("mean", "median", "mode", "min", "maximum", "range", "quantile", "sum", "varpop", "sdpop", "count", "diversity") fun <- omnibus::pmatchSafe(tolower(fun), funs) @@ -70,9 +68,9 @@ methods::setMethod( fun <- "stdev" } else if (fun == "quantile") { - if (is.null(prob)) stop("A value must be specified for ", sQuote("prob"), " if the aggregating function is ", sQuote("quantile"), ".") + if (is.null(prob)) stop("A value must be specified for `prob` if the aggregating function is `quantile`.") - if (prob < 0 | prob > 1) stop("Argument ", sQuote("prob"), " must be in the range [0, 1].") + if (prob < 0 | prob > 1) stop("Argument `prob` must be in the range [0, 1].") } @@ -157,11 +155,12 @@ methods::setMethod( methods::setMethod( f = "aggregate", signature = c(x = "GVector"), - function(x, dissolve = TRUE) { + function(x) { .locationRestore(x) gtype <- geomtype(x) - src <- .aggregate(x, dissolve = dissolve, gtype = gtype, copy = TRUE) + # src <- .aggregate(x, dissolve = dissolve, gtype = gtype, copy = TRUE) + src <- .aggregate(x, dissolve = TRUE, gtype = gtype, copy = TRUE) # aggregate data table if (nrow(x) == 0L) { @@ -221,7 +220,7 @@ methods::setMethod( #' @param dissolve Logical #' @param copy Logical: If TRUE, make copy of vector before operations #' @noRd -.aggregate <- function(x, gtype, dissolve, copy) { +.aggregate <- function(x, dissolve, gtype, copy) { if (inherits(x, "GVector")) { .locationRestore(x) @@ -235,8 +234,8 @@ methods::setMethod( oldcats <- .vCats(src, db = FALSE) if (length(oldcats) > 1L) { - table <- data.table::data.table(fr = rep(1L, length(oldcats))) - .vAttachDatabase(src, table = table, replace = TRUE) + table <- data.table::data.table(frid = rep(1L, length(oldcats))) + .vAttachDatabase(src, table = table, replace = TRUE, cats = oldcats) # newcats <- data.frame(oldfr = oldcats, fr = rep(1L, length(oldcats))) diff --git a/R/app.r b/R/app.r index f2a37fea..5089818a 100644 --- a/R/app.r +++ b/R/app.r @@ -6,15 +6,15 @@ #' #' `appCheck()` tests whether a formula supplied to `app()` has any "forbidden" function calls. #' -#' The `app()` function operates in a manner slightly different from [terra::app()]. The function to be applied *must* be written as a character string. For example, if the raster had layer names "`x1`" and "`x2`", then the function might be like `"= max(sqrt(x1), log(x2))"`. Rasters **cannot** have the same names as functions used in the formula. In this example, the rasters could not be named "max", "sqrt", or "log". +#' The `app()` function operates in a manner somewhat different from [terra::app()]. The function to be applied *must* be written as a character string. For example, if the `GRaster` had layer names "`x1`" and "`x2`", then the function might be like `"= max(sqrt(x1), log(x2))"`. Rasters **cannot** have the same names as functions used in the formula. In this example, the rasters could not be named "max", "sqrt", or "log". Note that the name of a `GRaster` is given by [names()]--this can be different from the name of the object in **R**. #' -#' The `app()` function will automatically check for raster names that appear also to be functions that appear in the formula. However, you can check a formula before running `app()` by using the `appCheck()` function. You can obtain a list of `app()` functions using `appFuns()`. Note that these are sometimes different from how they are applied in **R**. +#' The `app()` function will automatically check for `GRaster` names that appear also to be functions that appear in the formula. However, you can check a formula before running `app()` by using the `appCheck()` function. You can obtain a list of `app()` functions using `appFuns()`. Note that these are sometimes different from how they are applied in **R**. #' #' Tips: #' * Make sure your `GRaster`s have `names()`. The function matches on these, not the name of the variable you use in **R** for the `GRaster`. -#' * In **GRASS**, use `null()` instead of `NA`, and use `isnull()` instead of `is.na()`. +#' * Use `null()` instead of `NA`, and use `isnull()` instead of `is.na()`. #' * If you want to calculate values using while ignoring `NA` (or `null`) values, see the functions that begin with `n` (like `nmean`). -#' * Be mindful of the data type that a function returns. In **GRASS**, these are `CELL` (integer), `FCELL` (floating point values--precise to about the 7th decimal place), and `DCELL` (double-floating point values--precise to about the 15th decimal place). In cases where you want to datatype a raster to be treated like a float or double data type raster, wrap the raster in the `float()` or `double()` functions to datatype it is treated as such. This is especially useful if the raster might be assumed to be the `CELL` type because it only contains integer values. You can get the data type of a raster using [datatype()] with the `type` argument set to `GRASS`. You can change the data type of a `GRaster` using [as.int()], [as.float()], and [as.doub()]. Note that categorical rasters are really `CELL` (integer) rasters with an associated "levels" table. You can also change a `CELL` raster to a `FCELL` raster by adding then subtracting a decimal value, as in `x - 0.1 + 0.1`. See `vignette("GRasters", package = "fasterRaster")`. +#' * Be mindful of the data type that a function returns. In **GRASS**, these are `CELL` (integer), `FCELL` (floating point values--precise to about the 7th decimal place), and `DCELL` (double-floating point values--precise to about the 15th decimal place; commensurate with the **R** `numeric` type). In cases where you want a `GRaster` to be treated like a float or double type raster, wrap the name of the `GRaster` in the `float()` or `double()` functions. This is especially useful if the `GRaster` might be assumed to be the `CELL` type because it only contains integer values. You can get the data type of a raster using [datatype()] with the `type` argument set to `GRASS`. You can change the data type of a `GRaster` using [as.int()], [as.float()], and [as.doub()]. Note that categorical rasters are really `CELL` (integer) rasters with an associated "levels" table. You can also change a `CELL` raster to a `FCELL` raster by adding then subtracting a decimal value, as in `x - 0.1 + 0.1`. See `vignette("GRasters", package = "fasterRaster")`. #' * The `rand()` function returns integer values by default. If you want non-integer values, use the tricks mentioned above to datatype non-integer values. For example, if you want uniform random values in the range between 0 and 1, use something like `= float(rand(0 + 0.1, 1 + 0.1) - 0.1)`. #' #' @param x A `GRaster` with one or more named layers. @@ -24,7 +24,7 @@ #' * It must use typical arithmetic operators like `+`, `-`, `*`, `/` and/or functions that can be seen using `appFuns(TRUE)`. #' * The [names()] of the rasters do not match any of the functions in the `appFuns(TRUE)` table. Note that `x` and `y` are forbidden names :( #' -#' The help page for **GRASS** module [`r.mapcalc`](https://grass.osgeo.org/grass84/manuals/r.mapcalc.html) will be especially helpful. +#' The help page for **GRASS** module `r.mapcalc` will be especially helpful. You can see this page using `grassHelp("r.mapcalc")`. #' #' @param datatype Character: This ensures that rasters are treated as a certain type before they are operated on. This is useful when using rasters that have all integer values, which **GRASS** can assume represent integers, even if they are not supposed to. In this case, the output of operations on this raster might be an integer if otherwise not corrected. Partial matching is used, and options include: #' * `"integer"`: Force all rasters to integers by truncating their values. The output may still be of type `float` if the operation creates non-integer values. @@ -42,10 +42,11 @@ #' #' @returns A `GRaster`. #' -#' @seealso [terra::app()], [terra::lapp()], [subst()], [classify()], and modules [`r.mapcalc`](https://grass.osgeo.org/grass84/manuals/r.mapcalc.html) and `r.mapcalc.simple` in **GRASS**. +#' @seealso [terra::app()], [terra::lapp()], [subst()], [classify()], and modules `r.mapcalc` in **GRASS** (viewable using `grassHelp("r.mapcalc")`) #' #' @example man/examples/ex_app.r #' +#' @name app #' @aliases app,lapp #' @rdname app #' @exportMethod app @@ -117,30 +118,24 @@ methods::setMethod( } # EOF ) -# #' @aliases appFuns -# #' @rdname app -# #' @export -# methods::setMethod( - # f = "appFuns", - # signature = c(x = "logical"), - # function(x = FALSE) { - #' @aliases appFuns #' @rdname app #' @export appFuns <- function(warn = TRUE) { - # appFunsTable <- NULL + appFunsTable <- NULL utils::data("appFunsTable", envir = environment(), package = "fasterRaster") - if (interactive()) { - showableCols <- c("Type", "GRASS_Function", "R_Function", "Definition", "Returns") + if (interactive()) { + + showableCols <- c("Type", "GRASS_Function", "R_Function", "Definition", "Returns") shiny::shinyApp( ui = shiny::fluidPage(DT::DTOutput("tbl")), server = function(input, output) { output$tbl <- DT::renderDT( - appFunsTable[ , showableCols], + # appFunsTable[ , showableCols], + appFunsTable[ , c("Type", "GRASS_Function", "R_Function", "Definition", "Returns")], caption = shiny::HTML("Functions that can be used in the fasterRaster app() function and their equivalents in R.
Note that in GRASS, 'null()' is the same as 'NA'."), options = list( pageLength = nrow(appFunsTable), @@ -156,14 +151,8 @@ appFuns <- function(warn = TRUE) { warning("You must be running R interactively to view the table using appFuns().") } - if (faster("useDataTable")) appFunsTable <- data.table::data.table(appFunsTable) - invisible(appFunsTable) - } - # } # EOF -# ) - #' @aliases appCheck #' @rdname app #' @exportMethod appCheck @@ -174,13 +163,20 @@ methods::setMethod( # any forbidden names in rasters? ns <- names(x) - funs <- appFuns(warn = FALSE) - if (inherits(funs, "data.table")) { - funs <- funs[["GRASS_Function"]] + appFunsTable <- NULL + utils::data("appFunsTable", envir = environment(), package = "fasterRaster") + + if (inherits(appFunsTable, "data.table")) { + funs <- appFunsTable[["GRASS_Function"]] } else { - funs$GRASS_Function + funs <- appFunsTable$GRASS_Function } + + parens <- regexec(funs, pattern = "\\(") + parens <- unlist(parens) + parens <- parens - 1L + funs <- substr(funs, 1L, parens) bads <- funs[funs %in% ns] @@ -198,15 +194,15 @@ methods::setMethod( if (length(realBads) > 0L) { - msg <- "At least one raster has a forbidden name that seems to appear in the string." + msg <- "At least one raster has a forbidden name that seems to appear in the equation:" if (failOnBad) { - stop(msg, "\n", realBads) + stop(msg, "\n", paste(realBads, collapse = " ")) } else { warning(msg) return(realBads) } } else if (msgOnGood) { - msg <- "Rasters have one or more forbidden names, but they do not seem to appear in the string." + msg <- "The GRasters have one or more forbidden names, but they do not seem to appear in\n the equation. Use the equation with caution, or rename your GRasters." warning(msg) } } diff --git a/R/as.contour.r b/R/as.contour.r index 19c9ec9d..61875512 100644 --- a/R/as.contour.r +++ b/R/as.contour.r @@ -24,8 +24,8 @@ setMethod( .locationRestore(x) .region(x) - if (!missing(nlevels) & !missing(levels)) stop("Please specify either ", sQuote("nlevels"), " or ", sQuote("levels"), ", but not both.") - if (missing(nlevels) & missing(levels)) stop("Please specify either ", sQuote("nlevels"), " or ", sQuote("levels"), ".") + if (!missing(nlevels) & !missing(levels)) stop("Please specify either `nlevels` or `levels`, but not both.") + if (missing(nlevels) & missing(levels)) stop("Please specify either `nlevels` or `levels`.") if (!missing(nlevels)) { mm <- minmax(x) diff --git a/R/as.lines.r b/R/as.lines.r index 0c2e91b6..6c5ca388 100644 --- a/R/as.lines.r +++ b/R/as.lines.r @@ -1,6 +1,6 @@ #' Convert a raster to a lines vector #' -#' @description [as.lines()] converts a `GRaster` to a "lines" `GVector`. Before you apply this function, you may need to run [thinLines()] on the raster to reduce linear features to a single-cell width. You may also need to use [clean geometry][breakPolys] (especially the "duplicated" and "removeDangles" `method`s) afterward to remove duplicated vertices and "dangling" lines. +#' @description [as.lines()] converts a `GRaster` to a "lines" `GVector`. Before you apply this function, you may need to run [thinLines()] on the raster to reduce linear features to a single-cell width. You may also need to use [clean geometry][breakPolys] (especially the [removeDups()] and [removeDangles()]) afterward to remove duplicated vertices and "dangling" lines. #' #' @param x A `GRaster`. If more than one layer is in the `GRaster`, only the first will be used (with a warning). #' diff --git a/R/backdoor.r b/R/backdoor.r index 9463da03..2773f398 100644 --- a/R/backdoor.r +++ b/R/backdoor.r @@ -1,6 +1,21 @@ #' Setup fasterRaster for ABS #' -#' This is a secret function for ABS's machine to be used for faster development of **fasterRaster**. +#' This is a secret function to be used for faster development of **fasterRaster**. It assume development is on a Windows machine. #' -#' @noRd -.backdoor <- function() faster(grassDir = "C:/Program Files/GRASS GIS 8.3", memory = 1024 * 8, cores = 2, verbose = TRUE) +#' @param ver Character: **GRASS**: e.g., "83" or "84". +#' +#' @returns `TRUE` (invisibly). +#' +#' @keywords internal +.backdoor <- function(ver = "84") { + + verNice <- paste0(substr(ver, 1L, 1L), ".", substr(ver, 2L, 2L)) + + faster( + grassDir = paste0("C:/Program Files/GRASS GIS ", verNice), + memory = 1024 * 8, + cores = 2, + verbose = TRUE + ) + invisible(TRUE) +} diff --git a/R/bioclims_GRaster.r b/R/bioclims_GRaster.r index 26013340..7b866ac7 100644 --- a/R/bioclims_GRaster.r +++ b/R/bioclims_GRaster.r @@ -2,6 +2,7 @@ #' #' @description The BIOCLIM set of bioclimatic variables were created for modeling species' geographic distributions (Booth et al. 2014). This function can create the "standard" 19 set of variables, plus several more from an "extended" set. #' +#' "Classic" set of BIOCLIM variables (Booth et al. 2014): #' The units reported below assume that input rasters are in mm (precipitation) and deg C (temperature), and that each raster represents a month (but other time units are allowed, with corresponding changes to the temporal units assumed below). #' #' * BIO1: Mean annual temperature, calculated using monthly means (deg C) @@ -29,22 +30,22 @@ #' * BIO41: Temperature of the quarter following the coldest quarter (based on mean temperature; deg C) #' * BIO42: Temperature of the quarter following the warmest quarter (based on mean temperature; deg C) #' * BIO43: Precipitation of the quarter following the coldest quarter (based on mean temperature; mm) -#' * BIO44: Precipitation of the quarter following the warmest quarter (based on mean temperature; mm) +#' * BIO44: Precipitation of the quarter following the warmest quarter (based on mean temperature; mm) #' #' * BIO45: Temperature of the quarter following the driest quarter (based on mean temperature; deg C) #' * BIO46: Temperature of the quarter following the wettest quarter (based on mean temperature; deg C) #' * BIO47: Precipitation of the quarter following the driest quarter (based on mean temperature; mm) -#' * BIO48: Precipitation of the quarter following the wettest quarter (based on mean temperature; mm) +#' * BIO48: Precipitation of the quarter following the wettest quarter (based on mean temperature; mm) #' #' * BIO49: Hottest month (based on maximum temperature) #' * BIO50: Coldest month (based on minimum temperature) #' * BIO51: Wettest month -#' * BIO52: Driest month +#' * BIO52: Driest month #' #' * BIO53: First month of the warmest quarter (based on mean temperature) #' * BIO54: First month of the coldest quarter (based on mean temperature) #' * BIO55: First month of the wettest quarter -#' * BIO56: First month of the driest quarter +#' * BIO56: First month of the driest quarter #' #' * BIO57: The greatest decrease in temperature from one month to the next (deg C; always >= 0) #' * BIO58: The greatest increase in temperature from one month to the next (deg C; always >= 0) @@ -59,8 +60,6 @@ #' #' BIOCLIMs 49 through 60 are not bioclimatic variables per se, but useful for assessing the properties of the variables that are defined based on the "-est" month or quarter. #' -#' The numbering of the new BIOCLIMs was begun at 41 because BIOCLIMs 20 through 40 are taken (Kriticos et al. 2014). -#' #' @param ppt A multi-layered `GRaster` or `SpatRaster`, representing monthly/weekly/daily precipitation. #' #' @param tmin,tmax A multi-layered `GRaster` or `SpatRaster`, representing monthly/weekly/daily minimum and maximum temperature. @@ -72,7 +71,7 @@ #' * `NULL` (default): Calculate BIOCLIMs 1 through 19 #' * `"*"`: Calculate all BIOCLIMs this function can calculate. #' * `"+"`: Calculate BIOCLIMs 41 onward. -#' * Any combination of the above (e.g., `c(1, 12, "+")`). +#' * Any combination of the above except `NULL` (e.g., `c(1, 12, "+")`). #' #' @param sample Logical: If `TRUE` (default), BIO4 and 15 are calculated with the sample standard deviation. If `FALSE`, then the population standard deviation is used. #' diff --git a/R/buffer.r b/R/buffer.r index 638d0868..bfef663e 100644 --- a/R/buffer.r +++ b/R/buffer.r @@ -145,7 +145,7 @@ methods::setMethod( dissolve = TRUE ) { - # .message(msg = "buffer", message = "As of GRASS 8.4, terra's buffer() function is much faster, even for very large vectors.") + # .message(msg = "buffer", message = "As of GRASS 8.3, terra's buffer() function is much faster, even for very large vectors.") .locationRestore(x) diff --git a/R/cleanGeom.r b/R/cleanGeom.r index 2ef7d075..3bee3d15 100644 --- a/R/cleanGeom.r +++ b/R/cleanGeom.r @@ -19,7 +19,7 @@ #' #' @param tolerance Numeric or `NULL` (default): Minimum distance in map units (degrees for unprojected, usually meters for projected) or minimum area (in meters-squared, regardless of projection). #' -#' @seealso [terra::topology()], [fillHoles()], *Details* section in [fast()], [simplifyGeom()], [smoothGeom()] +#' @seealso [terra::topology()], [fillHoles()], [terra::removeDupNodes()], *Details* section in [fast()], [simplifyGeom()], [smoothGeom()] #' #' @returns A `GVector`. #' diff --git a/R/clump.r b/R/clump.r index ad7009f7..55a1b247 100644 --- a/R/clump.r +++ b/R/clump.r @@ -22,7 +22,7 @@ methods::setMethod( signature = c(x = "GRaster"), function(x, minDiff = 0, minClumpSize = 1, diagonal = TRUE) { - if (minDiff < 0 | minDiff >= 1) stop(sQuote("minDiff"), " must be >= 0 and < 1.") + if (minDiff < 0 | minDiff >= 1) stop("Argument `minDiff` must be >= 0 and < 1.") .locationRestore(x) .region(x) diff --git a/R/clusterPoints.r b/R/clusterPoints.r index e9e8e0be..27c5d5d1 100644 --- a/R/clusterPoints.r +++ b/R/clusterPoints.r @@ -4,7 +4,7 @@ #' #' @param x A "points" `GVector`. #' -#' @param method Character: Method used to identify clusters. Explanations of methods are provided in the help page for the **GRASS** module [https://grass.osgeo.org/grass84/manuals/v.cluster.html](v.cluster). +#' @param method Character: Method used to identify clusters. Explanations of methods are provided in the help page for the **GRASS** module `v.cluster`, available using `grassHelp("v.cluster")`. #' * `"DBSCAN"` (default): Density-Based Spatial Clustering of Applications with Noise. #' * `"DBSCAN2"`: A modification of DBSCAN. #' * `"density"`: Cluster points by relative density. @@ -30,9 +30,7 @@ methods::setMethod( if (geomtype(x) != "points") stop("Only points GVectors can be clustered.") if (!is.null(maxDist)) { - - if (is.infinite(maxDist)) stop("Argument ", sQuote("maxDist"), " cannot be infinite.") - + if (is.infinite(maxDist)) stop("Argument `maxDist` cannot be infinite.") } method <- tolower(method) diff --git a/R/combineLevels.r b/R/combineLevels.r index 9f5900ac..81827541 100644 --- a/R/combineLevels.r +++ b/R/combineLevels.r @@ -2,7 +2,7 @@ #' #' @description This function creates a single "levels" table from the levels tables of one or more categorical `GRaster`s. #' -#' The difference between this function and [combineCats()] is that `combineCats()` creates a "combined" `GRaster` with a combined levels table, whereas this one just merges the levels tables. +#' The difference between this function and [concats()] is that `concats()` creates a "combined" `GRaster` with a combined levels table, whereas this one just merges the levels tables. #' #' @param x A `GRaster` or a `list` of `GRaster`s. #' @param ... Arguments to pass to [data.table::merge()]. @@ -11,7 +11,7 @@ #' #' @example man/examples/ex_GRaster_categorical.r #' -#' @seealso [combineCats()], `vignette("GRasters", package = "fasterRaster")` +#' @seealso [concats()], [terra::concats], `vignette("GRasters", package = "fasterRaster")` #' #' @aliases combineLevels #' @rdname combineLevels diff --git a/R/complete.cases.r b/R/complete.cases.r index 4fceb462..5a35fea1 100644 --- a/R/complete.cases.r +++ b/R/complete.cases.r @@ -28,7 +28,7 @@ methods::setMethod( function(..., levels = TRUE) { dots <- list(...) - if (length(dots) != 1L) stop("Can only assess complete cases for a single GRaster at a time (though it can be multi-layered).") + if (length(dots) != 1L) stop("This function only assess complete cases for a single GRaster at a time (though it can be multi-layered).") x <- dots[[1L]] if (levels) { @@ -63,7 +63,7 @@ methods::setMethod( function(...) { dots <- list(...) - if (length(dots) != 1L) stop("Can only assess complete cases for a single GVector at a time.") + if (length(dots) != 1L) stop("Tis function can only assess complete cases for a single GVector at a time.") x <- dots[[1L]] table <- x@table @@ -86,7 +86,7 @@ methods::setMethod( function(..., levels = TRUE) { dots <- list(...) - if (length(dots) != 1L) stop("Can only assess complete cases for a single GRaster at a time (though it can be multi-layered).") + if (length(dots) != 1L) stop("This function can only assess complete cases for a single GRaster at a time (though it can be multi-layered).") x <- dots[[1L]] if (levels) { @@ -121,7 +121,7 @@ methods::setMethod( function(...) { dots <- list(...) - if (length(dots) != 1L) stop("Can only assess missing cases for a single GVector at a time.") + if (length(dots) != 1L) stop("This function can only assess missing cases for a single GVector at a time.") x <- dots[[1L]] table <- x@table diff --git a/R/compositeRGB.r b/R/compositeRGB.r index 9c89a5c4..dc3ae1eb 100644 --- a/R/compositeRGB.r +++ b/R/compositeRGB.r @@ -24,7 +24,7 @@ methods::setMethod( signature(r = "GRaster"), function(r, g = NULL, b = NULL, levels = 256, dither = FALSE) { - msg <- paste0("Argument ", sQuote("r"), " must have 1 band (in which case arguments ", sQuote("g"), " and ", sQuote("b"), " must also be single-layer GRasters),\n or ", sQuote("r"), " must have 3 bands (and ", sQuote("g"), " and ", sQuote("b"), " must be NULL).") + msg <- paste0("Argument `r` must have 1 band (in which case arguments `g` and `b` must also be single-layer GRasters),\n or `r` must have 3 bands (and `g` and `b` must be NULL).") if (!(nlyr(r) %in% c(1L, 3L))) stop(msg) @@ -42,7 +42,7 @@ methods::setMethod( .locationRestore(r) .region(r) - if (!(length(levels %in% c(1L, 3L)))) stop("Argument ", sQuote("levels"), " must have 1 or 3 values.") + if (!(length(levels %in% c(1L, 3L)))) stop("Argument `levels` must have 1 or 3 values.") if (length(levels) == 1L) levels <- rep(levels, 3L) src <- .makeSourceName("r_composite", "raster") diff --git a/R/combineCats.r b/R/concats.r similarity index 96% rename from R/combineCats.r rename to R/concats.r index c9a7dfb1..58485a05 100644 --- a/R/combineCats.r +++ b/R/concats.r @@ -25,13 +25,13 @@ #' #' @example man/examples/ex_GRaster_categorical.r #' -#' @seealso [combineLevels()], `vignette("GRasters", package = "fasterRaster")` +#' @seealso [combineLevels()], [terra::concats()], `vignette("GRasters", package = "fasterRaster")` #' -#' @aliases combineCats -#' @rdname combineCats -#' @exportMethod combineCats +#' @aliases concats +#' @rdname concats +#' @exportMethod concats methods::setMethod( - f = "combineCats", + f = "concats", signature = c(x = "GRaster"), function(x, ..., na.rm = TRUE) { diff --git a/R/connectors.r b/R/connectors.r index 83d3a3fb..9c94c05a 100644 --- a/R/connectors.r +++ b/R/connectors.r @@ -5,9 +5,9 @@ #' @param x,y `GVector`s. #' @param minDist,maxDist Either `NULL` (default) or numeric values: Ignore features separated by less than or greater than these distances. #' -#' @return A `GVector`. +#' @returns A `GVector` with a data table that has the length of each connecting line in meters. #' -#' @seealso Module `v.distance` in **GRASS** +#' @seealso **GRASS** module `v.distance` (see `grassHelp("v.distance")`). #' #' @example man/examples/ex_connectors.r #' @@ -19,9 +19,9 @@ methods::setMethod( signature(x = "GVector", y = "GVector"), function(x, y, minDist = NULL, maxDist = NULL) { - if (!is.null(minDist) && minDist < 0) stop("Argument ", sQuote("minDist"), " must be positive or NULL.") - if (!is.null(maxDist) && maxDist < 0) stop("Argument ", sQuote("maxDist"), " must be positive or NULL.") - if ((!is.null(maxDist) & !is.null(maxDist)) && (minDist > maxDist)) stop("Argument ", sQuote("minDist"), " is greater than ", sQuote("maxDist"), ".") + if (!is.null(minDist) && minDist < 0) stop("Argument `minDist` must be positive or NULL.") + if (!is.null(maxDist) && maxDist < 0) stop("Argument `maxDist` must be positive or NULL.") + if ((!is.null(maxDist) & !is.null(maxDist)) && (minDist > maxDist)) stop("Argument `minDist` is greater than `maxDist`.") compareGeom(x, y) .locationRestore(x) @@ -30,9 +30,11 @@ methods::setMethod( if (is.null(maxDist)) maxDist <- -1 if (!.vHasDatabase(x)) { + cats <- .vCats(x) + # db <- data.frame(TEMPTEMP_minDist_meters = -1) db <- data.frame(cat = cats, TEMPTEMP_minDist_meters = -1) - .vAttachDatabase(x, table = db, replace = TRUE) + .vAttachDatabase(x, table = db, replace = TRUE, cats = cats) } @@ -54,7 +56,10 @@ methods::setMethod( # # remove column that was added to x # rgrass::execGRASS("v.db.dropcolumn", map = sources(x), columns = "TEMPTEMP_minDist_meters", flags = .quiet()) - .makeGVector(src) + table <- .vAsDataTable(x) + table <- table[ , "TEMPTEMP_minDist_meters"] + names(table) <- "length_meters" + .makeGVector(src, table = table) } # EOF ) diff --git a/R/crds.r b/R/crds.r index f3acb97c..bde8aa1f 100644 --- a/R/crds.r +++ b/R/crds.r @@ -106,7 +106,7 @@ st_coordinates <- function(x) { } else if (gtype == "points") { - data <- rgrass::execGRASS( + info <- rgrass::execGRASS( cmd = "v.to.db", map = src, flags = c(.quiet(), "p"), @@ -115,13 +115,14 @@ st_coordinates <- function(x) { intern = TRUE ) - # data <- data[-1L] - cutAt <- which(data == "Reading features...") - if (length(cutAt) > 0L) data <- data[1L:(cutAt - 1L)] + info <- info[!grepl(info, pattern = "cat|x|y|z")] + info <- info[grepl(info, pattern = "\\|")] + # cutAt <- which(info == "Reading features...") + # if (length(cutAt) > 0L) info <- info[1L:(cutAt - 1L)] - data <- strsplit(data, split="\\|") - data <- lapply(data, as.numeric) - out <- do.call(rbind, data) + info <- strsplit(info, split = "\\|") + info <- lapply(info, as.numeric) + out <- do.call(rbind, info) if (z) { out <- out[ , 2L:4L, drop = FALSE] diff --git a/R/datatype.r b/R/datatype.r index 80e17db0..447194f9 100644 --- a/R/datatype.r +++ b/R/datatype.r @@ -71,7 +71,7 @@ methods::setMethod( } else if (out[i] == "DCELL") { out[i] <- if (type == "GDAL") { "Float64" } else { "FLT8S" } } else { - warning("Values are too small/large to represent. Assigning ", sQuote("double"), " type.") + warning("Values are too small/large to represent. Assigning `double` type.") out[i] <- if (type == "GDAL") { "Float64" } else { "FLT8S" } } @@ -141,7 +141,7 @@ methods::setMethod( # # # } else if (min[i] > -1.79e+308 & max[i] < 1.79e+308) { # # # out[i] <- if (type == "GDAL") { "Float64" } else if (type == "terra") { "FLT8S" } else if (type == "GRASS") { "DCELL" } else if (type == "fasterRaster") { "double" } # # # } else { -# # # warning("Values are too small/large to represent. Assigning ", sQuote("double"), " type.") +# # # warning("Values are too small/large to represent. Assigning `double` type.") # # # out[i] <- if (type == "GDAL") { "Float64" } else if (type == "terra") { "FLT8S" } else if (type == "GRASS") { "DCELL"} else if (type == "fasterRaster") { "double" } # # # } # # # } diff --git a/R/denoise_noise.r b/R/denoise_noise.r index c9ee1b48..a4fb704d 100644 --- a/R/denoise_noise.r +++ b/R/denoise_noise.r @@ -28,11 +28,11 @@ methods::setMethod( # if (percent %% 1 != 0) { if (!omnibus::is.wholeNumber(percent)) { - warning("Argument ", sQuote("percent"), " must be an integer. Value will be rounded.") + warning("Argument `percent` must be an integer. Value will be rounded.") percent <- round(percent) } - if (percent < 50 | percent > 99) stop("Argument ", sQuote("percent"), " must be an integer in the range [50, 99].") + if (percent < 50 | percent > 99) stop("Argument `percent` must be an integer in the range [50, 99].") .locationRestore(x) .region(x) diff --git a/R/distance.r b/R/distance.r index cd81673d..a4411be3 100644 --- a/R/distance.r +++ b/R/distance.r @@ -66,14 +66,14 @@ methods::setMethod( maxDist = NULL ) { - if (!is.null(minDist) && minDist < 0) stop("Argument ", sQuote("minDist"), " must be positive or NULL.") - if (!is.null(maxDist) && maxDist < 0) stop("Argument ", sQuote("maxDist"), " must be positive or NULL.") - if ((!is.null(maxDist) & !is.null(maxDist)) && (minDist > maxDist)) stop("Argument ", sQuote("minDist"), " is greater than ", sQuote("maxDist"), ".") + if (!is.null(minDist) && minDist < 0) stop("Argument `minDist` must be positive or NULL.") + if (!is.null(maxDist) && maxDist < 0) stop("Argument `maxDist` must be positive or NULL.") + if ((!is.null(maxDist) & !is.null(maxDist)) && (minDist > maxDist)) stop("Argument `minDist` is greater than `maxDist`.") method <- tolower(method) methods <- c("euclidean", "squared", "maximum", "manhattan", "geodesic") method <- omnibus::pmatchSafe(method, methods) - if (is.lonlat(x) & method != "geodesic") warning("Argument ", sQuote("method"), " should be ", sQuote("geodesic"), " for rasters with longitude/latitude coordinate reference systems.") + if (is.lonlat(x) & method != "geodesic") warning("Argument `method` should be `geodesic` for rasters with longitude/latitude coordinate reference systems.") .locationRestore(x) .region(x) @@ -134,13 +134,13 @@ methods::setMethod( maxDist = NULL ) { - if (!is.null(minDist) && minDist < 0) stop("Argument ", sQuote("minDist"), " must be positive or NULL.") - if (!is.null(maxDist) && maxDist < 0) stop("Argument ", sQuote("maxDist"), " must be positive or NULL.") - if ((!is.null(maxDist) & !is.null(maxDist)) && (minDist > maxDist)) stop("Argument ", sQuote("minDist"), " is greater than ", sQuote("maxDist"), ".") + if (!is.null(minDist) && minDist < 0) stop("Argument `minDist` must be positive or NULL.") + if (!is.null(maxDist) && maxDist < 0) stop("Argument `maxDist` must be positive or NULL.") + if ((!is.null(maxDist) & !is.null(maxDist)) && (minDist > maxDist)) stop("Argument `minDist` is greater than `maxDist`.") methods <- c("euclidean", "squared", "maximum", "manhattan", "geodesic") method <- omnibus::pmatchSafe(method, methods) - if (is.lonlat(x) & method != "geodesic") warning("Argument ", sQuote("method"), " should be ", sQuote("geodesic"), " for rasters with longitude/latitude coordinate reference systems.") + if (is.lonlat(x) & method != "geodesic") warning("Argument `method` should be `geodesic` for rasters with longitude/latitude coordinate reference systems.") compareGeom(x, y) .locationRestore(x) @@ -195,8 +195,8 @@ methods::setMethod( maxDist = NULL ) { - if (!is.null(minDist) && minDist < 0) stop("Argument ", sQuote("minDist"), " must be positive or NULL.") - if (!is.null(maxDist) && maxDist < 0) stop("Argument ", sQuote("maxDist"), " must be positive or NULL.") + if (!is.null(minDist) && minDist < 0) stop("Argument `minDist` must be positive or NULL.") + if (!is.null(maxDist) && maxDist < 0) stop("Argument `maxDist` must be positive or NULL.") if ((!is.null(maxDist) & !is.null(maxDist)) && (minDist > maxDist)) stop("Argument `minDist` is greater than `maxDist`.") compareGeom(x, y) @@ -217,6 +217,7 @@ methods::setMethod( ) info <- info[-1L] + info <- info[grepl(info, pattern = "\\|")] info <- strsplit(info, split="\\|") info <- lapply(info, as.numeric) info <- do.call(rbind, info) @@ -273,6 +274,7 @@ methods::setMethod( ) out <- out[-1L] + out <- out[grepl(out, pattern = "\\|")] out <- strsplit(out, split = "\\|") out <- do.call(rbind, out) n <- nrow(out) diff --git a/R/exists.r b/R/exists.r index e9ad5283..76a04e6e 100644 --- a/R/exists.r +++ b/R/exists.r @@ -18,7 +18,7 @@ methods::setMethod( .locationRestore(x) src <- sources(x) - src %in% .ls() + src %in% .ls(type = "raster") } # EOF ) @@ -33,7 +33,7 @@ methods::setMethod( .locationRestore(x) src <- sources(x) - src %in% .ls() + src %in% .ls(type = "vector") } # EOF ) diff --git a/R/extend.r b/R/extend.r index 481853fd..5b53c945 100644 --- a/R/extend.r +++ b/R/extend.r @@ -90,14 +90,14 @@ methods::setMethod( if (inherits(y, "numeric")) { if (!(length(y) %in% c(1L, 2L, 4L))) { - stop("Argument ", sQuote("y"), " is invalid.") + stop("Argument `y` is invalid.") } else if (length(y) == 1L) { y <- rep(y, 4L) } else if (length(y) == 2L) { y <- rep(y, each = 2L) } - if (any(!omnibus::is.wholeNumber(y))) stop("Values of ", sQuote("y"), " must be numeric integers.") + if (any(!omnibus::is.wholeNumber(y))) stop("Values of `y` must be numeric integers.") if (any(y < 0L)) y[y < 0L] <- 0L } else { @@ -108,7 +108,7 @@ methods::setMethod( } else if (inherits(y, "GSpatial")) { extent <- ext(y, vector = TRUE) } else { - stop("Argument ", sQuote("y"), " is invalid.") + stop("Argument `y` is invalid.") } # by how many rows and columns do we grow? diff --git a/R/extract.r b/R/extract.r index 575d4a8c..8d048a2c 100644 --- a/R/extract.r +++ b/R/extract.r @@ -36,7 +36,9 @@ #' #' @param cats Logical (extracting from a raster): If `TRUE` (default) and `x` is a categorical `GRaster`, then return the category labels instead of the values. #' -#' @param verbose Logical: If `TRUE`, display progress (will only function when extracting from points on a `GRaster` when the number of `GRaster`s is large). +#' @param verbose Logical: If `TRUE`, display progress (will only function when extracting from points on a `GRaster` when the number of `GRaster`s is large, or when extracting using a "points" `GVector` with lots of points). +#' +#' @param ... Arguments to pass to [project()]. This is used only if extracting from a `GRaster` at locations specified by a `GVector`, and they have a different coordinate reference system. In this case, users should specify the `wrap` argument to [project()]. #' #' @returns A `data.frame` or `data.table`. #' @@ -58,10 +60,27 @@ methods::setMethod( overlap = TRUE, xy = FALSE, cats = TRUE, - verbose = FALSE + verbose = FALSE, + ... ) { .locationRestore(x) + + sameCRS <- compareGeom(x, y, stopOnError = FALSE, messages = FALSE) + if (!sameCRS) { + + warning("The GVector has a different coordinate reference system than the GRaster.\n The GVector was projected to the CRS of the GRaster. If the GVector spans\n the international date line, you may need to specify `wrap = TRUE` when\n using this function.", immediate. = TRUE) + + dots <- list(...) + if (any(names(dots) == "wrap")) { + wrap <- dots$wrap + } else { + wrap = FALSE + } + y <- project(y, x, wrap = wrap) + + } + compareGeom(x, y) nLayers <- nlyr(x) @@ -126,8 +145,8 @@ methods::setMethod( if (any(fun == "quantile")) { - if (length(prob) > 1L) stop("Argument ", sQuote("prob"), " can only have one value.") - if (prob > 1 | prob < 0) stop("Argument ", sQuote("prob"), " must be in the range [0, 1].") + if (length(prob) > 1L) stop("Argument `prob` can only have one value.") + if (prob > 1 | prob < 0) stop("Argument `prob` must be in the range [0, 1].") prob <- round(100 * prob) } @@ -355,8 +374,8 @@ methods::setMethod( cats = TRUE ) { - if (ncol(y) < 2L) stop("Argument ", sQuote("y"), " must have at least two columns. The first must represent longitude and the second latitude.") - if (ncol(y) > 2L) warning("Argument ", sQuote("y"), " has more than two columns. The first will be assumed to represent longitude and the second latitude.") + if (ncol(y) < 2L) stop("Argument `y` must have at least two columns. The first must represent longitude and the second latitude.") + if (ncol(y) > 2L) warning("Argument `y` has more than two columns. The first will be assumed to represent longitude and the second latitude.") y <- terra::vect(y, geom = colnames(y)[1L:2L], crs = crs(x), keepgeom = FALSE) y <- fast(y) @@ -416,7 +435,7 @@ methods::setMethod( cats = TRUE ) { - if (length(y) != 2L) stop("Argument ", sQuote("y"), " must have two values, longitude and latitude.") + if (length(y) != 2L) stop("Argument `y` must have two values, longitude and latitude.") y <- cbind(y) colnames(y) <- c("x", "y") extract(x = x, y = y, xy = xy, cats = cats) @@ -430,14 +449,14 @@ methods::setMethod( methods::setMethod( f = "extract", signature = c(x = "GVector", y = "GVector"), - function(x, y, xy = FALSE) { + function(x, y, xy = FALSE, verbose = TRUE) { - if (geomtype(y) != "points") stop("Argument", sQuote("y"), " must be a points vector.") + if (geomtype(y) != "points") stop("Argument`y` must be a points vector.") if (is.3d(y)) warning("Coordinates in the z-dimension will be ignored.") .locationRestore(x) coords <- crds(y, z = FALSE) - .extractFromVect(x, coords, xy) + .extractFromVect(x, coords, xy, verbose = verbose) } # EOF @@ -449,7 +468,7 @@ methods::setMethod( methods::setMethod( f = "extract", signature = c(x = "GVector", y = "data.frame"), - function(x, y, xy = FALSE) .extractFromVect(x, y[ , 1L:2L], xy) + function(x, y, xy = FALSE, verbose = TRUE) .extractFromVect(x, y[ , 1L:2L], xy, verbose = verbose) ) #' @aliases extract @@ -458,10 +477,10 @@ methods::setMethod( methods::setMethod( f = "extract", signature = c(x = "GVector", y = "data.table"), - function(x, y, xy = FALSE) { + function(x, y, xy = FALSE, verbose = TRUE) { y <- as.data.frame(y) - .extractFromVect(x, y[ , 1L:2L], xy) + .extractFromVect(x, y[ , 1L:2L], xy, verbose = verbose) } # EOF ) @@ -472,7 +491,7 @@ methods::setMethod( methods::setMethod( f = "extract", signature = c(x = "GVector", y = "matrix"), - function(x, y, xy = FALSE) .extractFromVect(x, y[ , 1L:2L], xy) + function(x, y, xy = FALSE, verbose = TRUE) .extractFromVect(x, y[ , 1L:2L], xy, verbose = verbose) ) #' @aliases extract @@ -484,7 +503,7 @@ methods::setMethod( function(x, y, xy = FALSE) { y <- cbind(y) - .extractFromVect(x, y, xy) + .extractFromVect(x, y, xy, verbose = FALSE) } # EOF ) @@ -497,9 +516,9 @@ methods::setMethod( # methods::setMethod( # f = "extract", # signature = c(x = "GVector", y = "character"), -# function(x, y, xy = FALSE) { +# function(x, y, xy = FALSE, verbose = TRUE) { -# y <- .crdsVect(y, z = FALSE, gm = "points") +# y <- .crdsVect(y, z = FALSE, gm = "points", verbose = verbose) # .extractFromVect(x, y, xy) # } # EOF @@ -510,9 +529,10 @@ methods::setMethod( #' @param xy T/F: Return coordinates #' @param nperSet Number of points to extract... too large throws an error. 1000 seems to break, so going with 900. #' @param data.table return as `data.table` +#' @param verbose Logical. #' #' @noRd -.extractFromVect <- function(x, y, xy, nPerSet = 900L, data.table = TRUE) { +.extractFromVect <- function(x, y, xy, nPerSet = 900L, data.table = TRUE, verbose = FALSE) { .locationRestore(x) @@ -523,17 +543,24 @@ methods::setMethod( if (n > nPerSet) { + sets <- ceiling(n / nPerSet) + if (verbose | faster("verbose")) { + pb <- utils::txtProgressBar(min = 0, max = sets, initial = 0, style = 3, width = 30) + } + out <- data.table::data.table() for (set in seq_len(sets)) { - - omnibus::say(set) + + if (verbose | faster("verbose")) utils::setTxtProgressBar(pb, set) yy <- y[(1L + (set - 1L) * nPerSet):min(set * nPerSet, n)] - thisOut <- .extractFromVect(x, y = yy, xy = xy, data.table = TRUE) + thisOut <- .extractFromVect(x, y = yy, xy = xy, data.table = TRUE, verbose = FALSE) out <- rbind(out, thisOut) } + + if (verbose | faster("verbose")) close(pb) } else { @@ -585,9 +612,7 @@ methods::setMethod( if (nrow(x) == 0L) { id.x <- NULL - out <- data.table::data.table(id.y = 1L:n, id.x = NA_integer_) - if (lenNonnas > 0L) out[nonnasIndex, id.x := nons] # vector has data table diff --git a/R/fast.r b/R/fast.r index d143152d..57f8b9cd 100644 --- a/R/fast.r +++ b/R/fast.r @@ -2,7 +2,7 @@ #' #' @description `fast()` creates a `GRaster` or `GVector` from 1) a file; 2) from a `SpatRaster`, `SpatVector`, or `sf` vector; or 3) from a numeric vector, `matrix`, `data.frame`, or `data.table`. Behind the scenes, this function will also create a connection to **GRASS** if none has yet been made yet. #' -#' **GRASS** supports loading from disk a variety of raster formats (see the **GRASS** manual page for [`r.in.gdal`](https://grass.osgeo.org/grass84/manuals/r.in.gdal.html)) and vector formats ([`v.in.ogr`](https://grass.osgeo.org/grass84/manuals/v.in.ogr.html)), though not all of them will work with this function. +#' **GRASS** supports loading from disk a variety of raster formats (see the **GRASS** manual page for `r.in.gdal` (see `grassHelp("r.in.gdal")`) and vector formats `v.in.ogr` (see grassHelp("v.in.ogr")`), though not all of them will work with this function. #' #' Note that `GVectors` may fail to be created if they contain issues that do not coincide with the topological data model used by **GRASS**. The most common of these is overlapping polygons. See *Details* on how to fix these kinds of issues. #' @@ -69,7 +69,7 @@ #' * **Correction outside of *fasterRaster***: Before you convert the vector into **fasterRaster**'s `GVector` format, you can also try using the [terra::makeValid()] or [sf::st_make_valid()] tools to fix issues, then use `fast()`. #' * **Post-conversion to a `GVector`**: If you do get a vector loaded into `GVector` format, you can also use a set of **fasterRaster** vector-manipulation [tools][breakPolys] or [fillHoles()] to fix issues. #' -#' @seealso [rgrass::read_RAST()] and [rgrass::read_VECT()], [vector cleaning][breakPolys], [fillHoles()], plus modules [`v.in.ogr`](https://grass.osgeo.org/grass84/manuals/v.in.ogr.html) and [`r.import`](https://grass.osgeo.org/grass84/manuals/r.import.html) in **GRASS**. +#' @seealso [rgrass::read_RAST()] and [rgrass::read_VECT()], [vector cleaning][breakPolys], [fillHoles()], plus **GRASS** modules `v.in.ogr` (see `grassHelp("v.in.ogr")`) and `r.import` (see `grassHelp("r.import")`) #' #' @returns A `GRaster` or `GVector`. #' @@ -241,13 +241,13 @@ methods::setMethod( } else if (rastOrVect == "vector") { - # x is a filename and xVect is missing: we have not come through methods for SpatVectors or sf objects + # x is a filename and xVect is missing: we have NOT come through methods for SpatVectors or sf objects if (!any(dotNames == "xVect")) { x <- terra::vect(x) out <- fast(x, extent = extent, correct = correct, snap = snap, area = area, steps = steps, resolve = resolve, dropTable = dropTable, verbose = verbose, ...) - # x is a filename and xVect is present: we have come through a method for SpatVectors or sf objects + # x is a filename and xVect is present: we HAVE come here through a method for SpatVectors or sf objects } else { if (!is.na(resolve)) resolve <- omnibus::pmatchSafe(resolve, c("aggregate", "disaggregate"), n = 1L) @@ -313,8 +313,7 @@ methods::setMethod( #} src <- .makeSourceName("fast_v_in_ogr", "vector") - if (is.null(snap) & is.null(area)) { - + if (is.null(snap) & (is.null(area) || area == 0)) { # slower if we need to record messages suppressMessages( @@ -332,7 +331,11 @@ methods::setMethod( ) ) - valid <- !any(grepl(run, pattern = "WARNING: The output contains topological errors")) + valid <- !any(c( + grepl(run, pattern = "WARNING: The output contains topological errors"), + grepl(run, pattern = "Invalid argument") + )) + if (valid) { # more thorough test... slower info <- .vectInfo(src) @@ -654,7 +657,7 @@ methods::setMethod( methods::setMethod( "fast", signature(x = "sf"), - function(x, extent = NULL, correct = TRUE, snap = NULL, area = NULL, steps = 10, dropTable = FALSE, resolve = NA, verbose = TRUE) .fastVector(x, correct = correct, snap = snap, area = area, steps = steps, extent = extent, dropTable = dropTable, resolve = resolve, verbose = verbose) + function(x, extent = NULL, correct = TRUE, snap = NULL, area = NULL, steps = 10, resolve = NA, dropTable = FALSE, verbose = TRUE) .fastVector(x, correct = correct, snap = snap, area = area, steps = steps, extent = extent, dropTable = dropTable, resolve = resolve, verbose = verbose) ) #' @rdname fast @@ -877,7 +880,7 @@ methods::setMethod( # NB we ***need** a table with the GVector--otherwise, subset_single_bracket does not work as expected if (is.null(table)) xVect$DUMMYDUMMY_ <- 1L:nrow(xVect) - vectFile <- tempfile(fileext = ".gpkg") + vectFile <- paste0(faster("workDir"), "/", omnibus::rstring(1L), ".gpkg") terra::writeVector(xVect, filename = vectFile, filetype = "GPKG", overwrite = TRUE) } else { diff --git a/R/fasterRaster.r b/R/fasterRaster.r index 59b593d1..8254f616 100644 --- a/R/fasterRaster.r +++ b/R/fasterRaster.r @@ -3,9 +3,9 @@ #' @description **fasterRaster**: Processing of large-in-memory/-on disk rasters and spatial vectors in using **GRASS GIS**. Most functions in the **terra** and **sf** packages are recreated. Processing of medium-sized and smaller spatial objects will nearly always be faster using **terra** or **sf**. To use most of the functions you must have the stand-alone version of **GRASS GIS** version 8.3 or higher (not the **OSGeoW4** installer version). Note that due to differences in how **GRASS**, **terra**, and **sf** were implemented, results will not always be strictly comparable between functions for the same operation. #' #' ## Most useful tutorials and functions: -#' * The quick-start guide to getting started with **fasterRaster** , accessible using `vignette("fasterRaster", package = "fasterRaster")` -#' * The vignette on types of `GRaster`s, accessible using `vignette("GRasters", package = "fasterRaster")` -#' * The vignette on how to speed up **fasterRaster**, accessible using `vignette("faster_fasterRaster", package = "fasterRaster")` +#' * The quick-start guide to getting started with **fasterRaster**, accessible using `vignette("fasterRaster", package = "fasterRaster")` +#' * Types of `GRaster`s, accessible using `vignette("GRasters", package = "fasterRaster")` +#' * How to speed up **fasterRaster**, accessible using `vignette("faster_fasterRaster", package = "fasterRaster")` #' * [faster()]: Set the directory where **GRASS** is installed on your system, and set or get other package-wide options. This function must be run once before using most **fasterRaster** functions. #' * [fast()]: Convert a `SpatRaster`, `SpatVector`, or `sf` vector to **fasterRaster**'s raster format (`GRaster`s) or vector format (`GVector`s), or load one from a file #' * [rast()], [vect()], and [st_as_sf()]: Convert `GRaster`s and `GVector`s to `SpatRaster`s, `SpatVector`s, or `sf` vectors @@ -33,7 +33,7 @@ #' * [nonnacell()]: Number of non-`NA` cells #' * [nrow()]: Number of rows #' * [nlevels()]: Number of categories -#' * [res()], [xres()], [yres()], and [zres()]: Spatial resolution +#' * [res()], [res3d()], [xres()], [yres()], and [zres()]: Spatial resolution #' * [sources()]: Name of the `GRaster` in **GRASS** #' * [topology()]: Dimensionality (2D or 3D) #' * [zext()]: Vertical extent @@ -44,22 +44,27 @@ #' * [Logical comparisons][Compare-methods]: `<`, `<=`, `==`, `!=`, `>=`, and `>`, plus \code{\link[fasterRaster]{%in%}} and \code{\link[fasterRaster]{%notin%}} (for categorical rasters only) #' * [Logical operators][Logic-methods]: `|`and `&` #' -#' Single-layer mathematical functions (applied to each layer of a `GRaster`): -#' - Working with `NA`s: [is.na()], [not.na()], and [maskNA()] -#' - Trigonometry: [sin()], [cos()], [tan()], [asin()], [acos()], [atan()], [atan2()] -#' - Logarithms and powers: [exp()], [log()], [ln()], [log1p()], [log2()], [log10()], [sqrt()] -#' - Rounding: [round()], [floor()], [ceiling()], [trunc()] -#' - Signs: [abs()] +#' Mathematical functions that are applied to each layer of a `GRaster`: +#' * Working with `NA`s: [is.na()], [not.na()], and [maskNA()] +#' * Trigonometry: [sin()], [cos()], [tan()], [asin()], [acos()], [atan()], [atan2()] +#' * Logarithms and powers: [exp()], [log()], [ln()], [log1p()], [log2()], [log10()], [sqrt()] +#' * Rounding: [round()], [floor()], [ceiling()], [trunc()] +#' * Signs: [abs()] #' -#' Multi-layer functions (applied across layers of a "stack" of `GRaster`s): -#' - Numeration: [sum()], [count()] -#' - Central tendency: [mean()], [mmode()], [median()] -#' - Dispersion: [stdev()], [var()], [varpop()], [nunique()], [range()], [quantile()], [skewness()], [kurtosis()] -#' - Extremes: [min()], [max()], [which.min()], [which.max()] +#' Mathematical functions that are applied across layers of multi-layered `GRaster`s: +#' * Numeration: [sum()], [count()] +#' * Central tendency: [mean()], [mmode()], [median()] +#' * Dispersion: [stdev()], [var()], [varpop()], [nunique()], [range()], [quantile()], [skewness()], [kurtosis()] +#' * Extremes: [min()], [max()], [which.min()], [which.max()] +#' * `NA`s: [allNA()], [anyNA()] #' -#' The operators [$] and \code{\link[fasterRaster]{[[}} can be used to subset or remove specific layers of a `GRaster`. -#' The \code{\link[fasterRaster]{[<-}} operator can be used to replace values of cells of a `GRaster`. -#' The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster]{[[<-}}, and \code{\link[fasterRaster]{add<-}}, can be used to replace specific layers of a `GRaster`. +#' Subsetting, assigning, and replacing `GRaster` layers +#' * [$], \code{\link[fasterRaster]{[[}}, or [subset()]: Subset or remove specific layers of a `GRaster` +#' * \code{\link[fasterRaster]{[<-}}: Replace values of cells of a `GRaster` +#' * \code{\link[fasterRaster]{[[<-}}: Replace specific layers of a `GRaster` +#' * \code{\link[fasterRaster]{add<-}}: Replace specific layers of a `GRaster` +#' +#' Operations on `GRaster`s #' * [as.int()], [as.float()], [as.doub()]: Change data type (integer/float/double) #' * [as.lines()]: Convert a `GRaster` to a "lines" vector #' * [as.points()]: Convert a `GRaster` to a "points" vector @@ -72,8 +77,8 @@ #' * [cellSize()]: Cell area #' * [classify()]: Partition cell values into strata #' * [clump()]: Group adjacent cells with similar values -#' * [combineCats()]: Combine values from two or more categorical and/or integer rasters #' * [combineLevels()]: Combine the "levels" tables of two or more categorical `GRaster`s +#' * [concats()]: Combine values from two or more categorical and/or integer rasters by concatenating them #' * [crop()]: Remove parts of a `GRaster` #' * [denoise()]: Remove "noise" from a `GRaster` using a principal components analysis (PCA) #' * [distance()]: Distance to non-`NA` cells, or vice versa @@ -87,25 +92,26 @@ #' * [interpIDW()]: Interpolate values at points to a `GRaster` #' * [kernel()]: Kernel density estimator of points #' * [layerCor()]: Correlation or covariance between two or more `GRaster` layers -#' * [longlat()]: Create longitude/latitude rasters #' * [mask()]: Remove values in a `GRaster` based on values in another `GRaster` or vector #' * [maskNA()]: Mask all non-NA cells or all NA cells #' * [match()], \code{\link[fasterRaster]{%in%}}, and \code{\link[fasterRaster]{%notin%}}: Find which cells of a `GRaster` match or do not match certain values #' * [merge()]: Combine two or more rasters with different extents and fill in `NA`s -#' \code{\link[fasterRaster]{names<-}}: Assign names to a `GRaster` +#' * \code{\link[fasterRaster]{names<-}}: Assign names to a `GRaster` #' * [noise()]: Remove coarse-scale trends from a `GRaster`, leaving just fine-scale "noise" #' * [pairs()]: Plot correlations between `GRaster` layers -#' * [pca()]: Apply a principal components analysis (PCA) to a `GRaster` -#' * [pcs()]: Retrieve a principal components model from a PCA `GRaster` generated using `pca()` +#' * [pcs()]: Retrieve a principal components model from a PCA `GRaster` generated using `princomp()` #' * [plot()]: Display a `GRaster` -#' * [plotRGB()]: Display a multispectral `GRaster` using red, blue, green, and alpha channels #' * [project()]: Change coordinate reference system and cell size #' * [predict()]: Make predictions to a `GRaster` from a linear model or generalized linear model +#' * [princomp()]: Apply a principal components analysis (PCA) to a `GRaster` +#' * [regress()]: Regression intercept, slope, r2, and t-value across each set of cells #' * [resample()]: Change cell size #' * [reorient()]: Convert degrees between 'north-orientation' and 'east orientation' +#' * [sampleRast()]: Randomly sample cells from a `GRaster` #' * [scale()], [scalepop()], and [unscale()]: Subtract means and divide by standard deviations, or inverse of that #' * [selectRange()]: Select values from rasters in a stack based on values in another `GRaster` #' * [spatSample()]: Randomly points from a `GRaster` +#' * [stretch()]: Rescale values in a GRaster #' * [subst()]: Re-assign cell values #' * [thinLines()]: Reduce linear features on a `GRaster` so linear features are 1 cell wide #' * [tiles()]: Divide a `GRaster` into spatially exclusive subsets (though with possible overlap) @@ -113,14 +119,16 @@ #' * [zonal()]: Statistics (mean, sum, etc.) on areas of a `GRaster` defined by sets of cells with the same values in another `GRaster`, or by geometries in a `GVector` #' * [zonalGeog()]: Geographic statistics (area, perimeter, fractal dimension, etc.) for sets of cells with the same values #' -#' ## Functions for creating `GRaster`s *de novo* +#' ## Creating `GRaster`s *de novo* #' * [fractalRast()]: Create a fractal `GRaster` +#' * [init()]: GRaster with values equal to row, column, coordinate, regular, or "chess" +#' * [longlat()]: Create longitude/latitude rasters #' * [rnormRast()]: A random `GRaster` with values drawn from a normal distribution #' * [rSpatialDepRast()]: Create a random `GRaster` with or without spatial dependence #' * [runifRast()]: A random `GRaster` with values drawn from a uniform distribution #' * [sineRast()]: Sine wave rasters #' -#' ## Functions for analysis of terrain and flow of water across landscapes +#' ## Analysis of terrain and hydrology #' * [as.contour()]: Contour lines from a `GRaster` #' * [flow()]: Identify watershed basins and direction and accumulation of flow #' * [flowPath()]: Path of water flow across a landscape @@ -133,8 +141,8 @@ #' * [terrain()]: Slope, aspect, curvature, and partial slopes #' * [wetness()]: Topographic wetness index #' -#' ## Functions operating on categorical (factor) rasters -#' \code{\link[fasterRaster]{%in%}}, and \code{\link[fasterRaster]{%notin%}}: Mask cells that match or do not match a given category +#' ## Operations on categorical (factor) `GRaster`s +#' * \code{\link[fasterRaster]{%in%}}, and \code{\link[fasterRaster]{%notin%}}: Mask cells that match or do not match a given category #' * [activeCat()] and [activeCats()]: Column(s) that defines category labels #' \code{\link[fasterRaster]{activeCat<-}}: Set column that defines category labels #' * [addCats()]: Add new columns to a "levels" table @@ -142,28 +150,29 @@ #' * [categories()]: Set "levels" table for specific layers of a categorical raster #' * [catNames()]: Column names of each "levels" table #' * [cats()]: "Levels" table of a categorical raster -#' * [combineCats()]: Combine categories from two or more categorical rasters #' * [combineLevels()]: Combine the "levels" tables of two or more categorical `GRaster`s #' * [complete.cases()]: Find rows of a categorical `GRaster`'s "levels" table that have no `NA`s in them +#' * [concats()]: Combine categories from two or more categorical rasters by concatenating them #' * [droplevels()]: Remove one or more levels #' * [freq()]: Frequency of each category across cells of a raster #' * [is.factor()]: Is a raster categorical? -#' * [levels()]: "Levels" table of a categorical raster -#' \code{\link[fasterRaster]{levels<-}}: Set "levels" table of a categorical raster +#' * [levels()]: "Levels" table of a categorical raster +#' * \code{\link[fasterRaster]{levels<-}}: Set "levels" table of a categorical raster #' * [match()], \code{\link[fasterRaster]{%in%}}, and \code{\link[fasterRaster]{%notin%}}: Find which cells of a `GRaster` match or do not match certain category labels #' * [minmax()]: "Lowest" and "highest" category values of categorical rasters (when argument `levels = TRUE`) #' * [missing.cases()]: Find rows of a categorical `GRaster`'s "levels" table that have at least one `NA` in them #' * [missingCats()]: Values that have no category assigned to them #' * [nlevels()]: Number of levels +#' * [segregate()]: Create one GRaster layer per unique value in a GRaster #' * [subst()]: Re-assign category levels #' * [zonalGeog()]: Geographic statistics (area, perimeter, fractal dimension, etc.) for sets of cells with the same values #' -#' ## Functions for analysis of remote sensing rasters +#' ## Analysis of remote sensing rasters #' * [compositeRGB()]: Combine red, green, and blue color bands to make a composite `GRaster` #' * [plotRGB()]: Display a multispectral `GRaster` using red, blue, green, and alpha channels #' * [vegIndex()]: Vegetation indices from surface reflectance #' -#' ### Functions that operate on **terra** `SpatRaster`s +#' ## Functions that operate on **terra** `SpatRaster`s #' * [bioclims()]: BIOCLIM rasters (classic set and extended set) #' * [fragmentation()]: Landscape fragmentation class from Riitters et al. (2020) #' @@ -186,11 +195,14 @@ #' * [topology()]: Dimensionality (2D or 3D) #' * [zext()]: Vertical extent #' -#' ## Functions that operate on or create `GVector`s -#' The \code{\link[fasterRaster]{[}} operator can be used to subset geometries of a `GVector`. -#' The [$] and \code{\link[fasterRaster]{[[}} operators can be used to get columns of a `GVector`'s data table. -#' The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific columns of a `GVector`'s data table or to add columns. -#' \code{\link[fasterRaster]{addTable<-}}: Add a data table to a `GVector` +#' ## Subsetting and assigning geometries or rows and columns of `GVector`s +#' * [$] or \code{\link[fasterRaster]{[[}}: Subset columns of a `GVector`'s data table +#' * \code{\link[fasterRaster]{[}} or [subset()]: Subset geometries of a `GVector` +#' * \code{\link[fasterRaster]{$<-}}: Replace specific columns of a `GVector`'s data table or add columns +#' * \code{\link[fasterRaster]{addTable<-}}: Add a data table to a `GVector` +#' * [dropTable()]: Remove a `GVector`s data table +#' +#' ## Operations on `GVector`s #' * [aggregate()]: Combine `GVector` geometries #' * [as.data.frame()]: Convert a `GVector`'s attribute table to a `data.frame` #' * [as.data.table()]: Convert a `GVector`'s attribute table to a `data.table` @@ -206,7 +218,6 @@ #' * [delaunay()]: Delaunay triangulation #' * [disagg()]: Separate multipart geometries into singlepart geometries #' * [distance()]: Distance between geometries in two `GVector`, or from a `GVector` to cells of a `GRaster` -#' * [dropTable()]: Remove the data table from a `GVector` #' * [erase()] or `-`: Remove part of a `GVector` that overlaps with another #' * [expanse()]: Area of polygons or length of lines #' * [extract()]: Extract values from a `GVector` at specific points @@ -215,8 +226,8 @@ #' * [hexagons()]: Create a hexagonal grid #' * [interpIDW()]: Interpolate values at points to a `GRaster` using inverse-distance weighting #' * [interpSplines()]: Interpolate values at points to a `GRaster` using splines -#' * [intersect()] or `*`: Intersection of two `GVectors`. -#' * [kernel()]: Kernel density estimator of points. +#' * [intersect()] or `*`: Intersection of two `GVectors` +#' * [kernel()]: Kernel density estimator of points #' * [missing.cases()]: Find rows of a `GVector`'s data table that have at least `NA` in them #' \code{\link[fasterRaster]{names<-}}: Assign names to columns of a `GVector`s data table #' * [project()]: Change coordinate reference system @@ -229,10 +240,14 @@ #' * [tail()]: Last rows of a `GVector`'s data table #' * [thinPoints()]: Reduce number of points in same raster cell #' * [union()] or `+`: Combine two `GVector`s -#' * [xor()] or `/``: Select parts of polygons not shared by two `GVector`s +#' * [voronoi()]: Voronoi tessellation +#' * [xor()] or `/`: Select parts of polygons not shared by two `GVector`s +#' +#' ## Creating `GVector`s *de novo* +#' * [rvoronoi()]: Random Voronoi tesselation #' -#' ## Functions for fixing issues with `GVector`s -#' (See also tools that can be used during `GVector` creation/loading in [fast()].) +#' ## Fixing issues with `GVector`s +#' (See also *Details* [fast()].) #' * [breakPolys()]: Break topologically clean areas #' * [fillHoles()]: Fill "holes" of a `GVector` #' * [fixBridges()]: Change "bridges" to "islands" @@ -255,8 +270,8 @@ #' * [as.float()]: Convert a `GRaster` to a floating-point raster (**GRASS** data type `FCELL`) #' * [as.int()]: Convert a `GRaster` to an integer raster (**GRASS** data type `CELL`) #' * [as.points()], [as.lines()], and [as.polygons()]: Convert a `GRaster` to a `GVector` +#' * [categories()] and \code{\link[fasterRaster]{levels<-}}: Convert an integer raster to a categorical ("factor") raster. #' * [fast()]: Convert a `SpatRaster` to a `GRaster`; a `SpatVector`, `sf` vector, numeric vector, `matrix`, `data.frame`, or `data.table` to a `GVector`; or load a vector or raster from a file -#' * [categories()] and [levels<-]: Convert an integer raster to a categorical ("factor") raster. #' * [rast()]: Convert a `GRaster` to a `SpatRaster` #' * [rasterize()]: Convert a `GVector` to a `GRaster` #' * [st_as_sf()]: Convert a `GVector` to a `sf` vector @@ -265,14 +280,19 @@ #' ## General purpose functions #' * [compareGeom()]: Determine if geographic metadata is same between `GRaster`s and/or `GVector`s #' * [dropRows()]: Remove rows from a `data.frame` or `data.table` +#' * [grassGUI()]: Start the **GRASS** GUI (not recommended for most users!!!) +#' * [grassHelp()]: Open the help page for a **GRASS** module. #' * [grassInfo()]: **GRASS** version and citation +#' * [grassStarted()]: Has a connection **GRASS** been made within the current **R** session? #' * [mow()]: Remove unused rasters and vectors from the **GRASS** cache #' * [reorient()]: Convert degrees between 'north-orientation' and 'east orientation' #' * [replaceNAs()]: Replace `NA`s in columns of a `data.table` or `data.frame`, or in a vector #' * [seqToSQL()]: Format a numeric series into an SQL value call +#' * [workDir()]: #' * [update()]: Refresh metadata in a `GRaster` or `GVector` object #' #' ## Data objects +#' * [fastData()]: Helper function to quickly obtain example rasters and vectors #' * [appFunsTable][appFunsTable] (see also [appFuns()]): Functions usable by the [app()] function #' * [madChelsa][madChelsa]: Climate rasters for of a portion of eastern Madagascar #' * [madCoast0][madCoast0], [madCoast4][madCoast4], and [madCoast][madCoast]: Borders of an eastern portion of Madagascar @@ -284,14 +304,20 @@ #' * [madLANDSAT][madLANDSAT]: Surface reflectance in 2023 #' * [madPpt][madPpt], [madTmin][madTmin], [madTmax][madTmax]: Rasters of mean monthly precipitation, and minimum and maximum temperature #' * [madRivers][madRivers]: Rivers vector -#' * [vegIndices][vegIndices]: Vegetation indices that can be calculated using [vegIndex()]. +#' * [vegIndices][vegIndices]: Vegetation indices that can be calculated using [vegIndex()] #' #' ## Esoteric tutorials and arcane notes -#' Comparisons between `GRegion`s can be performed using the `==` and `!=` operators. -#' Vignette on **GRASS** "projects/locations" and "mapsets": `vignette("projects_mapsets", package = "fasterRaster"`) -#' Vignette on **GRASS** "regions": `vignette("regions", package = "fasterRaster")` -#' Vignette on **fasteRaster** hidden functions: `vignette("hidden_functions", package = "fasterRaster")` -#' * [grassStarted()]: Has a connection **GRASS** been made within the current **R** session? +#' * Comparisons between `GRegion`s can be performed using the `==` and `!=` operators. +#' * Vignette on **GRASS** "projects/locations" and "mapsets": `vignette("projects_mapsets", package = "fasterRaster")` +#' * Vignette on **GRASS** "regions": `vignette("regions", package = "fasterRaster")` +#' * Vignette on **fasteRaster** hidden functions: `vignette("hidden_functions", package = "fasterRaster")` +#' +#' ## Classes +#' * [`GLocation`]: Fundamental class; points to a "location/project" in **GRASS** +#' * [`GSpatial`]: Basic class of any spatial object +#' * [`GRegion`]: Points to a "region" of a "location/project" in **GRASS** +#' * [`GRaster`]: Raster class +#' * [`GVector`]: Spatial vector class #' #' @author Adam B. Smith #' @name fasterRaster diff --git a/R/fillHoles.r b/R/fillHoles.r index 293326ab..0029fd16 100644 --- a/R/fillHoles.r +++ b/R/fillHoles.r @@ -4,7 +4,7 @@ #' #' @param x A `GVector`. #' -#' @param fail Logical: If `TRUE` (default), and **GRASS 8.4** or higher is not installed, cause an error. If `FALSE`, a warning will be displayed and a `NULL` value will be returned. This function requires **GRASS 8.4** or higher to be installed. +#' @param fail Logical: If `TRUE` (default), and **GRASS 8.3** or higher is not installed, cause an error. If `FALSE`, a warning will be displayed and a `NULL` value will be returned. This function requires **GRASS 8.3** or higher to be installed. #' #' @returns A `GVector`. #' diff --git a/R/fillNAs.r b/R/fillNAs.r index 564d988a..226dae8c 100644 --- a/R/fillNAs.r +++ b/R/fillNAs.r @@ -8,7 +8,7 @@ #' #' @param method Character: Type of spline, either "`bilinear`" (default), "`bicubic`", or "`RST`" (regularized splines with tension). Partial matching is used and case is ignored. #' -#' **Note**: The RST method will often display warnings, but thesecan be ignored. +#' **Note**: The RST method will often display warnings, but these can be ignored. #' #' @param min,max Numeric: Lowest and highest values allowed in the interpolated values. Values outside these bounds will be truncated to the minimum/maximum value(s) allowed. The default imposes no constraints. For multi-layered rasters, you can supply a single value for `min` and/or `max`, or multiple values (one per layer). Values will be recycled if there are fewer than one or them per layer in the raster. #' @@ -18,7 +18,7 @@ #' #' @example man/examples/ex_fillNAs.r #' -#' @seealso [terra::interpNear()]; module [r.fillnulls](https://grass.osgeo.org/grass84/manuals/r.fillnulls.html) in **GRASS** +#' @seealso [terra::interpNear()], **GRASS** module `r.fillnulls` (see `grassHelp("r.fillnulls")`) #' #' @aliases fillNAs #' @rdname fillNAs @@ -40,9 +40,9 @@ methods::setMethod( if (length(max) < nLayers) max <- rep(max, length.out = nLayers) mm <- minmax(x) - if (any(min > mm["min", ])) warning("The ", sQuote("min"), " value is greater than the actual minimum value in at least one raster layer.\n Observed values will be truncated.") + if (any(min > mm["min", ])) warning("The `min` value is greater than the actual minimum value in at least one raster layer.\n Observed values will be truncated.") - if (any(max > mm["max", ])) warning("The ", sQuote("max"), " value is less than the actual maximum value in at least one raster layer.\n Observed values will be truncated.") + if (any(max > mm["max", ])) warning("The `max` value is less than the actual maximum value in at least one raster layer.\n Observed values will be truncated.") srcs <- .makeSourceName("r_fillnulls", "raster", nLayers) diff --git a/R/flow.r b/R/flow.r index 96d8e56e..e3c347a2 100644 --- a/R/flow.r +++ b/R/flow.r @@ -7,7 +7,7 @@ #' * Flooded areas; and/or #' * Topographic convergence (log of flow accumulation divided by local slope). #' -#' More details about the computations can be found at the help page for the [`r.terraflow`](https://grass.osgeo.org/grass84/manuals/r.terraflow.html) module for **GRASS**. +#' More details about the computations can be found at the help page for the **GRASS** module `r.terraflow`] (see `grassHelp("r.terraflow")`) #' #' @param x A `GRaster` with a single layer, typically representing elevation. #' @@ -23,9 +23,9 @@ #' * `"TCI"`: Topographic convergence index #' * `"*"`: All of the above #' -#' @seealso [flowPath()], [streams()], the [`r.terraflow`](https://grass.osgeo.org/grass84/manuals/r.terraflow.html) module for **GRASS** +#' @seealso [flowPath()], [streams()], the **GRASS** module `r.terraflow` (see `grassHelp("r.terraflow")`) #' -#' @param scratchDir Character: Directory in which to store temporary files. The **GRASS** module `r.terraflow` makes a lot of temporary files. The default is given by [tempdir()]. +#' @param scratchDir Character or `NULL` (default): Directory in which to store temporary files. The **GRASS** module `r.terraflow` makes a lot of temporary files. If this is `NULL`, then a temporary folder in the user's working directory will be used (see [getwd()]). #' #' @returns A `GRaster`. #' @@ -42,9 +42,11 @@ methods::setMethod( direction = "multi", return = "accumulation", dirThreshold = Inf, - scratchDir = tempdir() + scratchDir = NULL ) { + if (nlyr(x) > 1L) stop("This function can only use a single-layered GRaster as input.") + returns <- c("accumulation", "basins", "direction", "flooded", "TCI") if (any(return == "*")) return <- returns return <- omnibus::pmatchSafe(return, returns) @@ -52,11 +54,15 @@ methods::setMethod( direction <- omnibus::pmatchSafe(direction, c("single", "multi"), nmax = 1L) - if (nlyr(x) > 1L) stop("This function can only use a single-layered GRaster as input.") - .locationRestore(x) .region(x) + if (is.null(scratchDir)) { + scratchDir <- paste0(getwd(), "/flow_temporary_files") + omnibus::dirCreate(scratchDir) + on.exit(unlink(scratchDir, recursive = TRUE, force = TRUE)) + } + args <- list( cmd = "r.terraflow", elevation = sources(x), @@ -74,6 +80,13 @@ methods::setMethod( if (any(return == "flooded")) args$filled <- .makeSourceName("r_flow_filled", "raster") if (any(return == "TCI")) args$tci <- .makeSourceName("r_flow_tci", "raster") + if (is.null(scratchDir)) { + scratchDir <- getwd() + scratchDir <- paste0(scratchDir, '/flow_temp_files') + omnibus::dirCreate(scratchDir) + on.exit(unlink(scratchDir, recursive = TRUE, force = TRUE, expand = TRUE), add = TRUE) + } + do.call(rgrass::execGRASS, args = args) names <- srcs <- character() diff --git a/R/flowPath.r b/R/flowPath.r index e488ff95..b9baeb27 100644 --- a/R/flowPath.r +++ b/R/flowPath.r @@ -17,7 +17,7 @@ #' #' @example man/examples/ex_flowPath.r #' -#' @seealso [flow()], [streams()], the [`r.drain`](https://grass.osgeo.org/grass84/manuals/r.drain.html) module for **GRASS** +#' @seealso [flow()], [streams()], the **GRASS** module `r.drain` (see `grassHelp("r.drain")`) #' #' @aliases flowPath #' @rdname flowPath diff --git a/R/focal.r b/R/focal.r index 8fb17dce..6cde292f 100644 --- a/R/focal.r +++ b/R/focal.r @@ -13,7 +13,7 @@ #' * "`mean`" (default) #' * "`median`" #' * "`mode`" -#' * "`min`" or "`max`": Minumum or maximum. Should not use a weights matrix. +#' * "`min`" or "`max`": Minimum or maximum. Should not use a weights matrix. #' * "`range`": Difference between the maximum and minimum. Should not use a weights matrix. #' * "`sd`": Sample standard deviation. NB: This is the same as the [stats::sd()] function. #' * "`sdpop`": Population standard deviation. NB: This is the same as the function "stddev" in the **GRASS** module `r.neighbors`. diff --git a/R/fractalRast.r b/R/fractalRast.r index 1ebaa11f..1ad8dfea 100644 --- a/R/fractalRast.r +++ b/R/fractalRast.r @@ -28,7 +28,7 @@ methods::setMethod( sigma = 1, dimension = 2.05) { - if (any(dimension <= 2) | any(dimension >= 3)) stop("Argument ", sQuote("dimension"), " must be in the range (2, 3).") + if (any(dimension <= 2) | any(dimension >= 3)) stop("Argument `dimension` must be in the range (2, 3).") mu <- rep(mu, length.out = n) sigma <- rep(sigma, length.out = n) diff --git a/R/fragmentation.r b/R/fragmentation.r index c842350d..e38ecbca 100644 --- a/R/fragmentation.r +++ b/R/fragmentation.r @@ -42,7 +42,7 @@ methods::setMethod( function(x, w = 3, undet = "undetermined", none = NA, na.rm = TRUE, cores = faster("cores"), verbose = TRUE) { # errors? - if (!omnibus::is.wholeNumber(w) || w < 1L || w %% 2 == 0) stop("Argument ", sQuote("w"), " must be an odd, positive integer.") + if (!omnibus::is.wholeNumber(w) || w < 1L || w %% 2 == 0) stop("Argument `w` must be an odd, positive integer.") undet <- omnibus::pmatchSafe(undet, c("undetermined", "perforated", "edge"), nmax = 1L) # setup diff --git a/R/freq.r b/R/freq.r index 85e90f55..d93092c5 100644 --- a/R/freq.r +++ b/R/freq.r @@ -55,7 +55,7 @@ methods::setMethod( nLayers <- length(src) - if (any(dtype != "CELL") & bins <= 0) stop("Argument ", sQuote("bins"), " must be a positive integer.") + if (any(dtype != "CELL") & bins <= 0) stop("Argument `bins` must be a positive integer.") # get values for each raster out <- list() diff --git a/R/geomorphons.r b/R/geomorphons.r index fc50845a..ae3f984b 100644 --- a/R/geomorphons.r +++ b/R/geomorphons.r @@ -1,6 +1,6 @@ #' Identify terrain feature types #' -#' @description Geomorphons are idealized terrain types calculated from an elevator raster based on a moving window of a given size. The window is a torus (which can have an inner radius of 0, so can also be a circle), which allows it to identify geomorphons of a given size while ignoring ones larger or smaller. There are 10 basic geomorphons. Consult the The **GRASS** module [`r.geomorphon`](https://grass.osgeo.org/grass84/manuals/r.geomorphon.html) for more details and diagrams of each type of geomorphon. They include: +#' @description Geomorphons are idealized terrain types calculated from an elevator raster based on a moving window of a given size. The window is a torus (which can have an inner radius of 0, so can also be a circle), which allows it to identify geomorphons of a given size while ignoring ones larger or smaller. There are 10 basic geomorphons. Consult the the manual for **GRASS** module `r.geomorphon` using `grassHelp("r.geomorphon")` for more details and diagrams of each type of geomorphon. Geomorphon types include: #' 1. Flat areas: Focal area has approximately the same elevation as surrounding areas #' 2. Pits: An area is lower than all other surrounding areas #' 3. Valley: Focal area has elevation similar to two opposing side of the window but lower than the other two opposing sides @@ -23,13 +23,13 @@ #' @param flatDist Numeric: Distance (in meters) to correct for the effect of large distances on the diminished capacity to identify "flat" geomorphons. If the distance between the focal area and a surrounding area surpasses this distance, then the effective value of `flat` will be reduced #' #' @param mode Character: Method for implementing the zenith/line-of-site search. Partial matching is used: -#' * `"1"` (default): The "original" geomorphon mode (in **GRASS** module [`r.geomorphon`](https://grass.osgeo.org/grass84/manuals/r.geomorphon.html), the "anglev1" method) +#' * `"1"` (default): The "original" geomorphon mode (in **GRASS** module `r.geomorphon`, the "anglev1" method) #' * `"2"`: Better handling of cases with equal zenith/nadir angles (the "anglev2" method) #' * `"2d"`: As `"2"`, but takes into account zenith/nadir distance ("anglev2_distance" method) #' #' @returns A categorical `GRaster` where each geomorphon is a category (see `vignette("GRasters", package = "fasterRaster")`). #' -#' @seealso Module [`r.geomorphon`](https://grass.osgeo.org/grass84/manuals/r.geomorphon.html) in **GRASS** +#' @seealso **GRASS** module `r.geomorphon` (see `grassHelp("r.geomorphon")`) #' #' @example man/examples/ex_geomorphons.r #' diff --git a/R/global.r b/R/global.r index bd215b67..118ee103 100644 --- a/R/global.r +++ b/R/global.r @@ -122,7 +122,7 @@ methods::setMethod( intern = TRUE ) - if (versionNumber >= 8.3) args$nprocs <- faster("cores") + if (versionNumber >= 8.4) args$nprocs <- faster("cores") if (any(fun == "median")) args$flags <- c(args$flags, "e") info <- do.call(rgrass::execGRASS, args) @@ -145,12 +145,15 @@ methods::setMethod( colNames <- fun isQuant <- which(colNames == "quantile") quantNames <- paste0("quantile_", probs) + nCols <- length(colNames) if (length(fun) == 1L & fun[1L] == "quantile") { colNames <- quantNames } else if (colNames[1L] == "quantile") { - colNames <- c(quantNames, colNames[2L:length(colNames)]) - } else if (colNames[length(colNames)] == "quantile") { - colNames <- c(colNames[1L:(length(colNames) - 1L)], quantNames) + colNames <- c(quantNames, colNames[2L:nCols]) + } else if (colNames[nCols] == "quantile") { + colNames <- c(colNames[1L:(nCols - 1L)], quantNames) + } else { + colNames <- c(colNames[(1L:(isQuant) - 1L)], quantNames, colNames[(isQuant + 1L):nCols]) } names(thisOut) <- colNames @@ -213,6 +216,7 @@ methods::setMethod( # this <- strsplit(this, split=":")[[1L]][2L] # this <- as.numeric(this) + quantInfo <- quantInfo[seq_along(probs)] this <- strsplit(quantInfo, split = ":") this <- lapply(this, as.numeric) this <- do.call(rbind, this) @@ -280,7 +284,7 @@ methods::setMethod( intern = TRUE ) - if (versionNumber >= 8.3) args$nprocs <- faster("cores") + if (versionNumber >= 8.4) args$nprocs <- faster("cores") thisInfo <- do.call(rgrass::execGRASS, args = args) if (faster("clean")) on.exit(.rm(srcSS, type = "raster", warn = FALSE), add = TRUE) @@ -331,7 +335,7 @@ methods::setMethod( intern = TRUE ) - if (grassInfo("versionNumber") >= 8.3) args$nprocs <- faster("cores") + if (grassInfo("versionNumber") >= 8.4) args$nprocs <- faster("cores") thisInfo <- do.call(rgrass::execGRASS, args = args) if (faster("clean")) on.exit(.rm(srcSS, type = "raster", warn = FALSE), add = TRUE) diff --git a/R/grassGUI.r b/R/grassGUI.r new file mode 100644 index 00000000..6cd7b917 --- /dev/null +++ b/R/grassGUI.r @@ -0,0 +1,26 @@ +#' Start the GRASS GUI (potentially dangerous!) +#' +#' @description This function starts the **GRASS** GUI. It is provided merely as a utility... in most cases, it should *not* be used if you are doing any kind of analysis of rasters or vectors using **fasterRaster**. The reason for this prohibition is that **fasterRaster** objects, like `GRaster`s and `GVector`s, are really "pointers" to objects in **GRASS**. If **fasterRaster** points to a **GRASS** object that is changed in **GRASS** but not **R**, then **fasterRaster** will not "know" about it, so changed won't be reflected in the **fasterRaster** object. +#' +#' One aspect of the GUI that is useful but will not change objects is to use it to plot rasters and vectors. However, the a **fasterRaster** object in **R** will have a different name in **GRASS**. The name in **GRASS** of a `GVector` or `GRaster` is given by [sources()]. +#' +#' @returns Nothing (starts the **GRASS** GUI). +#' +#' @seealso [mow()] +#' +#' @example man/examples/ex_grassGUI.r +#' +#' @aliases grassGUI +#' @rdname grassGUI +#' @exportMethod grassGUI +methods::setMethod( + f = "grassGUI", + signature = c(x = "missing"), + function() { + if (grassStarted()) { + rgrass::execGRASS("g.gui", ui = "wxpython", flags = c(.quiet(), "f")) + } else { + warning("GRASS needs to be started by using `fast()` at least once before starting the GUI.") + } + } +) diff --git a/R/grassHelp.r b/R/grassHelp.r new file mode 100644 index 00000000..191bf590 --- /dev/null +++ b/R/grassHelp.r @@ -0,0 +1,49 @@ +#' Open the help page for a GRASS module +#' +#' @description This function opens the manual page for a **GRASS** module (function) in your browser. +#' +#' @param x Character: Any of: +#' * The name of a **GRASS** module (e.g., `"r.mapcalc"`). +#' * `"type"`: Display a page wherein modules are classified by types. +#' * `"topics"`: Display an index of topics. +#' +#' @param online Logical: If `FALSE` (default), show the manual page that was included with your installation of **GRASS** on your computer. If `FALSE`, show the manual page online (requires an Internet connection). In either case, the manual page will display for the version of **GRASS** you have installed. +#' +#' @returns Nothing (opens a web page). +#' +#' @example man/examples/ex_grassHelp.r +#' +#' @aliases grassHelp +#' @rdname grassHelp +#' @export +grassHelp <- function(x, online = FALSE) { + + if (interactive()) { + + if (!grassStarted()) { + omnibus::say("You must start GRASS first by using fast() at least once before opening a manual page.") + return() + } + + x <- tolower(x) + if (length(x) != 1L) stop("Only one help page can be opened at a time.") + + args <- list( + cmd = "g.manual", + entry = x, + flags = .quiet() + ) + + if (x == "type") { + args$flags <- c(args$flags, "i") + } else if (x == "index") { + args$flags <- c(args$flags, "t") + } + + do.call(rgrass::execGRASS, args = args) + + } else { + warning("You can only open GRASS manual pages in an interactive R session.") + } + +} diff --git a/R/grassInfo.r b/R/grassInfo.r index ebad2b3a..144f0953 100644 --- a/R/grassInfo.r +++ b/R/grassInfo.r @@ -6,7 +6,7 @@ #' * `"citation"` (default) #' * `"copyright"`: Copyright information #' * `"version"`: Version number and release year -#' * `"versionNumber"`: Version number as numeric, major and minor only (e.g., 8.3) +#' * `"versionNumber"`: Version number as numeric, major and minor only (e.g., 8.4) #' #' Partial matching is used and case is ignored. #' diff --git a/R/grassStarted.r b/R/grassStarted.r index a3e78f4b..d05d7b37 100644 --- a/R/grassStarted.r +++ b/R/grassStarted.r @@ -1,6 +1,6 @@ #' Has "GRASS" been started or not? #' -#' @description Returns `TRUE` or `FALSE`, depending on whether a **GRASS** connection has been made or not within the current **R** session. Usually used only by developers. +#' @description Returns `TRUE` or `FALSE`, depending on whether a **GRASS** connection has been made or not within the current **R** session. Usually used only by developers. **GRASS** is started the first time [fast()] is used. #' #' @returns Logical. #' diff --git a/R/grid.r b/R/grid.r index f5d4ba0c..9fb06c51 100644 --- a/R/grid.r +++ b/R/grid.r @@ -49,7 +49,7 @@ methods::setMethod( # calculate cell number and re-calibrate GRASS region if (is.null(nx) & is.null(ny)) { - stop("At least one of ", sQuote("nx"), " or ", sQuote("ny"), " must be defined.") + stop("At least one of `nx` or `ny` must be defined.") } else if (!is.null(nx) & is.null(ny)) { if (use == "number") { diff --git a/R/hillshade.r b/R/hillshade.r index 8a4b47a6..e65990a0 100644 --- a/R/hillshade.r +++ b/R/hillshade.r @@ -24,8 +24,8 @@ methods::setMethod( signature = c(x = "GRaster"), definition = function(x, angle = 45, direction = 0, zscale = 1) { - if (angle < 0 | angle > 90) stop("Argument ", sQuote("angle"), " must be in the range [0, 90].") - if (direction < 0 | direction > 360) stop("Argument ", sQuote("angle"), " must be in the range [0, 360].") + if (angle < 0 | angle > 90) stop("Argument `angle` must be in the range [0, 90].") + if (direction < 0 | direction > 360) stop("Argument `angle` must be in the range [0, 360].") .locationRestore(x) .region(x) diff --git a/R/init.r b/R/init.r new file mode 100644 index 00000000..f39913f0 --- /dev/null +++ b/R/init.r @@ -0,0 +1,75 @@ +#' GRaster with values equal to row, column, coordinate, regular, or "chess" +#' +#' @description This function can be used to make a `GRaster` with cell values equal to the cell center's longitude, latitude, row, or column, or in a "chess"-like or "regular" pattern. +#' +#' @param x A `GRaster` to be used as a template. +#' +#' @param fun Character: Any of: +#' * `"x"` or `"y"`: Cell longitude or latitude +#' * `"row"` or `"col"`: Cell row or column +#' * `"chess"`: Alternating values. +#' * `"regular"`: Evenly-spaced cells with the same value. +#' +#' @param odd Logical: If `TRUE` (default), and `fun` is `"chess"`, then the top left cell in the raster will be a "negative" cell. If `FALSE`, then the top left cell with be "positive". +#' +#' @param every Numeric or integer: If `fun` is `"regular"`, then make every `every` cell a "positive" cell, and interstitial cells "negative." The default is 2 (every other cell). +#' +#' @param vals Vector of two numeric values: If `fun` is `"chess"` or `"regular"`, then assign the first value to "positive" cells and the second value to "negative" cells. The default is `c(1, 0)` +#' +#' @returns A `GRaster` with as many layers as `x`. +#' +#' @seealso [terra::init()], [longlat()] +#' +#' @example man/examples/ex_init.r +#' +#' @aliases init +#' @rdname init +#' @exportMethod init +methods::setMethod( + f = "init", + signature = c(x = "GRaster"), + function(x, fun, odd = TRUE, vals = c(0, 1)) { + + funs <- c("x", "y", "row", "col", "chess", "regular") + fun <- omnibus::pmatchSafe(fun, funs, n = 1) + + # if (fun %in% c("chess", "regular") && (!omnibus::is.wholeNumber(every) | every < 1)) stop("The value of `every` must be a whole number > 0.") + + .locationRestore(x) + .region(x) + + vals <- as.character(vals) + vals[vals == "NA"] <- "null()" + + nLayers<- nlyr(x) + srcs <- .makeSourceName(paste0("init_", fun), "raster", nLayers) + for (i in seq_len(nLayers)) { + + if (fun == "chess") { + + if (odd) { + ex <- paste0(srcs[i], " = if((row() % 2 == 1 & col() % 2 == 1) | (row() % 2 == 0 & col() % 2 == 0), ", vals[1L], ", ", vals[2L], ")") + } else { + ex <- paste0(srcs[i], " = if((row() % 2 == 0 & col() % 2 == 1) | (row() % 2 == 1 & col() % 2 == 0), ", vals[1L], ", ", vals[2L], ")") + } + + } else if (fun == "regular") { + + if (odd) { + ex <- paste0(srcs[i], " = if(row() % 2 == 1 | col() % 2 == 1, ", vals[1L], ", ", vals[2L], ")") + } else { + ex <- paste0(srcs[i], " = if(row() % 2 == 0 | col() % 2 == 0, ", vals[1L], ", ", vals[2L], ")") + } + + } else if (fun != "chess") { + + ex <- paste0(srcs[i], " = ", fun, "()") + + } + rgrass::execGRASS("r.mapcalc", expression = ex, flags = c(.quiet(), "overwrite")) + + } + .makeGRaster(srcs, "layer") + + } # EOF +) diff --git a/R/interpIDW.r b/R/interpIDW.r index 35bdbb23..41eb15c2 100644 --- a/R/interpIDW.r +++ b/R/interpIDW.r @@ -14,7 +14,7 @@ #' #' @returns A `GRaster`. #' -#' @seealso [terra::interpIDW()], [interpSplines()], [fillNAs()], module [`v.surf.idw`](https://grass.osgeo.org/grass84/manuals/v.surf.idw.html) in **GRASS** +#' @seealso [terra::interpIDW()], [interpSplines()], [fillNAs()], **GRASS** module `v.surf.idw` (se `grasshelp("v.surf.idw")`) #' #' @aliases interpIDW #' @rdname interpIDW @@ -24,7 +24,7 @@ methods::setMethod( signature = c(x = "GVector", y = "GRaster"), function(x, y, field, nPoints = Inf, power = 2) { - if (geomtype(x, grass = TRUE) != "point") stop("Argument ", sQuote("x"), " must be a points GVector.") + if (geomtype(x, grass = TRUE) != "point") stop("Argument `x` must be a points GVector.") compareGeom(x, y) .locationRestore(x) @@ -34,14 +34,14 @@ methods::setMethod( # copy values field to x if (is.null(field) & is.2d(x)) { - stop("Argument ", sQuote("field"), " cannot be NULL if ", sQuote("x"), " is a 2-dimensional points GVector.") + stop("Argument `field` cannot be NULL if `x` is a 2-dimensional points GVector.") } else if (is.numeric(field) | is.integer(field)) { field <- names(x)[field] } if (!is.null(field)) { - if (anyNA(x@table[[field]])) stop("The column ", sQuote(field), " has at least one NA in it. NAs are not permissible.") + if (anyNA(x@table[[field]])) stop("The column `field` has at least one NA in it. NAs are not permissible.") cats <- .vCats(x, db = FALSE) db <- data.table::data.table(frid = cats, TEMPTEMP_ = x@table[[field]]) diff --git a/R/interpSplines.r b/R/interpSplines.r index 6fe3b5a3..7be9aa2f 100644 --- a/R/interpSplines.r +++ b/R/interpSplines.r @@ -29,7 +29,7 @@ #' * `lambda` is `NULL` and `interpolate` is `FALSE`: A `data.frame` with values of `lambdas` that were assessed, plus `mean` (mean residual value) and `rms` (root mean square error). You can see the table using `attr(output_raster, "lambdas", exact = TRUE)`. #' * `lambda` is a number (`interpolate` is ignored): A `GRaster`. #' -#' @seealso [interpIDW()], [fillNAs()], module [`v.surf.bspline`](https://grass.osgeo.org/grass84/manuals/v.surf.bspline.html) in **GRASS** +#' @seealso [interpIDW()], [fillNAs()], **GRASS** module `v.surf.bspline` (see `grassHelp("v.surf.bspline")`) #' #' @aliases interpSplines #' @rdname interpSplines @@ -117,16 +117,16 @@ methods::setMethod( ) { if (!is.null(lambda)) { - if (lambda <= 0) stop("Argument ", sQuote("lambda"), " must be NULL or > 0.") + if (lambda <= 0) stop("Argument `lambda` must be NULL or > 0.") } if (!is.null(lambda)) interpolate <- TRUE - if (geomtype(x, grass = TRUE) != "point") stop("Argument ", sQuote("x"), " must be a points GVector.") + if (geomtype(x, grass = TRUE) != "point") stop("Argument `x` must be a points GVector.") if (inherits(y, "GVector")) { - if (geomtype(y, grass = TRUE) != "point") stop("Argument ", sQuote("y"), " must be a points GVector or a GRaster.") + if (geomtype(y, grass = TRUE) != "point") stop("Argument `y` must be a points GVector or a GRaster.") } @@ -139,14 +139,14 @@ methods::setMethod( # copy values field to x if (is.null(field) & is.2d(x)) { - stop("Argument ", sQuote("field"), " cannot be NULL if ", sQuote("x"), " is a 2-dimensional points GVector.") + stop("Argument `field` cannot be NULL if `x` is a 2-dimensional points GVector.") } else if (is.numeric(field) | is.integer(field)) { field <- names(x)[field] } if (!is.null(field)) { - if (anyNA(x@table[[field]])) stop("The column ", sQuote(field), " has at least one NA in it. NAs are not permissible.") + if (anyNA(x@table[[field]])) stop("The column `field` has at least one NA in it. NAs are not permissible.") cats <- .vCats(x, db = FALSE) db <- data.table::data.table(frid = cats, TEMPTEMP_ = x@table[[field]]) diff --git a/R/is.lonlat.r b/R/is.lonlat.r index ba3f98e1..8fa0b96b 100644 --- a/R/is.lonlat.r +++ b/R/is.lonlat.r @@ -1,6 +1,6 @@ #' Test if a coordinate reference system is unprojected #' -#' @description `is.lonlat()` attempst to determine if a coordinate reference system is unprojected (e.g., WGS84, NAD83, NAD27, etc.). For `GRaster`s and `GVector`s, the function should always be correct. For WKT character strings and `sf` vectors, it does this by looking for the "CONVERSION[" tag in the WKT string (or the object's WKT string), and if it finds one, returns `FALSE`. This may not be truthful in all cases. +#' @description `is.lonlat()` attempts to determine if a coordinate reference system is unprojected (e.g., WGS84, NAD83, NAD27, etc.). For `GRaster`s and `GVector`s, the function should always be correct. For WKT character strings and `sf` vectors, it does this by looking for the "CONVERSION[" tag in the WKT string (or the object's WKT string), and if it finds one, returns `FALSE`. This may not be truthful in all cases. #' #' @param x A WKT coordinate reference string or an object from which on can be obtained (e.g., a `GRaster`, `GVector`, `GRegion`, `GLocation`, `SpatRaster`, `SpatVector`, or `sf` object). #' diff --git a/R/layerIndex.r b/R/layerIndex.r index e10dbbe4..324879c4 100644 --- a/R/layerIndex.r +++ b/R/layerIndex.r @@ -6,10 +6,12 @@ #' #' @param recycle Logical: If `TRUE` (default), and `layer` is logical and smaller in number than the number of layers, then recycle the vector of `layer`. #' +#' @param negate Logical: If `TRUE`, return indices of all layers *not* identified in `layer`. +#' #' @returns An integer vector. #' #' @keywords internal -.layerIndex <- function(layer, x, recycle = TRUE) { +.layerIndex <- function(layer, x, recycle = TRUE, negate = FALSE) { nx <- nlyr(x) @@ -23,6 +25,9 @@ if (any(layer > nx) | any(layer < 1L)) stop("Index out of bounds.") } if (any(!(layer %in% seq_len(nx)))) stop("Raster only contains ", nlyr(x), " layer(s).") + + if (negate) layer <- seq_len(nx)[-layer] + layer } diff --git a/R/levels.r b/R/levels.r index e7b3dbd4..6228f231 100644 --- a/R/levels.r +++ b/R/levels.r @@ -112,8 +112,8 @@ methods::setMethod( signature = c(x = "GRaster"), function(x, layer = 1, value, active = 1) { - layer <- NULL # obviates check(): "no visible binding for global variable `layer`" - layer <- .layerIndex(layer, x, recycle = TRUE) + # layer <- NULL # obviates check(): "no visible binding for global variable `layer`" + layer <- .layerIndex(layer = layer, x, recycle = TRUE) if (!inherits(value, "list")) value <- list(value) @@ -150,7 +150,7 @@ methods::setMethod( for (i in layer) { x@levels[[i]] <- value[[i]] - x@activeCat[i] <- as.integer(active) + x@activeCat[i] <- as.integer(active + 1L) } methods::validObject(x) x diff --git a/R/locationFind.r b/R/locationFind.r index dcab912c..7e1d8e22 100644 --- a/R/locationFind.r +++ b/R/locationFind.r @@ -1,17 +1,17 @@ #' Match CRS of a GSpatial object and an existing "GRASS" location #' -#' @description The function searches the set of available **GRASS** "locations" for one that has a coordinate reference system matching a `GSpatial` object. If none are found, or if no connection with **GRASS** has yet been made, then it returns `NULL`. Otherwise, it returns either the index or the name of the matching location. +#' @description The function searches the set of available **GRASS** "projects" (previously known as "locations") for one that has a coordinate reference system matching a `GSpatial` object. If none are found, or if no connection with **GRASS** has yet been made, then it returns `NULL`. Otherwise, it returns either the index or the name of the matching location. #' #' @param x Either: #' * Missing: Returns names and coordinate reference system strings of all "locations". #' * A character representing a coordinate reference system in WKT format -#' * A `SpatRaster`, `SpatVector`, or `sf` vector +#' * A `SpatRaster`, `SpatVector`, or `sf` vector with a coordinate reference system #' * A `GSpatial` object (usually a `GRaster` or `GVector`) #' #' @param return Either: #' * `"name"` (default): Returns the name of the "location" with a coordinate reference system the same as `x`. -#' * `"index"`: Returns the index of this "location". -#' * `"crs"`: Returns the coordinate reference system of this "location". +#' * `"index"`: Returns the index of this "location" in `.fasterRaster$locations` of the `.fasterRaster` environment. +#' * `"crs"`: Returns the coordinate reference system of this "project/location". #' #' @param match Character: Method used to find the location. If `match` is "`name`"" (default), then the name of the location is used. If `match` is "`crs`", then the coordinate reference system of each location is checked for a match. #' diff --git a/R/locationRestore.r b/R/locationRestore.r index 79e1017e..68a97e99 100644 --- a/R/locationRestore.r +++ b/R/locationRestore.r @@ -63,7 +63,7 @@ methods::setMethod( index <- .locationFind(location, return = "index") if (is.null(index)) { - stop("Location has not been created.") + stop("Location has not been created. You must use faster() to set the installation directory where GRASS is installed, then use fast() at least once to start GRASS.") } opts <- faster() @@ -79,7 +79,6 @@ methods::setMethod( ### reconnect to location emptyRast <- terra::rast(matrix(1L), crs = coordRef) - ### start the GRASS session suppressWarnings( session <- rgrass::initGRASS( gisBase = grassDir, @@ -95,7 +94,7 @@ methods::setMethod( ) ) - .fasterRaster$activeLocation <- location + .fasterRaster$activeLocation <<- location } diff --git a/R/longlat.r b/R/longlat.r index 8dbd6318..c352546c 100644 --- a/R/longlat.r +++ b/R/longlat.r @@ -1,10 +1,12 @@ #' Create longitude/latitude rasters #' -#' @description `longlat()` creates two rasters, one with cell values equal to the longitude of the cell centers, and one with cell values equal to the latitude of the cell centers. Values will be in decimal degrees, regardless of the projection of the raster. +#' @description `longlat()` creates two rasters, one with cell values equal to the longitude of the cell centers, and one with cell values equal to the latitude of the cell centers. Values will be in decimal degrees, regardless of the projection of the raster. If you want projected coordinates, use [init()]. #' #' @param x A `GRaster`. #' #' @returns A `GRaster` stack. +#' +#' @seealso [init()] #' #' @example man/examples/ex_longlat.r #' diff --git a/R/ls.r b/R/ls.r index 386c1697..be21dd6b 100644 --- a/R/ls.r +++ b/R/ls.r @@ -14,6 +14,7 @@ .ls <- function(type = c("rasters", "vectors", "rasters3d", "groups")) { rov <- c("rasters", "vectors", "rasters3d", "groups") + type <- omnibus::pmatchSafe(type, rov, useFirst = TRUE, n = length(rov)) if (is.null(type)) type <- rov # find rasters and vector @@ -23,7 +24,7 @@ # failure to match if (anyNA(match)) { - warning("No matches.", immediate.=TRUE) + warning("No matches.", immediate. = TRUE) out <- NULL # specific match @@ -31,7 +32,7 @@ # rasters if (any(match == 1L)) { - rasts <- rgrass::execGRASS("g.list", flags=.quiet(), type="raster", intern=TRUE, echoCmd=FALSE) + rasts <- rgrass::execGRASS("g.list", flags = .quiet(), type = "raster", intern = TRUE, echoCmd = FALSE) if (length(rasts) > 0L) names(rasts) <- rep("raster", length(rasts)) rasts <- sort(rasts) } diff --git a/R/madChelsa.r b/R/madChelsa.r index 93ca2685..31eba43b 100644 --- a/R/madChelsa.r +++ b/R/madChelsa.r @@ -14,7 +14,7 @@ #' #' @keywords climate Madagascar #' -#' @references Karger, D.N., Conrad, O., Böhner, J., Kawohl, T., Kreft, H., Soria-Auza, R.W., Zimmermann, N.E., Linder, H.P., and Kessler, M. 2017. Climatologies at high resolution for the earth's land surface areas. *Scientific Data* 4:170122. \doi{10.1038/sdata.2017.122} +#' @references Karger, D.N., Conrad, O., Bohner, J., Kawohl, T., Kreft, H., Soria-Auza, R.W., Zimmermann, N.E., Linder, H.P., and Kessler, M. 2017. Climatologies at high resolution for the earth's land surface areas. *Scientific Data* 4:170122. \doi{10.1038/sdata.2017.122} #' #' @source \doi{https://doi.org/10.1038/sdata.2017.122} #' diff --git a/R/makeSourceName.r b/R/makeSourceName.r index 0ff97b40..5175783b 100644 --- a/R/makeSourceName.r +++ b/R/makeSourceName.r @@ -13,7 +13,7 @@ #' @keywords internal .makeSourceName <- function(x = NULL, type = NULL, n = 1L, name = NULL) { - if (is.null(x) & is.null(type)) stop("Both ", sQuote("x"), " and ", sQuote("type"), " cannot be ", dQuote("NULL"), " at the same time.") + if (is.null(x) & is.null(type)) stop("Both `x` and `type` cannot be NULL at the same time.") type <- tolower(type) diff --git a/R/mow.r b/R/mow.r index ae666043..b11bd96e 100644 --- a/R/mow.r +++ b/R/mow.r @@ -1,33 +1,37 @@ #' Remove unused rasters and vectors from the GRASS cache #' -#' @description **fasterRaster** attempts to remove intermediate rasters and vectors from the **GRASS** cache as they are not needed, but files can still accumulate, especially if you remove `GRaster`s or `GVector`s from the **R** working environment (e.g., by using [rm()] or simply using the same variable name for different rasters/vectors). This function will a) search the **GRASS** cache for all rasters/vectors there; and b) remove any of them that are not pointed to by an object in the active **R** environment. +#' @description **fasterRaster** attempts to delete rasters and vectors in the **GRASS** cache. This function will a) search the current **GRASS** "project/location" cache for all rasters/vectors there; and b) remove any of them that are not pointed to by an object in the active **R** environment. Only objects in the currently active **GRASS** project/location will be removed (see `vignette("project_mapset", package = "fasterRaster")`). #' -#' Note that calling this function inside another function's environment can be very dangerous, as it will only be able to see objects in that environment, and thus delete any rasters/vectors outside that environment. -#' -#' Note also that this function will only clean the current **GRASS** "project"/"location" (see `vignette("projects_mapsets", package = "fasterRaster")`). +#' Note that calling this function inside another function's environment without providing an argument for `x` can be very **dangerous**, as it will detect objects outside that environment, and thus delete any rasters/vectors outside that environment. #' #' @param x Either missing (default) or an environment. #' #' @param type Either `NULL` or a character vector. If `NULL`, all rasters and vectors in the **GRASS** cache are candidates for deletion. Otherwise, this can be either `"raster"`, `"vector"`, or both. #' +#' @param keep Either `NULL` (default) or a `list()` of `GRaster`s and/or `GVector`s that you want to retain. The rasters and vectors in **GRASS** pointed to by these objects will not be deleted. +#' #' @param verbose Logical: If `TRUE` (default), report progress. #' #' @param ask Logical: If `TRUE` (default), prompt for reassurance. #' #' @returns Invisibly returns a list with the number of rasters and vectors deleted. #' -#' @seealso Option `clean` in [faster()] +#' @seealso Option `clean` in [faster()]; [grass()] #' #' @example man/examples/ex_mow.r #' #' @aliases mow #' @rdname mow #' @export mow -mow <- function(x, type = NULL, verbose = TRUE, ask = TRUE) { +mow <- function(x, type = NULL, keep = NULL, verbose = TRUE, ask = TRUE) { if (ask) { - response <- readline("Are you sure you want to clean the GRASS cache? (y/n) ") - if (response != "y") return(invisible(list(rasters = 0, vectors = 0))) + response <- readline("Are you sure you want to clean the GRASS cache? (Y/n) ") + if (response != "Y") return(invisible(list(rasters = 0, vectors = 0))) + } + + if (!is.null(keep)) { + if (!is.list(keep)) stop("Argument `keeps` must be a list or NULL.") } if (missing(x)) { @@ -57,6 +61,12 @@ mow <- function(x, type = NULL, verbose = TRUE, ask = TRUE) { } # next object in environment + if (!is.null(GSpatials)) { + for (i in seq_along(keep)) { + GSpatials <- GSpatials[!(GSpatials$rObject %in% keep[[i]])] + } + } + if (nrow(GSpatials) == 0L) return(invisible(list(rasters = 0, vectors = 0))) # see what's in GRASS @@ -72,7 +82,7 @@ mow <- function(x, type = NULL, verbose = TRUE, ask = TRUE) { if ("raster" %in% type & "raster" %in% names(grassObjs)) { toDelete <- grassObjs[names(grassObjs) == "raster"] - if (verbose) omnibus::say("Deleting ", length(toDelete), " rasters from the GRASS cache...") + if (verbose) omnibus::say("Deleting ", length(toDelete), " raster(s) from the GRASS cache...") .rm(toDelete, type = "raster", warn = TRUE, verify = FALSE) out$rasters <- out$rasters + length(toDelete) @@ -81,7 +91,7 @@ mow <- function(x, type = NULL, verbose = TRUE, ask = TRUE) { if ("vector" %in% type & "vector" %in% names(grassObjs)) { toDelete <- grassObjs[names(grassObjs) == "vector"] - if (verbose) omnibus::say("Deleting ", length(toDelete), " vectors from the GRASS cache...") + if (verbose) omnibus::say("Deleting ", length(toDelete), " vector(s) from the GRASS cache...") .rm(toDelete, type = "vector", warn = TRUE, verify = FALSE) out$vectors <- out$vectors + length(toDelete) diff --git a/R/nacell.r b/R/nacell.r index 6b2bf68f..99acb037 100644 --- a/R/nacell.r +++ b/R/nacell.r @@ -75,6 +75,7 @@ methods::setMethod( intern = TRUE ) + # Should be GRASS eight point three! if (grassInfo("versionNumber") >= 8.3) args$nprocs <- faster("cores") info <- do.call(rgrass::execGRASS, args = args) diff --git a/R/predict.r b/R/predict.r index 07b9f93a..6726eba1 100644 --- a/R/predict.r +++ b/R/predict.r @@ -6,7 +6,7 @@ #' #' This `predict()` function can handle: #' * Linear predictors and intercepts like `y ~ 1 + x`; -#' * Quadratic terms like `y ~ x^2` (or, in **R** formular notation, `y ~ I(x^2)`); +#' * Quadratic terms like `y ~ x^2` (or, in **R** formula notation, `y ~ I(x^2)`); #' * Two-way interaction terms between scalars like `y ~ x1:x2` and `y ~ x1 * x2`; #' * Categorical predictors (i.e., categorical `GRaster`s; see `vignette("GRasters", package = "fasterRaster")`)); #' * Two-way interactions between a categorical predictor and a scalar predictor; and diff --git a/R/pca.r b/R/princomp.r similarity index 90% rename from R/pca.r rename to R/princomp.r index bcf0612f..a51486f4 100644 --- a/R/pca.r +++ b/R/princomp.r @@ -10,15 +10,15 @@ #' #' @returns A multi-layer `GRaster` with one layer per principal component axis. The [pcs()] function can be used on the output raster to retrieve a `prcomp` object from the raster, which includes rotations (loadings) and proportions of variance explained. #' -#' @seealso [stats::prcomp()]; module `i.pca` in **GRASS** +#' @seealso [terra::princomp()], [terra::prcomp()] #' -#' @example man/examples/ex_pca.r +#' @example man/examples/ex_princomp.r #' -#' @aliases pca -#' @rdname pca -#' @exportMethod pca +#' @aliases princomp +#' @rdname princomp +#' @exportMethod princomp methods::setMethod( - f = "pca", + f = "princomp", signature = c(x = "GRaster"), function(x, scale = TRUE, scores = FALSE) { @@ -121,13 +121,13 @@ methods::setMethod( #' Retrieve a principal components model from a PCA GRaster #' -#' @param x A `GRaster` created by [pca()] +#' @param x A `GRaster` created by [princomp()] #' #' @returns An object of class `prcomp`. #' -#' @seealso [pca()], [stats::prcomp()], module `i.pca` in **GRASS** +#' @seealso [princomp()], [terra::princomp()], module `i.pca` in **GRASS** #' -#' @example man/examples/ex_pca.r +#' @example man/examples/ex_princomp.r #' #' @aliases pcs #' @rdname pcs diff --git a/R/project.r b/R/project.r index 18862531..06b13d78 100644 --- a/R/project.r +++ b/R/project.r @@ -120,7 +120,9 @@ methods::setMethod( # .message(msg = "project_raster", message = "This function can produce erroneous results if the raster crosses a pole or the international date line.") # imperfect catch for cases where `wrap` should be `TRUE` but is not - if (.projection(x) %in% c("WGS84", "NAD83", "NAD27") & !wrap) { + unproj <- .projection(x) %in% + c("Latitude-Longitude", "WGS84", "WGS 84", "NAD83", "NAD 83", "NAD27", "NAD 27") + if (unproj & !wrap) { extent <- ext(x, vector = TRUE) if ((extent[1L] == -180 & extent[2L] == 180) | (extent[3L] == -90 & extent[4L] == 90)) warning("This GRaster seems to wrap around the globe to meet at the international\n date line and/or the poles. Should `wrap` be `TRUE`?") @@ -339,10 +341,8 @@ methods::setMethod( # .regionRespectsDims(x = x, y = y, align = align) # "center" method of determining cell resolution - } else if (res == "center") { - + } else if (res == "center") { .regionResCenterMethod(x = x, y = y, align = align) - } } @@ -362,7 +362,6 @@ methods::setMethod( args <- list( cmd = "r.proj", - location = .location(x), mapset = .mapset(x), input = sources(x)[i], output = srcs[i], @@ -370,6 +369,7 @@ methods::setMethod( memory = faster("memory"), flags = c(.quiet(), "overwrite") ) + args <- .addLocationProject(args, .location(x)) if (wrap) args$flags <- c(args$flags, "n") @@ -409,14 +409,16 @@ methods::setMethod( ) { # imperfect catch for cases where `wrap` should be `TRUE` but is not - if (.projection(x) %in% c("WGS84", "NAD83", "NAD27") & !wrap) { + unproj <- .projection(x) %in% + c("Latitude-Longitude", "WGS84", "WGS 84", "NAD83", "NAD 83", "NAD27", "NAD 27") + if (unproj & !wrap) { extent <- ext(x, vector = TRUE) if ( (extent[1L] == -180 & extent[2L] == 180) | (extent[3L] == -90 & extent[4L] == 90) | (extent[1L] > 0 & extent[2L] < 0) | - (extent[3L] > extent[4L]) + (extent[3L] > extent[4L]) | (extent[4L] < extent[3L]) ) warning("This GVector seems to span the international date line and/or poles. Should `wrap` be `TRUE`?") @@ -443,15 +445,16 @@ methods::setMethod( args <- list( cmd = "v.proj", - location = .location(x), dbase = faster("workDir"), mapset = .mapset(x), input = sources(x), output = src, flags = c(.quiet(), "overwrite") - ) + ) + args <- .addLocationProject(args, .location(x)) + if (wrap) args$flags <- c(args$flags, "w") # if crosses international date line - if (geomtype(x, grass = TRUE) == "point") args$flags <- c(args$flags, "b") # disable topology build for points + # if (geomtype(x, grass = TRUE) == "point") args$flags <- c(args$flags, "b") # disable topology build for points do.call(rgrass::execGRASS, args = args) out <- .makeGVector(src, table = x@table) diff --git a/R/rasterize.r b/R/rasterize.r index 80ea9ce0..92cdf001 100644 --- a/R/rasterize.r +++ b/R/rasterize.r @@ -16,7 +16,7 @@ #' #' @returns A `GRaster`. #' -#' @seealso [terra::rasterize()], module [`v.to.rast`](https://grass.osgeo.org/grass84/manuals/v.to.rast.html) in **GRASS** +#' @seealso [terra::rasterize()], **GRASS** module `v.to.rast` (see `grassHelp("v.to.rast")`) #' #' @example man/examples/ex_rasterize.r #' @@ -66,7 +66,7 @@ methods::setMethod( nBys <- length(bys) src <- rep(NA_character_, nBys) levels <- list() - if (verbose & nBys > 1L) pb <- utils::txtProgressBar(min = 0, max = nBys, initial = 0, style = 3) + if (verbose & nBys > 1L) pb <- utils::txtProgressBar(min = 0, max = nBys, initial = 0, style = 3, width = 30) for (i in seq_len(nBys)) { @@ -78,7 +78,7 @@ methods::setMethod( index <- which(x@table[[by]] == bys[i]) xx <- x[index] - thisOut <- .rasterize(xx, y, field = field, background = background, by = NULL, verbose = FALSE) + thisOut <- .rasterize(xx, y, gtype = gtype, field = field, background = background, by = NULL, verbose = FALSE) src[i] <- thisOut$src levels[[i]] <- thisOut$levels diff --git a/R/region.r b/R/region.r index a5c062d9..489db362 100644 --- a/R/region.r +++ b/R/region.r @@ -314,10 +314,10 @@ methods::setMethod( if (!is.null(trim)) { trimToTopo <- topology(trim) - if (any(!(topo %in% trimToTopo))) stop("Topology of ", sQuote("trim"), " does not match topology of ", sQuote("x"), ".") + if (any(!(topo %in% trimToTopo))) stop("Topology of `trim` does not match topology of `x`.") trim <- sources(trim) - if (length(trim) != 1L) stop("Argument ", sQuote("trim"), " can have only one layer.") + if (length(trim) != 1L) stop("Argument `trim` can have only one layer.") } diff --git a/R/regress.r b/R/regress.r new file mode 100644 index 00000000..d6f14e77 --- /dev/null +++ b/R/regress.r @@ -0,0 +1,49 @@ +#' Regression intercept, slope, r2, and t-value across each set of cells +#' +#' @description This function performs a regression on each set of cells in a multi-layered `GRaster`. The output is a `GRaster` with the intercept, slope, r^2 value, and Student's t value. The regression formula is as `y ~ 1 + x`, where `x` is the layer number of each layer (e.g., 1 for the first or top layer in the input `GRaster`, 2 for the second or second-to-top layer, etc.). Note that this is restricted version of the functionality in [terra::regress()]. +#' +#' @param y A multi-layer `GRaster`. +#' +#' @param x Ignored. +#' +#' @param na.rm Logical: If `FALSE`, any series of cells with `NA` in at least one cell results in an `NA` in the output. +#' +#' @returns A multi-layer `GRaster`. +#' +#' @seealso [terra::regress()] +#' +#' @example man/examples/ex_GRaster_arithmetic_across_layers.r +#' +#' @aliases regress +#' @rdname regress +#' @exportMethod regress +methods::setMethod( + f = "regress", + signature = c(y = "GRaster", x = "missing"), + function(y, x, na.rm = FALSE) { + + if (nlyr(y) < 2) stop("The `GRaster` must have >1 layer.") + + .locationRestore(y) + .region(y) + + fx <- "offset" + fxName <- "intercept" + intercept <- .genericMultiLayer(fx = fx, fxName = fxName, x = y, na.rm = na.rm) + + fx <- "slope" + fxName <- "slope" + slope <- .genericMultiLayer(fx = fx, fxName = fxName, x = y, na.rm = na.rm) + + fx <- "detcoeff" + fxName <- "r2" + r2 <- .genericMultiLayer(fx = fx, fxName = fxName, x = y, na.rm = na.rm) + + fx <- "tvalue" + fxName <- "tvalue" + tvalue <- .genericMultiLayer(fx = fx, fxName = fxName, x = y, na.rm = na.rm) + + c(intercept, slope, r2, tvalue) + + } # EOF +) diff --git a/R/replaceNAs.r b/R/replaceNAs.r index f07f1222..16af5830 100644 --- a/R/replaceNAs.r +++ b/R/replaceNAs.r @@ -20,7 +20,7 @@ methods::setMethod( signature = c(x = "data.frame"), function(x, replace, cols = NULL) { - if (length(replace) != 1L) stop("Argument ", sQuote("replace"), " must be a single value.") + if (length(replace) != 1L) stop("Argument `replace` must be a single value.") if (is.null(cols)) cols <- seq_len(ncol(x)) @@ -49,7 +49,7 @@ methods::setMethod( signature = c(x = "matrix"), function(x, replace, cols = NULL) { - if (length(replace) != 1L) stop("Argument ", sQuote("replace"), " must be a single value.") + if (length(replace) != 1L) stop("Argument `replace` must be a single value.") if (is.null(cols)) cols <- seq_len(ncol(x)) @@ -78,7 +78,7 @@ methods::setMethod( signature = c(x = "data.table"), function(x, replace, cols = NULL) { - if (length(replace) != 1L) stop("Argument ", sQuote("replace"), " must be a single value.") + if (length(replace) != 1L) stop("Argument `replace` must be a single value.") if (is.null(cols)) cols <- seq_len(ncol(x)) @@ -151,7 +151,7 @@ methods::setMethod( #' @noRd .replaceNAsAtomic <- function(x, replace) { - if (length(replace) != 1L) stop("Argument ", sQuote("replace"), " must be a single value.") + if (length(replace) != 1L) stop("Argument `replace` must be a single value.") x[is.na(x)] <- replace x diff --git a/R/replace_single_square_bracket.r b/R/replace_single_square_bracket.r index 4faac3a3..0e1b04c8 100644 --- a/R/replace_single_square_bracket.r +++ b/R/replace_single_square_bracket.r @@ -1,6 +1,6 @@ #' Replace values of a GRaster #' -#' @description The `[<-` operator can be used to replace all of the values of a `GRaster`, or specific values depending on the expression in `i`. For example, you could use `rast[] <- 10` to assign 10 to all cells, or `rast[rast > 0] <- 10` to assign all cells with values >0 to 10. +#' @description The `[<-` operator can be used to replace all of the values of a `GRaster`, or specific values depending on the expression in `i`. For example, you could use `rast[] <- 10` to assign 10 to all cells, or `rast[rast > 0] <- 10` to assign all cells with values >0 to 10. You can also use one raster to set values in another, as in `rast1[rast2 > 0] <- 10`. #' #' @param x A `GRaster`. #' @param i Either missing or a conditional statement that resolves to a `GRaster`. diff --git a/R/res.r b/R/res.r index cfd7c484..2979e8ae 100644 --- a/R/res.r +++ b/R/res.r @@ -2,7 +2,7 @@ #' #' @description Spatial resolution of a `GRaster`: #' * `res()`: 2-dimensional resolution (x and y).\cr\cr -#' * `res3d()`: 3-dimensinal resolution (z, y, and z).\cr\cr +#' * `res3d()`: 3-dimensional resolution (z, y, and z).\cr\cr #' * `xres()`, `yres()`, and `zres()`: East-west resolution, north-south resolution, and top-bottom resolution. #' #' @param x A `GRaster`, `GRegion`, or missing. If missing, the resolution of the currently active "region" is returned (see `vignette("regions", package = "fasterRaster")`). @@ -16,6 +16,7 @@ #' @aliases res #' @rdname res #' @exportMethod res +#' @keywords res setMethod( f = "res", signature = "missing", diff --git a/R/resample.r b/R/resample.r index b9260e9e..4b604d19 100644 --- a/R/resample.r +++ b/R/resample.r @@ -18,7 +18,7 @@ #' #' @returns A `GRaster`. #' -#' @seealso [terra::resample()], modules [`r.resample`](https://grass.osgeo.org/grass84/manuals/r.resample.html) and [`r.resamp.interp`](https://grass.osgeo.org/grass84/manuals/r.resamp.interp.html) in **GRASS** +#' @seealso [terra::resample()], **GRASS** modules `r.resample` and `r.resamp.interp` (see `grassHelp("`r.resample`") and `grassHelp("`r.resamp.interp`")`) #' #' @example man/examples/ex_resample.r #' @@ -165,7 +165,7 @@ methods::setMethod( memory = faster("memory"), flags = c(.quiet(), "overwrite") ) - if (versionNumber >= 8.3) args$nprocs <- faster("cores") + if (versionNumber >= 8.4) args$nprocs <- faster("cores") do.call(rgrass::execGRASS, args = args) } @@ -181,6 +181,7 @@ methods::setMethod( memory = faster("memory"), flags = c(.quiet(), "overwrite") ) + # nprocs became available with GRASS eight point three if (versionNumber >= 8.3) args$nprocs <- faster("cores") do.call(rgrass::execGRASS, args = args) @@ -197,6 +198,7 @@ methods::setMethod( memory = faster("memory"), flags = c(.quiet(), "overwrite") ) + # nprocs became available with GRASS eight point three if (versionNumber > 8.3) args$nprocs <- faster("cores") do.call(rgrass::execGRASS, args = args) diff --git a/R/rnormRast.r b/R/rnormRast.r index 598be641..fc5f1b6a 100644 --- a/R/rnormRast.r +++ b/R/rnormRast.r @@ -28,7 +28,7 @@ methods::setMethod( sigma = 1, seed = NULL) { - if (!is.null(seed)) if (length(seed) != n) stop("You must provide one value of ", sQuote("seed"), " per raster, or set it to NULL.") + if (!is.null(seed)) if (length(seed) != n) stop("You must provide one value of `seed` per raster, or set it to NULL.") mu <- rep(mu, length.out = n) sigma <- rep(sigma, length.out = n) diff --git a/R/runifRast.r b/R/runifRast.r index fe5b089d..16b2e84e 100644 --- a/R/runifRast.r +++ b/R/runifRast.r @@ -30,7 +30,7 @@ methods::setMethod( seed = NULL ) { - if (!is.null(seed)) if (length(seed) != n) stop("You must provide one value of ", sQuote("seed"), " per raster, or set it to NULL.") + if (!is.null(seed)) if (length(seed) != n) stop("You must provide one value of `seed` per raster, or set it to NULL.") .locationRestore(x) .region(x) diff --git a/R/segregate.r b/R/segregate.r new file mode 100644 index 00000000..7b6f6f46 --- /dev/null +++ b/R/segregate.r @@ -0,0 +1,86 @@ +#' Create one GRaster layer per unique value in a GRaster +#' +#' @description This function creates a multi-layered `GRaster` for every unique values in an input `GRaster`. By default, the output will have a value of 1 wherever the input has the given value, and 0 elsewhere. This is useful for creating dummy variable `GRaster` layers for use with models that have factors, especially if the input `GRaster` is categorical. Note that the [predict()] function in **fasterRaster** usually does not need this treatment of `GRaster`s since it can handle categorical rasters already. +#' +#' @param x A `GRaster`. +#' +#' @param classes Either `NULL` (default) or a character vector with category labels for which to create outputs. If the input is not a categorical/factor or `integer` `GRaster`, this is ignored. +#' +#' @param keep Logical: If `FALSE` (default), then the original value in the input `GRaster` will be retained in the each of the output `GRaster` layers wherever the input had the respective value. Other cells will be assigned a value of `other`. +#' +#' @param other Numeric or `NA`: Value to assign to cells that do not have the target value. +#' +#' @param bins Numeric: Number of bins in which to put values. This is only used for `GRaster`s that are not categorical/factor rasters or `integer` rasters. +#' +#' @param digits Numeric: Number of digits to which to round input if it is a `numeric` or `double` `GRaster` (see `vignettes("GRasters", package = "fasterRaster")`). +#' +#' @returns If the input `x` is a single-layered `GRaster`, the output will be a multi-layered `GRaster` with one layer per value in the input, or one layer per values in `classes`. If the input is a multi-layered `GRaster`, the output will be a `list` of multi-layered `GRaster`s. +#' +#' @example man/examples/ex_segregate.r +#' +#' @seealso [terra::segregate()] +#' +#' @aliases segregate +#' @rdname segregate +#' @exportMethod segregate +methods::setMethod( + f = "segregate", + signature = c(x = "GRaster"), + function(x, classes = NULL, keep = FALSE, other = 0, bins = 100, digits = 3) { + + .locationRestore(x) + .region(x) + + if (!is.null(classes) & (all(is.factor(x)) | all(is.integer(x)))) x <- x[x %in% classes] + if (is.na(other)) other <- "null()" + + out <- list() + nLayers <- nlyr(x) + for (i in seq_len(nLayers)) { + + # unique values + dtype <- datatype(x, type = "GRASS")[i] + freqs <- freq(x[[i]], digits = digits, bins = bins) + freqs <- freqs[count > 0] + vals <- freqs$value + + nVals <- length(vals) + if (nVals == 0) { + thisOut <- NA + } else { + + thisSrcs <- .makeSourceName("segregate", "raster", nVals) + for (j in seq_len(nVals)) { + + if (keep) { + thisKeep <- vals[j] + } else { + thisKeep <- 1 + } + ex <- paste0(thisSrcs[j], " = if(", sources(x)[i], " == ", vals[j], ", ", thisKeep, ", ", other, ")") + rgrass::execGRASS("r.mapcalc", expression = ex, flags = c(.quiet(), "overwrite")) + + } + + names <- if (is.factor(x)[i]) { + freqs[[3]] + } else { + as.character(vals) + } + thisOut <- .makeGRaster(thisSrcs, names = names) + + } + + out[[i]] <- thisOut + + } + + if (nLayers == 1L) { + out <- out[[1L]] + } else { + names(out) <- names(x) + } + out + + } # EOF +) diff --git a/R/selectRange.r b/R/selectRange.r index f64a0a36..be531298 100644 --- a/R/selectRange.r +++ b/R/selectRange.r @@ -22,7 +22,7 @@ methods::setMethod( .region(x) if (nlyr(y) > 1L) { - warning("The ", sQuote("y"), " raster has more than one layer. On the first will be used.") + warning("The`y` raster has more than one layer. On the first will be used.") y <- y[[1L]] } if (datatype(y, "GRASS") != "CELL") y <- round(y) diff --git a/R/simplifyGeom.r b/R/simplifyGeom.r index 55b0077f..ddb045eb 100644 --- a/R/simplifyGeom.r +++ b/R/simplifyGeom.r @@ -31,13 +31,18 @@ methods::setMethod( # automatic distance if (is.null(tolerance)) { - extent <- ext(x, vector=TRUE) + extent <- ext(x, vector = TRUE) xext <- extent[2L] - extent[1L] yext <- extent[4L] - extent[3L] - zext <- diff(zext) - tolerance <- 0.02 * min(xext, yext, zext, na.rm=TRUE) + if (is.3d(x)) { + zext <- zext(x) + zext <- diff(zext) + } else { + zext <- NULL + } + tolerance <- 0.02 * min(xext, yext, zext, na.rm = TRUE) } else { - if (tolerance < 0) stop("Argument ", sQuote("tolerance"), " must be > 0.") + if (tolerance < 0) stop("Argument `tolerance` must be > 0.") } @@ -55,7 +60,7 @@ methods::setMethod( "reumann" } - if (method == "reumann" && (prop < 0 | prop > 1)) stop("Argument ", sQuote("prop"), " must be in the range [0, 1].") + if (method == "reumann" && (prop < 0 | prop > 1)) stop("Argument `prop` must be in the range [0, 1].") src <- .makeSourceName("generalized", "vect") args <- list( diff --git a/R/smoothGeom.r b/R/smoothGeom.r index 0f9824ce..fe719377 100644 --- a/R/smoothGeom.r +++ b/R/smoothGeom.r @@ -35,7 +35,7 @@ methods::setMethod( zext <- diff(zext) dist <- 0.02 * min(xext, yext, zext, na.rm=TRUE) } else { - if (dist < 0) stop("Argument ", sQuote("dist"), " must be > 0.") + if (dist < 0) stop("Argument `dist` must be > 0.") } .locationRestore(x) @@ -43,7 +43,7 @@ methods::setMethod( method <- tolower(method) method <- omnibus::pmatchSafe(method, c("hermite", "chaiken")) - if (method == "hermite" && angle < 0) stop("Argument ", sQuote("angle"), " must be >0.") + if (method == "hermite" && angle < 0) stop("Argument `angle` must be >0.") src <- .makeSourceName("generalized", "vect") args <- list( diff --git a/R/streams.r b/R/streams.r index 795c5299..939f5423 100644 --- a/R/streams.r +++ b/R/streams.r @@ -1,6 +1,6 @@ #' Create stream network #' -#' @description This function estimates the course of streams and rivers from an elevation raster. It is based on the **GRASS** module `\href{https://grass.osgeo.org/grass84/manuals/r.stream.extract.html}{r.stream.extract}`, where more details can be found. +#' @description This function estimates the course of streams and rivers from an elevation raster. It is based on the **GRASS** module `r.stream.extract`, where more details can be found (see `grassHelp("r.stream.extract")`) #' #' @param x A `GRaster` representing elevation. #' @@ -20,7 +20,7 @@ #' #' @example man/examples/ex_streams.r #' -#' @seealso [flow()], [flowPath()], the `\href{https://grass.osgeo.org/grass84/manuals/r.stream.extract.html}{r.stream.extract}` module in **GRASS** +#' @seealso [flow()], [flowPath()], **GRASS** module `r.stream.extract` (see `grassHelp("r.stream.extract")`) #' #' @aliases streams #' @rdname streams diff --git a/R/stretch.r b/R/stretch.r index fdad6054..2e361107 100644 --- a/R/stretch.r +++ b/R/stretch.r @@ -1,4 +1,4 @@ -#' Rescale values in a raster +#' Rescale values in a GRaster #' #' @description `stretch()` rescales the values in a `GRaster`. All values can be rescaled, or just values in a user-defined range. This range can be given by specifying either the lower and upper bounds of the range using `smin` and `smax`, and/or by the quantiles (across all cells of the raster) using `minq` and `maxq`. #' @@ -67,6 +67,7 @@ methods::setMethod( percentile = minq * 100 ) + # nprocs became available with GRASS eight point three if (versionNumber >= 8.3) args$nprocs <- faster("cores") info <- do.call(rgrass::execGRASS, args) @@ -98,6 +99,7 @@ methods::setMethod( percentile = maxq * 100 ) + # nprocs became available with GRASS eight point three if (versionNumber >= 8.3) args$nprocs <- faster("cores") info <- do.call(rgrass::execGRASS, args) diff --git a/R/subset.r b/R/subset.r new file mode 100644 index 00000000..f1b2c578 --- /dev/null +++ b/R/subset.r @@ -0,0 +1,50 @@ +#' Subset layers from a GRaster, or specific rows from a GVector +#' +#' @description `subset()` can be used to subset or remove one or more layers from a `GRaster`. It can also be used to subset or remove rows from a `GVector` with a data table. +#' +#' @param x A `GRaster` or `GVector`. +#' +#' @param subset Numeric integer, integer, logical, or character: Indicates the layer(s) of a `GRaster` to subset, or the rows(s) of a `GVector` to return. +#' +#' @param negate Logical: If `TRUE`, all layers or rows in `subset` will be *removed* from the output. Default is `FALSE`. +#' +#' @returns A `GRaster` or `GVector`. +#' +#' @seealso \code{\link[fasterRaster]{[[}}, \code{\link[fasterRaster]{[}} +#' +#' @example man/examples/ex_GRaster_GVector_subset_assign.r +#' +#' @aliases subset +#' @docType methods +#' @rdname subset +#' @exportMethod subset +methods::setMethod( + "subset", + signature = c(x = "GRaster"), + function(x, subset, negate = FALSE) { + + # test indices + subset <- .layerIndex(subset, x, recycle = TRUE, negate = negate) + x[[subset]] + + } # EOF +) + +#' @aliases subset +#' @rdname subset +#' @exportMethod subset +methods::setMethod( + "subset", + signature = c(x = "GVector"), + function(x, subset, negate = FALSE) { + + # turn subset into integer + if (is.logical(subset)) { + if (length(subset) < nr) subset <- rep(subset, length.out = nr) + subset <- which(subset) + } + if (negate) subset <- seq_len(nr)[-subset] + x[subset] + + } # EOF +) diff --git a/R/subset_dollar.r b/R/subset_dollar.r index 59306886..bd591339 100644 --- a/R/subset_dollar.r +++ b/R/subset_dollar.r @@ -8,7 +8,7 @@ #' #' @example man/examples/ex_GRaster_GVector_subset_assign.r #' -#' @seealso \code{\link[fasterRaster]{[}}, \code{\link[fasterRaster]{[[}} +#' @seealso [subset()], \code{\link[fasterRaster]{[}}, \code{\link[fasterRaster]{[[}} #' #' @name $ #' @aliases $,GRaster-method diff --git a/R/subset_double_square_brackets.r b/R/subset_double_square_brackets.r index 61051cb5..4a85947b 100644 --- a/R/subset_double_square_brackets.r +++ b/R/subset_double_square_brackets.r @@ -10,6 +10,8 @@ #' #' @returns A `GRaster` or `GVector`. #' +#' @seealso [subset()] +#' #' @example man/examples/ex_GRaster_GVector_subset_assign.r #' #' @name [[ diff --git a/R/subset_single_bracket.r b/R/subset_single_bracket.r index 4c55fa74..40177da2 100644 --- a/R/subset_single_bracket.r +++ b/R/subset_single_bracket.r @@ -14,7 +14,7 @@ #' #' @example man/examples/ex_GRaster_GVector_subset_assign.r #' -#' @seealso [$], \code{\link[fasterRaster]{[[}} +#' @seealso [subset()], [$], \code{\link[fasterRaster]{[[}} #' #' @name [ #' @aliases [,GVector,ANY,ANY-method @@ -336,7 +336,7 @@ methods::setMethod( rgrass::execGRASS("r.mapcalc", expression = ex, flags = c(.quiet(), "overwrite")) } - .makeGRaster(srcs, names(x)) + .makeGRaster(srcs, names(x), levels = cats(x), ac = activeCats(x)) } # EOF ) diff --git a/R/sun.r b/R/sun.r index c51b0874..d5c7e1e4 100644 --- a/R/sun.r +++ b/R/sun.r @@ -1,6 +1,6 @@ #' Solar radiance and irradiance #' -#' The `sun()` function calculates beam (direct), diffuse and ground reflected solar irradiation for a given day and set of topographic and atmospheric conditions. The function relies on the **GRASS** module [`r.sun`](https://grass.osgeo.org/grass84/manuals/r.sun.html), which contains a detailed explanation. +#' The `sun()` function calculates beam (direct), diffuse and ground reflected solar irradiation for a given day and set of topographic and atmospheric conditions. The function relies on the **GRASS** module `r.sun`, the manual page for which contains a detailed explanation (see `grassHelp("r.sun")`) #' #' @param elevation A `GRaster` with values representing elevation (typically in meters). #' @@ -18,7 +18,7 @@ #' #' @param albedo A `GRaster` or a numeric value: This is either a raster with values of ground albedo or a numeric value (in which case albedo is assumed to be the same everywhere). Albedo is unit-less, and the default value is 0.2. #' -#' @param linke A `GRaster` or a numeric value: This is either a raster with values of the Linke atmospheric turbidity coefficient or a numeric value (in which case the same value is assumed for all locations). The Linke coefficient is unit-less. The default value is 3, but see also the **GRASS** manual page for module [`r.sun`](https://grass.osgeo.org/grass84/manuals/r.sun.html). +#' @param linke A `GRaster` or a numeric value: This is either a raster with values of the Linke atmospheric turbidity coefficient or a numeric value (in which case the same value is assumed for all locations). The Linke coefficient is unit-less. The default value is 3, but see also the **GRASS** manual page for module `r.sun` (`grassHelp("r.sun")`). #' #' @param day Positive integer between 1 to 365, inclusive: Day of year for which to calculate ir/radiation. Default is 1 (January 1st). #' @@ -51,7 +51,7 @@ #' * `glob_rad`: Global radiation (Watt-hours/m2/day) #' * `insol_time`: Insolation duration (hours) #' -#' @seealso [terrain()], [horizonHeight()], module [`r.sun`](https://grass.osgeo.org/grass84/manuals/r.sun.html) in **GRASS** +#' @seealso [terrain()], [horizonHeight()], **GRASS** module `r.sun`(see `grassHelp("r.sun")`) #' #' @example man/examples/ex_sun.r #' diff --git a/R/trim.r b/R/trim.r index 7b8625c4..358fa97b 100644 --- a/R/trim.r +++ b/R/trim.r @@ -22,7 +22,7 @@ methods::setMethod( signature = c(x = "GRaster"), function(x, pad = 0) { - if (pad < 0) stop("Argument ", sQuote("pad"), " must be >= 0.") + if (pad < 0) stop("Argument `pad` must be >= 0.") .locationRestore(x) .region(x) diff --git a/R/vAttachDatabase.r b/R/vAttachDatabase.r index 04b0b855..92e6b759 100644 --- a/R/vAttachDatabase.r +++ b/R/vAttachDatabase.r @@ -1,13 +1,13 @@ #' Add a database table to a GRASS attribute table #' -#' @description `.vAttachDatabase()` adds a table to a **GRASS** vector. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the `GVector` slot `@table``. Some functions require tables (e.g., [extract()] and [spatSample()]). **This function is mostly of use to developers.** +#' @description `.vAttachDatabase()` adds a table to a **GRASS** vector. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the `GVector` slot `@table`. Some functions require tables (e.g., [extract()] and [spatSample()]). **This function is mostly of use to developers.** #' #' @param x A `GVector` or the name of a vector in **GRASS**. #' #' @param table Either `NULL` (default), or a `data.frame` or `data.table`, or a numeric or integer vector: -#' * If `NULL`, then a bare minimal table will be created with a column named `frid`, holding sequential integer values. -#' * If a `data.frame` or `data.table` and no column is named `frid`, one will be created with sequential integer values. If the table does have a column named `frid`, then it should have integer (not just numeric) values. -#' * If a `vector`, then these are coerced to type `integer` and used to define the `frid` column. +#' * If `NULL`, then a bare minimal table will be created with a column named `cat`, holding sequential integer values. +#' * If a `data.frame` or `data.table` and no column is named `cat`, one will be created with sequential integer values. If the table does have a column named `cat`, then it should have integer (not just numeric) values. +#' * If a `vector`, then these are coerced to type `integer` and used to define the `cat` column. #' #' There should be one row/value per geometry in `x`. #' @@ -44,7 +44,7 @@ } # if table does not have a "cat" column - if (!any(names(table) %in% "cat")) { + if (!any("cat" %in% names(table))) { if (is.null(cats)) cats <- .vCats(src, db = FALSE, integer = TRUE) catsRenum <- omnibus::renumSeq(cats) @@ -107,16 +107,21 @@ } # connect database to vector - rgrass::execGRASS( + args <- list( cmd = "v.db.connect", map = sources(x), table = srcTable, layer = "1", # key = "frid", key = "cat_", # adds an underscore, for some reason - flags = c(.quiet(), "overwrite", "o") + # flags = c(.quiet(), "overwrite", "o") + flags = c(.quiet(), "overwrite") ) + if (grassInfo("versionNumber") <= 8.3) args$flags <- c(args$flags, "o") + + do.call(rgrass::execGRASS, args = args) + # args <- list( # cmd = "v.db.addtable", # map = src, diff --git a/R/vDetachDatabase.r b/R/vDetachDatabase.r index f1924aff..fdeda1ef 100644 --- a/R/vDetachDatabase.r +++ b/R/vDetachDatabase.r @@ -1,6 +1,6 @@ #' Add a database table to a GRASS attribute table #' -#' @description `.vDetachDatabase()` detaches the database from a **GRASS** vector and deletes it. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the `GVector` slot `@table``. Some functions do require tables (e.g., [extract()] and [spatSample()]). **This function is mostly of use to developers.** +#' @description `.vDetachDatabase()` detaches the database from a **GRASS** vector and deletes it. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the `GVector` slot `@table`. Some functions do require tables (e.g., [extract()] and [spatSample()]). **This function is mostly of use to developers.** #' #' @param x A `GVector` or the name of a vector in **GRASS**. #' diff --git a/R/vHasDatabase.r b/R/vHasDatabase.r index a98fbf4a..b60b6afe 100644 --- a/R/vHasDatabase.r +++ b/R/vHasDatabase.r @@ -27,6 +27,12 @@ intern = TRUE ) - length(info) > 0L + if (length(info) < 1L) { + FALSE + } else if (length(info) > 1L) { + any(grepl(info, pattern = "is connected by")) + } else { + !grepl(info, pattern = "is not connected to a database") + } } diff --git a/R/vegIndex.r b/R/vegIndex.r index 3e655ff1..0d08637c 100644 --- a/R/vegIndex.r +++ b/R/vegIndex.r @@ -51,11 +51,11 @@ methods::setMethod( if (is.null(bits)) { - if (any(mm > 1)) stop("Raster values should be between 0 and 1 if ", sQuote("bits"), " is NULL.") + if (any(mm > 1)) stop("Raster values should be between 0 and 1 if `bits` is NULL.") } else { - if (!all(is.int(x))) stop("If argument ", sQuote("bits"), " is defined, then rasters must be of type ", sQuote("integer"), ".") + if (!all(is.int(x))) stop("If argument `bits` is defined, then rasters must be of type `integer`.") maxVal <- 2^bits if (any(mm > maxVal)) stop("Maximum value for ", bits, " bits is ", maxVal, ".\n At least one raster surpasses this.") diff --git a/R/wetness.r b/R/wetness.r index d9d32be4..14d05249 100644 --- a/R/wetness.r +++ b/R/wetness.r @@ -6,7 +6,7 @@ #' #' @returns A `GRaster`. #' -#' @seealso [terrain()], [ruggedness()], [geomorphons()], module [`r.topidx`](https://grass.osgeo.org/grass84/manuals/r.topidx.html) in **GRASS** +#' @seealso [terrain()], [ruggedness()], [geomorphons()], **GRASS** module `r.topidx` (see `grassHelp("r.topidx")`) #' #' @example man/examples/ex_ruggedness_wetness.r #' diff --git a/R/workDir.r b/R/workDir.r index b70669af..2b791f64 100644 --- a/R/workDir.r +++ b/R/workDir.r @@ -6,11 +6,12 @@ #' #' @returns Character. #' -#' @aliases workDir +#' @aliases .workDir #' @rdname workDir -#' @exportMethod workDir +#' @exportMethod .workDir +#' @keywords internal methods::setMethod( - f = "workDir", + f = ".workDir", signature = c(x = "GLocation"), function(x) x@workDir ) diff --git a/R/writeRaster.r b/R/writeRaster.r index 04482558..e3f26ff6 100644 --- a/R/writeRaster.r +++ b/R/writeRaster.r @@ -3,7 +3,7 @@ #' @description #' This function saves a `GRaster` to disk directly from a **GRASS** session. It is faster than using [rast()], then saving the output of that to disk (because `rast()` actually save the raster to disk, anyway). #' -#' The function will attempt to ascertain the file type to be ascertained from the file extension, but you can specify the format using the `format` argument (see entry for `...`). You can see a list of supported formats by simply using this function with no arguments, as in `writeRaster()`, or by consulting the online help page for the **GRASS** module [`r.out.gdal`](https://grass.osgeo.org/grass84/manuals/r.out.gdal.html). Only the `GeoTIFF` file format is guaranteed to work for multi-layered rasters. +#' The function will attempt to ascertain the file type to be ascertained from the file extension, but you can specify the format using the `format` argument (see entry for `...`). You can see a list of supported formats by simply using this function with no arguments, as in `writeRaster()`, or by consulting the online help page for the **GRASS** module `r.out.gdal` (see `grassHelp("r.out.gdal")`). Only the `GeoTIFF` file format is guaranteed to work for multi-layered rasters. #' #' The function will attempt to optimize the `datatype` argument, but this can take a long time. You can speed this up by setting `datatype` manually. Note that if you are saving a "stack" of `GRaster`s with different `datatype`s, the one with the highest information density will be used (e.g., low-bit integer < high-bit integer < floating-point < double-floating point). This can make rasters with lower datatypes much larger on disk. In these cases, it make be best to save rasters with similar `datatype`s together. #' @@ -51,7 +51,7 @@ #' #' @returns A `GRaster` (invisibly). A raster is also saved to disk. #' -#' @seealso [terra::writeRaster()], module [`r.out.gdal`](https://grass.osgeo.org/grass84/manuals/r.out.gdal.html) in **GRASS** +#' @seealso [terra::writeRaster()], **GRASS** module `r.out.gdal` (see `grassHelp("r.out.gdal")`) #' #' @example man/examples/ex_writeRaster.r #' @@ -112,7 +112,7 @@ setMethod( ### going to overwrite anything? if (!overwrite) { - if (file.exists(filename)) stop("File already exists and ", sQuote("overwrite"), " is FALSE:\n ", filename) + if (file.exists(filename)) stop("File already exists and `overwrite` is FALSE:\n ", filename) } ### format @@ -235,7 +235,7 @@ setMethod( # if (any(!(datatype(x, "GDAL") %in% datatype))) { # flags <- c(flags, "f") - # if (warn) warning("Argument ", sQuote("datatype"), " does not match the data type of the raster. Data may be lost.") + # if (warn) warning("Argument `datatype` does not match the data type of the raster. Data may be lost.") # } if (!("createopt" %in% names(dots))) createopt <- NULL diff --git a/R/writeVector.r b/R/writeVector.r index 5b70bdc6..c735c276 100644 --- a/R/writeVector.r +++ b/R/writeVector.r @@ -2,7 +2,7 @@ #' #' @description This function saves a `GVector` to disk directly from a **GRASS** session. #' -#' By default, files will be of OGC GeoPackage format (extension "`.gpkg`"), but this can be changed with the `format` argument. You can see a list of supported formats by simply using this function with no arguments, as in `writeVector()`, or by consulting the online help page for **GRASS** module [`v.out.ogr`](https://grass.osgeo.org/grass84/manuals/v.out.ogr.html). +#' By default, files will be of OGC GeoPackage format (extension "`.gpkg`"), but this can be changed with the `format` argument. You can see a list of supported formats by simply using this function with no arguments, as in `writeVector()`, or by consulting the online help page for **GRASS** module `v.out.ogr` (see `grassHelp("v.out.ogr")`). #' #' Note that if the vector has a data table attached and at least one numeric or integer column has an `NA` or `NaN` value, the function will yield a warning like: #' ``` @@ -27,11 +27,11 @@ #' #' @param attachTable Logical: If `TRUE` (default), attach the attribute to table to the vector before saving it. If `FALSE`, the attribute table will not be attached. #' -#' @param ... Additional arguments to send to **GRASS** module [`v.out.ogr`](https://grass.osgeo.org/grass84/manuals/v.out.ogr.html) in **GRASS**. +#' @param ... Additional arguments to send to **GRASS** module `v.out.ogr` (see `grassHelp("v.out.ogr")`). #' #' @returns Invisibly returns a `GRaster` (the input, `x`). Also saves the vector to disk. #' -#' @seealso [terra::writeVector()], [sf::st_write()], module [`v.out.ogr`](https://grass.osgeo.org/grass84/manuals/v.out.ogr.html) in **GRASS** +#' @seealso [terra::writeVector()], [sf::st_write()], **GRASS** module `v.out.ogr` (see `grassHelp("v.out.ogr")`) #' #' @example man/examples/ex_writeVector.r #' @@ -53,7 +53,7 @@ setMethod( ) { ### going to overwrite anything? - if (!overwrite && file.exists(filename)) stop(paste0("File already exists and ", sQuote("overwrite"), " is FALSE:\n ", filename)) + if (!overwrite && file.exists(filename)) stop(paste0("File already exists and `overwrite` is FALSE:\n ", filename)) .locationRestore(x) diff --git a/R/xor.r b/R/xor.r index b8d8a2ab..0a4c3d5f 100644 --- a/R/xor.r +++ b/R/xor.r @@ -1,12 +1,12 @@ #' Select parts of polygons not shared between two GVectors #' -#' @description The `xor()` function selects the area that does not overlap between two "polygon" `GVector`s. You can also use the `/` operator, as in `vect 1 / vect2`. +#' @description The `xor()` function selects the area that does *not* overlap between two "polygon" `GVector`s. You can also use the `/` operator, as in `vect1 / vect2`. #' #' @param x,y `GVector`s. #' #' @returns A `GVector`. #' -#' @seealso [c()], [aggregate()], [crop()], [intersect()], [union()], [erase()] +#' @seealso [crop()], [intersect()], [union()], [erase()] #' #' @example man/examples/ex_union_intersect_xor_erase.r #' diff --git a/_pkgdown.yml b/_pkgdown.yml index f0d5ca92..53320789 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -26,3 +26,389 @@ articles: - projects_mapsets - regions - hidden_functions + +reference: +- title: Where to start +- desc: The most commonly-used functions. +- contents: + - faster + - fast + - rast + - vect + - st_as_sf + - writeRaster + - writeVector +- title: GRaster properties +- contents: + - crs + - datatype + - dim + - dim3d + - E + - ext + - freq + - is.2d + - is.3d + - is.cell + - is.doub + - is.factor + - is.float + - is.int + - is.lonlat + - levels + - minmax + - 'N' + - names + - ncol + - nacell + - ncell + - ncell3d + - ndepth + - nlyr + - nonnacell + - nrow + - nlevels + - res + - res3d + - S + - sources + - topology + - xres + - yres + - zext + - zres +- title: Math, comparison, and logic +- contents: + - Arith + - Compare-methods + - Logic-methods +- title: Math layer-by-layer on GRasters +- contents: + - abs + - acos + - asin + - atan + - atan2 + - ceiling + - cos + - exp + - floor + - is.na + - log + - ln + - log1p + - log2 + - log10 + - maskNA + - not.na + - round + - sin + - sqrt + - tan + - trunc +- title: Math across GRaster layers +- contents: + - allNA + - anyNA + - count + - kurtosis + - max + - mean + - median + - min + - mmode + - nunique + - quantile + - range + - skewness + - stdev + - sum + - var + - varpop + - which.max + - which.min +- title: Subsetting and replacing GRasters +- contents: + - "`$`" + - "`$<-`" + - "`[`" + - "`[<-`" + - "`[[<-`" + - add<- + - subset +- title: Operations on GRasters +- contents: + - "`%in%`" + - "`%notin%`" + - as.doub + - as.int + - as.float + - as.lines + - as.points + - as.polygons + - aggregate + - bioclims + - buffer + - app + - c + - cellSize + - classify + - clump + - combineLevels + - concats + - crop + - denoise + - distance + - extend + - extract + - fillNAs + - focal + - fragmentation + - global + - hist + - interpIDW + - kernel + - layerCor + - mask + - maskNA + - match + - merge + - names<- + - noise + - pairs + - pcs + - plot + - plotRGB + - princomp + - project + - predict + - regress + - resample + - reorient + - sampleRast + - segregate + - stretch + - scale + - scalepop + - selectRange + - spatSample + - subst + - thinLines + - tiles + - trim + - unscale + - zonal + - zonalGeog +- title: Creating GRasters *de novo* +- contents: + - fractalRast + - init + - longlat + - rnormRast + - rSpatialDepRast + - runifRast + - sineRast +- title: Terrain and hydrology +- contents: + - as.contour + - flow + - flowPath + - geomorphons + - hillshade + - horizonHeight + - sun + - ruggedness + - streams + - terrain + - wetness +- title: Categorical GRasters +- contents: + - "`%in%`" + - "`%notin%`" + - activeCat + - activeCat<- + - activeCats + - addCats + - addCats<- + - categories + - catNames + - cats + - combineLevels + - complete.cases + - concats + - droplevels + - freq + - is.factor + - levels + - levels<- + - match + - minmax + - missing.cases + - missingCats + - nlevels + - segregate + - subst + - zonalGeog +- title: Remote sensing GRasters +- contents: + - compositeRGB + - plotRGB + - vegIndex +- titles: SpatRasters +- contents: + - bioclims + - fragmentation +- title: GVectors Properties +- contents: + - bottom + - crs + - datatype + - dim + - E + - expanse + - ext + - geomtype + - is.2d + - is.3d + - is.lines + - is.lonlat + - is.points + - is.polygons + - 'N' + - names + - ncol + - ngeom + - nrow + - nsubgeom + - S + - sources + - top + - topology + - W + - zext +- title: Subsetting and assignment of GVectors +- contents: + - "`$`" + - "`$<-`" + - "`[`" + - "`[[`" + - addTable<- + - dropTable + - subset +- title: Operations on GVectors +- contents: + - aggregate + - as.data.frame + - as.data.table + - as.points + - buffer + - clusterPoints + - colbind + - complete.cases + - connectors + - convHull + - crds + - crop + - delaunay + - disagg + - distance + - dropTable + - erase + - expanse + - extract + - grid + - head + - hexagons + - interpIDW + - interpSplines + - intersect + - kernel + - missing.cases + - names<- + - project + - rasterize + - rbind + - simplifyGeom + - smoothGeom + - st_as_sf + - st_buffer + - tail + - thinPoints + - union + - voronoi + - xor +- title: Creating GVectors *de novo* +- contents: + - rvoronoi +- title: Fixing GVector issues +- contents: + - breakPolys + - fillHoles + - fixBridges + - fixDangles + - fixLines + - remove0 + - removeAngles + - removeBridges + - removeDangles + - removeDupCentroids + - removeDups + - removeSmallPolys + - snap +- title: Converting between data types +- contents: + - as.contour + - as.doub + - as.data.frame + - as.data.table + - as.float + - as.int + - as.lines + - as.points + - as.polygons + - categories + - fast + - levels<- + - rast + - rasterize + - st_as_sf + - vect +- title: General functions +- contents: + - compareGeom + - dropRows + - grassGUI + - grassHelp + - grassInfo + - grassStarted + - mow + - replaceNAs + - seqToSQL + - update +- title: Example data +- contents: + - appFunsTable + - fastData + - madChelsa + - madCoast + - madCoast0 + - madCoast4 + - madCover + - madCoverCats + - madDypsis + - madElev + - madForest2000 + - madForest2014 + - madLANDSAT + - madPpt + - madTmax + - madTmin + - madRivers + - vegIndices +- title: Classes +- contents: + - GLocation + - GSpatial + - GRegion + - GRaster + - GVector diff --git a/articles/reference/figures/dist_to_rivers.png b/articles/reference/figures/dist_to_rivers.png new file mode 100644 index 00000000..76fd527c Binary files /dev/null and b/articles/reference/figures/dist_to_rivers.png differ diff --git a/articles/reference/figures/elev_rivers.png b/articles/reference/figures/elev_rivers.png new file mode 100644 index 00000000..ccdc4166 Binary files /dev/null and b/articles/reference/figures/elev_rivers.png differ diff --git a/data/appFunsTable.rda b/data/appFunsTable.rda index 20012f62..d9e80eca 100644 Binary files a/data/appFunsTable.rda and b/data/appFunsTable.rda differ diff --git a/fasterRaster_workspace.code-workspace b/fasterRaster_workspace.code-workspace index 355f765a..b0fa78d9 100644 --- a/fasterRaster_workspace.code-workspace +++ b/fasterRaster_workspace.code-workspace @@ -15,7 +15,14 @@ "statusBarItem.hoverBackground": "#2f7c47", "statusBarItem.remoteBackground": "#215732", "titleBar.activeBackground": "#215732", - "titleBar.inactiveBackground": "#21573299" + "titleBar.inactiveBackground": "#21573299", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "commandCenter.border": "#e7e7e799", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveForeground": "#e7e7e799" }, "peacock.color": "#215732" } diff --git a/inst/CITATION b/inst/CITATION index daeecbaa..d0e1bf82 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -4,7 +4,6 @@ note <- sprintf("R package version %s", meta$Version) doi <- "NA" title <- paste0(meta$Package, ": ", meta$Title) - citHeader("To cite fasterRaster in publications use:") bibentry(bibtype = "Manual", key = key, @@ -16,4 +15,3 @@ bibentry(bibtype = "Manual", note = note, doi = doi ) - diff --git a/inst/pkgdown.yml b/inst/pkgdown.yml index ea3ea398..d40e95d8 100644 --- a/inst/pkgdown.yml +++ b/inst/pkgdown.yml @@ -1,5 +1,5 @@ pandoc: 3.1.11 -pkgdown: 2.0.9 +pkgdown: 2.1.1 pkgdown_sha: ~ articles: faster_fasterRaster: faster_fasterRaster.html @@ -8,8 +8,7 @@ articles: hidden_functions: hidden_functions.html projects_mapsets: projects_mapsets.html regions: regions.html -last_built: 2024-09-20T03:06Z +last_built: 2024-10-07T14:52Z urls: reference: https://github.com/adamlilith/fasterRaster/reference article: https://github.com/adamlilith/fasterRaster/articles - diff --git a/junk b/junk deleted file mode 100644 index 84450a8c..00000000 --- a/junk +++ /dev/null @@ -1,4 +0,0 @@ -GISDBASE: C:/Users/adame/AppData/Local/Temp/Rtmpy6OsE5 -LOCATION_NAME: Tananarive_Paris_Laborde_Grid_gFHKwds00HtL -MAPSET: PERMANENT -GRASS_GUI: text diff --git a/man/Arithmetic.Rd b/man/Arithmetic.Rd index 95faaa19..988d3d5d 100644 --- a/man/Arithmetic.Rd +++ b/man/Arithmetic.Rd @@ -141,67 +141,5 @@ floor(elev + 0.5) ceiling(elev + 0.5) trunc(elev + 0.5) -# comparison -elev < 100 -elev <= 100 -elev == 100 -elev != 100 -elev > 100 -elev >= 100 - -elev + 100 < 2 * elev - -elevs > 10 -10 > elevs - -# logic -elev < 10 | elev > 200 -elev < 10 | cos(elev) > 0.9 - -elev < 10 | TRUE -TRUE | elev > 200 - -elev < 10 | FALSE -FALSE | elev > 200 - -elev < 10 & cos(elev) > 0.9 - -elev < 10 & TRUE -TRUE & elev > 200 - -elev < 10 & FALSE -FALSE & elev > 200 - -# Mathematical functions on GRasters with >= 2 layers: -mean(elevs) -mmode(elevs) -median(elevs) -nunique(elevs) - -sum(elevs) -count(elevs) -min(elevs) -max(elevs) -range(elevs) -skewness(elevs) -kurtosis(elevs) - -which.min(elevs) -which.max(elevs) - -slope(elevs) -intercept(elevs) -r2(elevs) -tvalue(elevs) - -stdev(elevs) -stdev(elevs, pop = FALSE) -var(elevs) -varpop(elevs) - -# Note: To get quantiles for each layer, use -# global(x, "quantile", probs = 0.2). -quantile(elevs, 0.1) - } } diff --git a/man/Compare-methods.Rd b/man/Compare-methods.Rd index 5e8b34ea..54388c05 100644 --- a/man/Compare-methods.Rd +++ b/man/Compare-methods.Rd @@ -55,7 +55,6 @@ You can also compare two \code{GRegion}s using the \code{==} and \code{!=} opera if (grassStarted()) { # Setup -library(sf) library(terra) # Example data @@ -69,87 +68,7 @@ names(elevs) <- c("elev1", "elev2", "log_elev", "sqrt_elev") elev elevs -# do some math -elev + 100 -elev - 100 -elev * 100 -elev / 100 -elev ^ 2 -elev \%/\% 100 # divide then round down -elev \%\% 100 # modulus - -100 + elev -100 \%/\% elev -100 \%\% elev - -elevs + 100 -100 + elevs - -# math with logicals -elev + TRUE -elev - TRUE -elev * TRUE -elev / TRUE -elev ^ TRUE -elev \%/\% TRUE # divide then round down -elev \%\% TRUE # modulus - -elevs + TRUE -TRUE + elevs - -# Raster interacting with raster(s): -elev + elev -elev - elev -elev * elev -elev / elev -elev ^ log(elev) -elev \%/\% sqrt(elev) # divide then round down -elev \%\% sqrt(elev) # modulus - -elevs + elev -elev * elevs - -# sign -abs(-1 * elev) -abs(elevs) - -# powers -sqrt(elevs) - -# trigonometry -sin(elev) -cos(elev) -tan(elev) - -asin(elev) -acos(elev) -atan(elev) - -atan(elevs) -atan2(elev, elev^1.2) -atan2(elevs, elev^1.2) -atan2(elev, elevs^1.2) -atan2(elevs, elevs^1.2) - -# logarithms -exp(elev) -log(elev) -ln(elev) -log2(elev) -log1p(elev) -log10(elev) -log10p(elev) -log(elev, 3) - -log(elevs) - -# rounding -round(elev + 0.5) -floor(elev + 0.5) -ceiling(elev + 0.5) -trunc(elev + 0.5) - -# comparison +# Comparisons elev < 100 elev <= 100 elev == 100 @@ -180,36 +99,5 @@ TRUE & elev > 200 elev < 10 & FALSE FALSE & elev > 200 -# Mathematical functions on GRasters with >= 2 layers: -mean(elevs) -mmode(elevs) -median(elevs) -nunique(elevs) - -sum(elevs) -count(elevs) -min(elevs) -max(elevs) -range(elevs) -skewness(elevs) -kurtosis(elevs) - -which.min(elevs) -which.max(elevs) - -slope(elevs) -intercept(elevs) -r2(elevs) -tvalue(elevs) - -stdev(elevs) -stdev(elevs, pop = FALSE) -var(elevs) -varpop(elevs) - -# Note: To get quantiles for each layer, use -# global(x, "quantile", probs = 0.2). -quantile(elevs, 0.1) - } } diff --git a/man/Logic-methods.Rd b/man/Logic-methods.Rd index 584218f4..371381b8 100644 --- a/man/Logic-methods.Rd +++ b/man/Logic-methods.Rd @@ -32,7 +32,7 @@ A binary \code{GRaster} (1 ==> \code{TRUE}, 0 ==> \code{FALSE}, plus \code{NA} when comparison results in \code{NA}). } \description{ -You can do logical operations on \code{GRaster}s. Here, a value of 1 is interpreted as \code{TRUE}, and a value of 0 is interpreted as \code{FALSE}. You can compare: +You can do logical operations on \code{GRaster}s. A cell with a value of 1 is interpreted as \code{TRUE}, and a value of 0 is interpreted as \code{FALSE}. You can compare: \itemize{ \item A \code{GRaster} to another \code{GRaster} \item A \code{GRaster} to a logical value (\code{TRUE} or \code{FALSE}, but not \code{NA}--see \code{\link[=not.na]{not.na()}}) @@ -49,7 +49,6 @@ Operators include: if (grassStarted()) { # Setup -library(sf) library(terra) # Example data @@ -63,87 +62,7 @@ names(elevs) <- c("elev1", "elev2", "log_elev", "sqrt_elev") elev elevs -# do some math -elev + 100 -elev - 100 -elev * 100 -elev / 100 -elev ^ 2 -elev \%/\% 100 # divide then round down -elev \%\% 100 # modulus - -100 + elev -100 \%/\% elev -100 \%\% elev - -elevs + 100 -100 + elevs - -# math with logicals -elev + TRUE -elev - TRUE -elev * TRUE -elev / TRUE -elev ^ TRUE -elev \%/\% TRUE # divide then round down -elev \%\% TRUE # modulus - -elevs + TRUE -TRUE + elevs - -# Raster interacting with raster(s): -elev + elev -elev - elev -elev * elev -elev / elev -elev ^ log(elev) -elev \%/\% sqrt(elev) # divide then round down -elev \%\% sqrt(elev) # modulus - -elevs + elev -elev * elevs - -# sign -abs(-1 * elev) -abs(elevs) - -# powers -sqrt(elevs) - -# trigonometry -sin(elev) -cos(elev) -tan(elev) - -asin(elev) -acos(elev) -atan(elev) - -atan(elevs) -atan2(elev, elev^1.2) -atan2(elevs, elev^1.2) -atan2(elev, elevs^1.2) -atan2(elevs, elevs^1.2) - -# logarithms -exp(elev) -log(elev) -ln(elev) -log2(elev) -log1p(elev) -log10(elev) -log10p(elev) -log(elev, 3) - -log(elevs) - -# rounding -round(elev + 0.5) -floor(elev + 0.5) -ceiling(elev + 0.5) -trunc(elev + 0.5) - -# comparison +# Comparisons elev < 100 elev <= 100 elev == 100 @@ -174,36 +93,5 @@ TRUE & elev > 200 elev < 10 & FALSE FALSE & elev > 200 -# Mathematical functions on GRasters with >= 2 layers: -mean(elevs) -mmode(elevs) -median(elevs) -nunique(elevs) - -sum(elevs) -count(elevs) -min(elevs) -max(elevs) -range(elevs) -skewness(elevs) -kurtosis(elevs) - -which.min(elevs) -which.max(elevs) - -slope(elevs) -intercept(elevs) -r2(elevs) -tvalue(elevs) - -stdev(elevs) -stdev(elevs, pop = FALSE) -var(elevs) -varpop(elevs) - -# Note: To get quantiles for each layer, use -# global(x, "quantile", probs = 0.2). -quantile(elevs, 0.1) - } } diff --git a/man/activeCat.Rd b/man/activeCat.Rd index a1b3b498..6cb4014e 100644 --- a/man/activeCat.Rd +++ b/man/activeCat.Rd @@ -152,12 +152,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/add.Rd b/man/add.Rd index a5013c13..f30e5b70 100644 --- a/man/add.Rd +++ b/man/add.Rd @@ -63,7 +63,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 diff --git a/man/addCats.Rd b/man/addCats.Rd index 57cc3376..5e5ddf8a 100644 --- a/man/addCats.Rd +++ b/man/addCats.Rd @@ -145,12 +145,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/aggregate.Rd b/man/aggregate.Rd index 8feb72d2..823a588e 100644 --- a/man/aggregate.Rd +++ b/man/aggregate.Rd @@ -15,7 +15,7 @@ na.rm = FALSE ) -\S4method{aggregate}{GVector}(x, dissolve = TRUE) +\S4method{aggregate}{GVector}(x) } \arguments{ \item{x}{A \code{GRaster} or \code{GVector}.} @@ -45,8 +45,6 @@ Note that unlike \code{terra::aggregate()} and \code{\link[terra:disaggregate]{t \item{prob}{Numeric (rasters only): Quantile at which to calculate \code{quantile}.} \item{na.rm}{Logical (rasters only): If \code{FALSE} (default), propagate \code{NA} cells or \code{NA} values.} - -\item{dissolve}{Logical (vectors only): If \code{TRUE} (default), then aggregated geometries will have their borders dissolved. This is ignored if the input \code{GVector} is not a "polygons" vector.} } \value{ A \code{GRaster} or \code{GVector}. @@ -77,15 +75,13 @@ elev <- fast(madElev) agg2 <- aggregate(elev, 2, "mean") agg2 -# terra -agg2terra <- aggregate(madElev, 2, "mean") -agg2terra - # Compare rasters aggregated by fasterRaster and terra. # These should be the same. +agg2terra <- aggregate(madElev, 2) + agg2 <- rast(agg2) agg2 <- extend(agg2, agg2terra) -agg2 - agg2terra +agg2 - agg2terra # value is ~0 ### Aggregate GRaster by a non-integer factor in 2 dimensions # fasterRaster @@ -112,19 +108,19 @@ agg2x3 madCoast4 <- fastData("madCoast4") # Convert: -coast <- fast(madCoast4) +coast4 <- fast(madCoast4) # Aggregate and disaggregate: -aggCoast <- aggregate(coast) -disaggCoast <- disagg(coast) +aggCoast <- aggregate(coast4) +disaggCoast <- disagg(coast4) -ngeom(coast) +ngeom(coast4) ngeom(aggCoast) ngeom(disaggCoast) # plot oldpar <- par(mfrow = c(1, 3)) -plot(coast, main = "Original", col = 1:nrow(coast)) +plot(coast4, main = "Original", col = 1:nrow(coast4)) plot(aggCoast, main = "Aggregated", col = 1:nrow(aggCoast)) plot(disaggCoast, main = "Disaggregated", col = 1:nrow(disaggCoast)) par(oldpar) diff --git a/man/app.Rd b/man/app.Rd index 466768dd..0c8dce74 100644 --- a/man/app.Rd +++ b/man/app.Rd @@ -1,7 +1,7 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/app.r -\name{app,GRaster-method} -\alias{app,GRaster-method} +\name{app} +\alias{app} \alias{app,lapp} \alias{appFuns} \alias{appCheck,GRaster,character-method} @@ -23,7 +23,7 @@ appFuns(warn = TRUE) \item The \code{\link[=names]{names()}} of the rasters do not match any of the functions in the \code{appFuns(TRUE)} table. Note that \code{x} and \code{y} are forbidden names :( } -The help page for \strong{GRASS} module \href{https://grass.osgeo.org/grass84/manuals/r.mapcalc.html}{\code{r.mapcalc}} will be especially helpful.} +The help page for \strong{GRASS} module \code{r.mapcalc} will be especially helpful. You can see this page using \code{grassHelp("r.mapcalc")}.} \item{datatype}{Character: This ensures that rasters are treated as a certain type before they are operated on. This is useful when using rasters that have all integer values, which \strong{GRASS} can assume represent integers, even if they are not supposed to. In this case, the output of operations on this raster might be an integer if otherwise not corrected. Partial matching is used, and options include: \itemize{ @@ -51,16 +51,16 @@ A \code{GRaster}. \code{appCheck()} tests whether a formula supplied to \code{app()} has any "forbidden" function calls. -The \code{app()} function operates in a manner slightly different from \code{\link[terra:app]{terra::app()}}. The function to be applied \emph{must} be written as a character string. For example, if the raster had layer names "\code{x1}" and "\code{x2}", then the function might be like \code{"= max(sqrt(x1), log(x2))"}. Rasters \strong{cannot} have the same names as functions used in the formula. In this example, the rasters could not be named "max", "sqrt", or "log". +The \code{app()} function operates in a manner somewhat different from \code{\link[terra:app]{terra::app()}}. The function to be applied \emph{must} be written as a character string. For example, if the \code{GRaster} had layer names "\code{x1}" and "\code{x2}", then the function might be like \code{"= max(sqrt(x1), log(x2))"}. Rasters \strong{cannot} have the same names as functions used in the formula. In this example, the rasters could not be named "max", "sqrt", or "log". Note that the name of a \code{GRaster} is given by \code{\link[=names]{names()}}--this can be different from the name of the object in \strong{R}. -The \code{app()} function will automatically check for raster names that appear also to be functions that appear in the formula. However, you can check a formula before running \code{app()} by using the \code{appCheck()} function. You can obtain a list of \code{app()} functions using \code{appFuns()}. Note that these are sometimes different from how they are applied in \strong{R}. +The \code{app()} function will automatically check for \code{GRaster} names that appear also to be functions that appear in the formula. However, you can check a formula before running \code{app()} by using the \code{appCheck()} function. You can obtain a list of \code{app()} functions using \code{appFuns()}. Note that these are sometimes different from how they are applied in \strong{R}. Tips: \itemize{ \item Make sure your \code{GRaster}s have \code{names()}. The function matches on these, not the name of the variable you use in \strong{R} for the \code{GRaster}. -\item In \strong{GRASS}, use \code{null()} instead of \code{NA}, and use \code{isnull()} instead of \code{is.na()}. +\item Use \code{null()} instead of \code{NA}, and use \code{isnull()} instead of \code{is.na()}. \item If you want to calculate values using while ignoring \code{NA} (or \code{null}) values, see the functions that begin with \code{n} (like \code{nmean}). -\item Be mindful of the data type that a function returns. In \strong{GRASS}, these are \code{CELL} (integer), \code{FCELL} (floating point values--precise to about the 7th decimal place), and \code{DCELL} (double-floating point values--precise to about the 15th decimal place). In cases where you want to datatype a raster to be treated like a float or double data type raster, wrap the raster in the \code{float()} or \code{double()} functions to datatype it is treated as such. This is especially useful if the raster might be assumed to be the \code{CELL} type because it only contains integer values. You can get the data type of a raster using \code{\link[=datatype]{datatype()}} with the \code{type} argument set to \code{GRASS}. You can change the data type of a \code{GRaster} using \code{\link[=as.int]{as.int()}}, \code{\link[=as.float]{as.float()}}, and \code{\link[=as.doub]{as.doub()}}. Note that categorical rasters are really \code{CELL} (integer) rasters with an associated "levels" table. You can also change a \code{CELL} raster to a \code{FCELL} raster by adding then subtracting a decimal value, as in \code{x - 0.1 + 0.1}. See \code{vignette("GRasters", package = "fasterRaster")}. +\item Be mindful of the data type that a function returns. In \strong{GRASS}, these are \code{CELL} (integer), \code{FCELL} (floating point values--precise to about the 7th decimal place), and \code{DCELL} (double-floating point values--precise to about the 15th decimal place; commensurate with the \strong{R} \code{numeric} type). In cases where you want a \code{GRaster} to be treated like a float or double type raster, wrap the name of the \code{GRaster} in the \code{float()} or \code{double()} functions. This is especially useful if the \code{GRaster} might be assumed to be the \code{CELL} type because it only contains integer values. You can get the data type of a raster using \code{\link[=datatype]{datatype()}} with the \code{type} argument set to \code{GRASS}. You can change the data type of a \code{GRaster} using \code{\link[=as.int]{as.int()}}, \code{\link[=as.float]{as.float()}}, and \code{\link[=as.doub]{as.doub()}}. Note that categorical rasters are really \code{CELL} (integer) rasters with an associated "levels" table. You can also change a \code{CELL} raster to a \code{FCELL} raster by adding then subtracting a decimal value, as in \code{x - 0.1 + 0.1}. See \code{vignette("GRasters", package = "fasterRaster")}. \item The \code{rand()} function returns integer values by default. If you want non-integer values, use the tricks mentioned above to datatype non-integer values. For example, if you want uniform random values in the range between 0 and 1, use something like \verb{= float(rand(0 + 0.1, 1 + 0.1) - 0.1)}. } } @@ -129,5 +129,5 @@ freq(rand) # cell frequencies } } \seealso{ -\code{\link[terra:app]{terra::app()}}, \code{\link[terra:lapp]{terra::lapp()}}, \code{\link[=subst]{subst()}}, \code{\link[=classify]{classify()}}, and modules \href{https://grass.osgeo.org/grass84/manuals/r.mapcalc.html}{\code{r.mapcalc}} and \code{r.mapcalc.simple} in \strong{GRASS}. +\code{\link[terra:app]{terra::app()}}, \code{\link[terra:lapp]{terra::lapp()}}, \code{\link[=subst]{subst()}}, \code{\link[=classify]{classify()}}, and modules \code{r.mapcalc} in \strong{GRASS} (viewable using \code{grassHelp("r.mapcalc")}) } diff --git a/man/as.contour.Rd b/man/as.contour.Rd index f61de0d1..45776712 100644 --- a/man/as.contour.Rd +++ b/man/as.contour.Rd @@ -32,7 +32,7 @@ elev <- fast(madElev) # Calculate contour lines: conts <- as.contour(elev, nlevels = 10) -plot(madElev) +plot(elev) plot(conts, add = TRUE) } diff --git a/man/as.lines.Rd b/man/as.lines.Rd index ea7a717e..8b2db4de 100644 --- a/man/as.lines.Rd +++ b/man/as.lines.Rd @@ -14,7 +14,7 @@ A \code{GVector}. } \description{ -\code{\link[=as.lines]{as.lines()}} converts a \code{GRaster} to a "lines" \code{GVector}. Before you apply this function, you may need to run \code{\link[=thinLines]{thinLines()}} on the raster to reduce linear features to a single-cell width. You may also need to use \link[=breakPolys]{clean geometry} (especially the "duplicated" and "removeDangles" \code{method}s) afterward to remove duplicated vertices and "dangling" lines. +\code{\link[=as.lines]{as.lines()}} converts a \code{GRaster} to a "lines" \code{GVector}. Before you apply this function, you may need to run \code{\link[=thinLines]{thinLines()}} on the raster to reduce linear features to a single-cell width. You may also need to use \link[=breakPolys]{clean geometry} (especially the \code{\link[=removeDups]{removeDups()}} and \code{\link[=removeDangles]{removeDangles()}}) afterward to remove duplicated vertices and "dangling" lines. } \examples{ if (grassStarted()) { diff --git a/man/bioclims.Rd b/man/bioclims.Rd index 9e54bec3..f67d22e9 100644 --- a/man/bioclims.Rd +++ b/man/bioclims.Rd @@ -43,7 +43,7 @@ \item \code{NULL} (default): Calculate BIOCLIMs 1 through 19 \item \code{"*"}: Calculate all BIOCLIMs this function can calculate. \item \code{"+"}: Calculate BIOCLIMs 41 onward. -\item Any combination of the above (e.g., \code{c(1, 12, "+")}). +\item Any combination of the above except \code{NULL} (e.g., \code{c(1, 12, "+")}). }} \item{sample}{Logical: If \code{TRUE} (default), BIO4 and 15 are calculated with the sample standard deviation. If \code{FALSE}, then the population standard deviation is used.} @@ -60,6 +60,7 @@ A \code{GRaster} with one or more layers. \description{ The BIOCLIM set of bioclimatic variables were created for modeling species' geographic distributions (Booth et al. 2014). This function can create the "standard" 19 set of variables, plus several more from an "extended" set. +"Classic" set of BIOCLIM variables (Booth et al. 2014): The units reported below assume that input rasters are in mm (precipitation) and deg C (temperature), and that each raster represents a month (but other time units are allowed, with corresponding changes to the temporal units assumed below). \itemize{ \item BIO1: Mean annual temperature, calculated using monthly means (deg C) @@ -114,8 +115,6 @@ The variables are defined assuming that the input rasters represent monthly valu BIOCLIMs 41 through 44 are added here to capture the "shoulder" seasons (spring and autumn) important in temperature regions. BIOCLIMs 45 through 48 are also included for consistency. BIOCLIMs 49 through 60 are not bioclimatic variables per se, but useful for assessing the properties of the variables that are defined based on the "-est" month or quarter. - -The numbering of the new BIOCLIMs was begun at 41 because BIOCLIMs 20 through 40 are taken (Kriticos et al. 2014). } \examples{ if (grassStarted()) { @@ -139,7 +138,7 @@ tmax <- fast(madTmax) # Takes longer to run compared to SpatRaster version for small rasters, so # just calculate select BIOCLIMs: -bc <- bioclims(ppt, tmin, tmax, bios = c(1, 5, 6, 12, 15), verbose = TRUE) +bc <- bioclims(ppt, tmin, tmax, bios = c(1, 5, 12)) bc plot(bc) diff --git a/man/breakPolys.Rd b/man/breakPolys.Rd index 13efd3e0..d5a6636f 100644 --- a/man/breakPolys.Rd +++ b/man/breakPolys.Rd @@ -158,5 +158,5 @@ legend("bottom", } } \seealso{ -\code{\link[terra:topology]{terra::topology()}}, \code{\link[=fillHoles]{fillHoles()}}, \emph{Details} section in \code{\link[=fast]{fast()}}, \code{\link[=simplifyGeom]{simplifyGeom()}}, \code{\link[=smoothGeom]{smoothGeom()}} +\code{\link[terra:topology]{terra::topology()}}, \code{\link[=fillHoles]{fillHoles()}}, \code{\link[terra:topology]{terra::removeDupNodes()}}, \emph{Details} section in \code{\link[=fast]{fast()}}, \code{\link[=simplifyGeom]{simplifyGeom()}}, \code{\link[=smoothGeom]{smoothGeom()}} } diff --git a/man/catNames.Rd b/man/catNames.Rd index 85482736..e73af3be 100644 --- a/man/catNames.Rd +++ b/man/catNames.Rd @@ -134,12 +134,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/clusterPoints.Rd b/man/clusterPoints.Rd index 6416ca5b..c2cb56d0 100644 --- a/man/clusterPoints.Rd +++ b/man/clusterPoints.Rd @@ -10,7 +10,7 @@ \arguments{ \item{x}{A "points" \code{GVector}.} -\item{method}{Character: Method used to identify clusters. Explanations of methods are provided in the help page for the \strong{GRASS} module \href{v.cluster}{https://grass.osgeo.org/grass84/manuals/v.cluster.html}. +\item{method}{Character: Method used to identify clusters. Explanations of methods are provided in the help page for the \strong{GRASS} module \code{v.cluster}, available using \code{grassHelp("v.cluster")}. \itemize{ \item \code{"DBSCAN"} (default): Density-Based Spatial Clustering of Applications with Noise. \item \code{"DBSCAN2"}: A modification of DBSCAN. diff --git a/man/combineLevels.Rd b/man/combineLevels.Rd index ad5137f8..9e286585 100644 --- a/man/combineLevels.Rd +++ b/man/combineLevels.Rd @@ -21,7 +21,7 @@ A \code{list} with a "levels" table (a \code{data.frame} or \code{data.table}), \description{ This function creates a single "levels" table from the levels tables of one or more categorical \code{GRaster}s. -The difference between this function and \code{\link[=combineCats]{combineCats()}} is that \code{combineCats()} creates a "combined" \code{GRaster} with a combined levels table, whereas this one just merges the levels tables. +The difference between this function and \code{\link[=concats]{concats()}} is that \code{concats()} creates a "combined" \code{GRaster} with a combined levels table, whereas this one just merges the levels tables. } \examples{ if (grassStarted()) { @@ -136,17 +136,17 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) } } \seealso{ -\code{\link[=combineCats]{combineCats()}}, \code{vignette("GRasters", package = "fasterRaster")} +\code{\link[=concats]{concats()}}, \link[terra:concats]{terra::concats}, \code{vignette("GRasters", package = "fasterRaster")} } diff --git a/man/complete.cases.Rd b/man/complete.cases.Rd index 29c73785..6a64e70d 100644 --- a/man/complete.cases.Rd +++ b/man/complete.cases.Rd @@ -52,8 +52,6 @@ madCover <- fastData("madCover") dypsis <- fast(madDypsis) cover <- fast(madCover) -levels(cover) - ### GVector # Look at the data table: diff --git a/man/compositeRGB.Rd b/man/compositeRGB.Rd index 1a801be7..8f437149 100644 --- a/man/compositeRGB.Rd +++ b/man/compositeRGB.Rd @@ -27,9 +27,6 @@ This function takes as arguments three rasters typically representing red, green \examples{ if (grassStarted()) { -# Setup -library(terra) - # Example data madElev <- fastData("madElev") # elevation raster madLANDSAT <- fastData("madLANDSAT") # multi-layer raster diff --git a/man/combineCats.Rd b/man/concats.Rd similarity index 93% rename from man/combineCats.Rd rename to man/concats.Rd index 4ae90124..bb1197c6 100644 --- a/man/combineCats.Rd +++ b/man/concats.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/combineCats.r -\name{combineCats,GRaster-method} -\alias{combineCats,GRaster-method} -\alias{combineCats} +% Please edit documentation in R/concats.r +\name{concats,GRaster-method} +\alias{concats,GRaster-method} +\alias{concats} \title{Combine values/categories of multiple GRasters into a single GRaster} \usage{ -\S4method{combineCats}{GRaster}(x, ..., na.rm = TRUE) +\S4method{concats}{GRaster}(x, ..., na.rm = TRUE) } \arguments{ \item{x}{A \code{GRaster} with one or more layers, each of which must be have cells that represent integers or categories (factors).} @@ -146,17 +146,17 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) } } \seealso{ -\code{\link[=combineLevels]{combineLevels()}}, \code{vignette("GRasters", package = "fasterRaster")} +\code{\link[=combineLevels]{combineLevels()}}, \code{\link[terra:concats]{terra::concats()}}, \code{vignette("GRasters", package = "fasterRaster")} } diff --git a/man/connectors.Rd b/man/connectors.Rd index 1046b84b..ae368ef8 100644 --- a/man/connectors.Rd +++ b/man/connectors.Rd @@ -13,7 +13,7 @@ \item{minDist, maxDist}{Either \code{NULL} (default) or numeric values: Ignore features separated by less than or greater than these distances.} } \value{ -A \code{GVector}. +A \code{GVector} with a data table that has the length of each connecting line in meters. } \description{ \code{connectors()} creates a lines \code{GVector} which represent the shortest (Great Circle) paths between each feature of one \code{GVector} and the nearest feature of another \code{GVector}. @@ -29,8 +29,8 @@ madRivers <- fastData("madRivers") madDypsis <- fastData("madDypsis") # Convert sf's to GVectors: -rivers <- fast(madRivers) dypsis <- fast(madDypsis) +rivers <- fast(madRivers) ### Connections from each point to nearest river consFromDypsis <- connectors(dypsis, rivers) @@ -49,5 +49,5 @@ plot(consFromRivers, col = "red", add = TRUE) } } \seealso{ -Module \code{v.distance} in \strong{GRASS} +\strong{GRASS} module \code{v.distance} (see \code{grassHelp("v.distance")}). } diff --git a/man/disagg.Rd b/man/disagg.Rd index ddfe8beb..19f6b885 100644 --- a/man/disagg.Rd +++ b/man/disagg.Rd @@ -39,15 +39,13 @@ elev <- fast(madElev) agg2 <- aggregate(elev, 2, "mean") agg2 -# terra -agg2terra <- aggregate(madElev, 2, "mean") -agg2terra - # Compare rasters aggregated by fasterRaster and terra. # These should be the same. +agg2terra <- aggregate(madElev, 2) + agg2 <- rast(agg2) agg2 <- extend(agg2, agg2terra) -agg2 - agg2terra +agg2 - agg2terra # value is ~0 ### Aggregate GRaster by a non-integer factor in 2 dimensions # fasterRaster @@ -74,19 +72,19 @@ agg2x3 madCoast4 <- fastData("madCoast4") # Convert: -coast <- fast(madCoast4) +coast4 <- fast(madCoast4) # Aggregate and disaggregate: -aggCoast <- aggregate(coast) -disaggCoast <- disagg(coast) +aggCoast <- aggregate(coast4) +disaggCoast <- disagg(coast4) -ngeom(coast) +ngeom(coast4) ngeom(aggCoast) ngeom(disaggCoast) # plot oldpar <- par(mfrow = c(1, 3)) -plot(coast, main = "Original", col = 1:nrow(coast)) +plot(coast4, main = "Original", col = 1:nrow(coast4)) plot(aggCoast, main = "Aggregated", col = 1:nrow(aggCoast)) plot(disaggCoast, main = "Disaggregated", col = 1:nrow(disaggCoast)) par(oldpar) diff --git a/man/distance.Rd b/man/distance.Rd index b102536a..beb43c73 100644 --- a/man/distance.Rd +++ b/man/distance.Rd @@ -130,11 +130,11 @@ plot(distTo3) distToVect <- distance(elev, rivers) plot(distToVect) -plot(st_geometry(madRivers), add = TRUE) +plot(rivers, add = TRUE) ### Case 3: GVector vs GVector -plot(st_geometry(madRivers)) -plot(st_geometry(madDypsis), add = TRUE) +plot(rivers) +plot(dypsis, add = TRUE) distToRivers <- distance(dypsis, rivers, unit = "yd") distToPlants <- distance(rivers, dypsis) diff --git a/man/dot-addLocationProject.Rd b/man/dot-addLocationProject.Rd new file mode 100644 index 00000000..f7528881 --- /dev/null +++ b/man/dot-addLocationProject.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/addLocationProject.r +\name{.addLocationProject} +\alias{.addLocationProject} +\title{Add a "project" or "location" argument to an "args" list} +\usage{ +.addLocationProject(args, locProj) +} +\arguments{ +\item{args}{A \code{list} of arguments to be passed to a \strong{GRASS} module.} + +\item{locProj}{Character: The name of the location or project.} +} +\value{ +A \code{list}. +} +\description{ +Unhelpfully, starting with \strong{GRASS} 8.4, what were previously called "locations" and now called "projects." These were supposed to be back-compatible, but are not. This function takes a list of arguments that will be passed to \code{\link[rgrass:execGRASS]{rgrass::execGRASS()}} and adds either a "location" or "project" argument, depending on the version of \strong{GRASS} being used. +} +\keyword{internal} diff --git a/man/dot-backdoor.Rd b/man/dot-backdoor.Rd new file mode 100644 index 00000000..e1982b48 --- /dev/null +++ b/man/dot-backdoor.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/backdoor.r +\name{.backdoor} +\alias{.backdoor} +\title{Setup fasterRaster for ABS} +\usage{ +.backdoor(ver = "84") +} +\arguments{ +\item{ver}{Character: \strong{GRASS}: e.g., "83" or "84".} +} +\value{ +\code{TRUE} (invisibly). +} +\description{ +This is a secret function to be used for faster development of \strong{fasterRaster}. It assume development is on a Windows machine. +} +\keyword{internal} diff --git a/man/dot-layerIndex.Rd b/man/dot-layerIndex.Rd index 6e20e926..76f41931 100644 --- a/man/dot-layerIndex.Rd +++ b/man/dot-layerIndex.Rd @@ -4,7 +4,7 @@ \alias{.layerIndex} \title{Get index of raster layers} \usage{ -.layerIndex(layer, x, recycle = TRUE) +.layerIndex(layer, x, recycle = TRUE, negate = FALSE) } \arguments{ \item{layer}{Integer, numeric, logical, or character: Refers to one or more layers.} @@ -12,6 +12,8 @@ \item{x}{A \code{GRaster}.} \item{recycle}{Logical: If \code{TRUE} (default), and \code{layer} is logical and smaller in number than the number of layers, then recycle the vector of \code{layer}.} + +\item{negate}{Logical: If \code{TRUE}, return indices of all layers \emph{not} identified in \code{layer}.} } \value{ An integer vector. diff --git a/man/droplevels.Rd b/man/droplevels.Rd index cb8dfb94..f4be6b59 100644 --- a/man/droplevels.Rd +++ b/man/droplevels.Rd @@ -133,12 +133,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/examples/ex_GRaster_GVector_subset_assign.r b/man/examples/ex_GRaster_GVector_subset_assign.r index 3c511489..c4232c1c 100644 --- a/man/examples/ex_GRaster_GVector_subset_assign.r +++ b/man/examples/ex_GRaster_GVector_subset_assign.r @@ -43,7 +43,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 diff --git a/man/examples/ex_GRaster_arithmetic_across_layers.r b/man/examples/ex_GRaster_arithmetic_across_layers.r new file mode 100644 index 00000000..a41247a4 --- /dev/null +++ b/man/examples/ex_GRaster_arithmetic_across_layers.r @@ -0,0 +1,60 @@ +if (grassStarted()) { + +# Setup +library(sf) +library(terra) + +# Example data +madChelsa <- fastData("madChelsa") + +# Convert a SpatRaster to a GRaster +chelsa <- fast(madChelsa) +chelsa # 4 layers + +# Central tendency +mean(chelsa) +mmode(chelsa) +median(chelsa) + +# Statistics +nunique(chelsa) +sum(chelsa) +count(chelsa) +min(chelsa) +max(chelsa) +range(chelsa) +skewness(chelsa) +kurtosis(chelsa) + +stdev(chelsa) +stdev(chelsa, pop = FALSE) +var(chelsa) +varpop(chelsa) + +# Which layers have maximum/minimum? +which.min(chelsa) +which.max(chelsa) + +# Regression +# Note the intercept is different for fasterRaster::regress(). +regress(chelsa) +regress(madChelsa, 1:nlyr(madChelsa)) + +# Note: To get quantiles for each layer, use +# global(x, "quantile", probs = 0.2). +quantile(chelsa, 0.1) + +# NAs +madForest2000 <- fastData("madForest2000") +forest2000 <- fast(madForest2000) +forest2000 <- project(forest2000, chelsa, method = "near") + +chelsaForest <- c(chelsa, forest2000) + +nas <- anyNA(chelsaForest) +plot(nas) + +allNas <- allNA(chelsaForest) +plot(allNas) + +} diff --git a/man/examples/ex_GRaster_arithmetic.r b/man/examples/ex_GRaster_arithmetic_by_layer.r similarity index 61% rename from man/examples/ex_GRaster_arithmetic.r rename to man/examples/ex_GRaster_arithmetic_by_layer.r index f555b7d4..b9b538cd 100644 --- a/man/examples/ex_GRaster_arithmetic.r +++ b/man/examples/ex_GRaster_arithmetic_by_layer.r @@ -95,66 +95,4 @@ floor(elev + 0.5) ceiling(elev + 0.5) trunc(elev + 0.5) -# comparison -elev < 100 -elev <= 100 -elev == 100 -elev != 100 -elev > 100 -elev >= 100 - -elev + 100 < 2 * elev - -elevs > 10 -10 > elevs - -# logic -elev < 10 | elev > 200 -elev < 10 | cos(elev) > 0.9 - -elev < 10 | TRUE -TRUE | elev > 200 - -elev < 10 | FALSE -FALSE | elev > 200 - -elev < 10 & cos(elev) > 0.9 - -elev < 10 & TRUE -TRUE & elev > 200 - -elev < 10 & FALSE -FALSE & elev > 200 - -# Mathematical functions on GRasters with >= 2 layers: -mean(elevs) -mmode(elevs) -median(elevs) -nunique(elevs) - -sum(elevs) -count(elevs) -min(elevs) -max(elevs) -range(elevs) -skewness(elevs) -kurtosis(elevs) - -which.min(elevs) -which.max(elevs) - -slope(elevs) -intercept(elevs) -r2(elevs) -tvalue(elevs) - -stdev(elevs) -stdev(elevs, pop = FALSE) -var(elevs) -varpop(elevs) - -# Note: To get quantiles for each layer, use -# global(x, "quantile", probs = 0.2). -quantile(elevs, 0.1) - } diff --git a/man/examples/ex_GRaster_categorical.r b/man/examples/ex_GRaster_categorical.r index 1d57cd9a..8819ea8b 100644 --- a/man/examples/ex_GRaster_categorical.r +++ b/man/examples/ex_GRaster_categorical.r @@ -110,12 +110,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/examples/ex_GRaster_comparison_logic.r b/man/examples/ex_GRaster_comparison_logic.r new file mode 100644 index 00000000..e75fc8f6 --- /dev/null +++ b/man/examples/ex_GRaster_comparison_logic.r @@ -0,0 +1,48 @@ +if (grassStarted()) { + +# Setup +library(terra) + +# Example data +madElev <- fastData("madElev") + +# Convert a SpatRaster to a GRaster +elev <- fast(madElev) +elevs <- c(elev, elev, log10(elev) - 1, sqrt(elev)) +names(elevs) <- c("elev1", "elev2", "log_elev", "sqrt_elev") + +elev +elevs + +# Comparisons +elev < 100 +elev <= 100 +elev == 100 +elev != 100 +elev > 100 +elev >= 100 + +elev + 100 < 2 * elev + +elevs > 10 +10 > elevs + +# logic +elev < 10 | elev > 200 +elev < 10 | cos(elev) > 0.9 + +elev < 10 | TRUE +TRUE | elev > 200 + +elev < 10 | FALSE +FALSE | elev > 200 + +elev < 10 & cos(elev) > 0.9 + +elev < 10 & TRUE +TRUE & elev > 200 + +elev < 10 & FALSE +FALSE & elev > 200 + +} diff --git a/man/examples/ex_aggregate_disagg.r b/man/examples/ex_aggregate_disagg.r index 45243641..25d943bc 100644 --- a/man/examples/ex_aggregate_disagg.r +++ b/man/examples/ex_aggregate_disagg.r @@ -18,15 +18,13 @@ elev <- fast(madElev) agg2 <- aggregate(elev, 2, "mean") agg2 -# terra -agg2terra <- aggregate(madElev, 2, "mean") -agg2terra - # Compare rasters aggregated by fasterRaster and terra. # These should be the same. +agg2terra <- aggregate(madElev, 2) + agg2 <- rast(agg2) agg2 <- extend(agg2, agg2terra) -agg2 - agg2terra +agg2 - agg2terra # value is ~0 ### Aggregate GRaster by a non-integer factor in 2 dimensions # fasterRaster @@ -53,19 +51,19 @@ agg2x3 madCoast4 <- fastData("madCoast4") # Convert: -coast <- fast(madCoast4) +coast4 <- fast(madCoast4) # Aggregate and disaggregate: -aggCoast <- aggregate(coast) -disaggCoast <- disagg(coast) +aggCoast <- aggregate(coast4) +disaggCoast <- disagg(coast4) -ngeom(coast) +ngeom(coast4) ngeom(aggCoast) ngeom(disaggCoast) # plot oldpar <- par(mfrow = c(1, 3)) -plot(coast, main = "Original", col = 1:nrow(coast)) +plot(coast4, main = "Original", col = 1:nrow(coast4)) plot(aggCoast, main = "Aggregated", col = 1:nrow(aggCoast)) plot(disaggCoast, main = "Disaggregated", col = 1:nrow(disaggCoast)) par(oldpar) diff --git a/man/examples/ex_asContour.r b/man/examples/ex_asContour.r index 7f29bdbb..cde4fe95 100644 --- a/man/examples/ex_asContour.r +++ b/man/examples/ex_asContour.r @@ -12,7 +12,7 @@ elev <- fast(madElev) # Calculate contour lines: conts <- as.contour(elev, nlevels = 10) -plot(madElev) +plot(elev) plot(conts, add = TRUE) } diff --git a/man/examples/ex_bioclims.r b/man/examples/ex_bioclims.r index d7022ae6..c8918c69 100644 --- a/man/examples/ex_bioclims.r +++ b/man/examples/ex_bioclims.r @@ -19,7 +19,7 @@ tmax <- fast(madTmax) # Takes longer to run compared to SpatRaster version for small rasters, so # just calculate select BIOCLIMs: -bc <- bioclims(ppt, tmin, tmax, bios = c(1, 5, 6, 12, 15), verbose = TRUE) +bc <- bioclims(ppt, tmin, tmax, bios = c(1, 5, 12)) bc plot(bc) diff --git a/man/examples/ex_complete.cases.r b/man/examples/ex_complete.cases.r index 54d81b78..17c8223e 100644 --- a/man/examples/ex_complete.cases.r +++ b/man/examples/ex_complete.cases.r @@ -12,8 +12,6 @@ madCover <- fastData("madCover") dypsis <- fast(madDypsis) cover <- fast(madCover) -levels(cover) - ### GVector # Look at the data table: diff --git a/man/examples/ex_connectors.r b/man/examples/ex_connectors.r index 220308ac..7bab3954 100644 --- a/man/examples/ex_connectors.r +++ b/man/examples/ex_connectors.r @@ -8,8 +8,8 @@ madRivers <- fastData("madRivers") madDypsis <- fastData("madDypsis") # Convert sf's to GVectors: -rivers <- fast(madRivers) dypsis <- fast(madDypsis) +rivers <- fast(madRivers) ### Connections from each point to nearest river consFromDypsis <- connectors(dypsis, rivers) diff --git a/man/examples/ex_distance.r b/man/examples/ex_distance.r index db71e7fb..bc0b822b 100644 --- a/man/examples/ex_distance.r +++ b/man/examples/ex_distance.r @@ -40,11 +40,11 @@ plot(distTo3) distToVect <- distance(elev, rivers) plot(distToVect) -plot(st_geometry(madRivers), add = TRUE) +plot(rivers, add = TRUE) ### Case 3: GVector vs GVector -plot(st_geometry(madRivers)) -plot(st_geometry(madDypsis), add = TRUE) +plot(rivers) +plot(dypsis, add = TRUE) distToRivers <- distance(dypsis, rivers, unit = "yd") distToPlants <- distance(rivers, dypsis) diff --git a/man/examples/ex_extract.r b/man/examples/ex_extract.r index 41dcec4e..657c5444 100644 --- a/man/examples/ex_extract.r +++ b/man/examples/ex_extract.r @@ -22,9 +22,8 @@ coast <- fast(madCoast4) # polygons vector extract(elev, dypsis, xy = TRUE) # Extract from categorical raster at points: -dypsisWGS84 <- project(dypsis, cover) # Convert to same CRS -categories <- extract(cover, dypsisWGS84) -categoryValues <- extract(cover, dypsisWGS84, cats = FALSE) +categories <- extract(cover, dypsis) +categoryValues <- extract(cover, dypsis, cats = FALSE) categories categoryValues @@ -35,7 +34,7 @@ extract(elev, coast, fun = c("sum", "mean", "countNonNA"), overlap = FALSE) extract(elev, rivers, fun = c("sum", "mean", "countNonNA"), overlap = FALSE) # Extract from a polygons vector at a points vector: -table <- extract(coast, dypsis, xy = TRUE) -head(table) # first 3 are outside polygons vector, next 3 are inside +polysFromPoints <- extract(coast, dypsis, xy = TRUE) +head(polysFromPoints) # first 3 are outside polygons vector, next 3 are inside } diff --git a/man/examples/ex_flowPath.r b/man/examples/ex_flowPath.r index de9e147b..d6699e35 100644 --- a/man/examples/ex_flowPath.r +++ b/man/examples/ex_flowPath.r @@ -14,7 +14,7 @@ ant <- coast4[coast4$NAME_4 == "Antanambe"] elevAnt <- crop(elev, ant) # Create a set of random points to serve as starting points: -starts <- spatSample(elevAnt, 10, as.points = TRUE, seed = 1) +starts <- spatSample(elevAnt, 10, as.points = TRUE, seed = 2) # Remove points in water: starts <- starts[complete.cases(starts)] @@ -23,14 +23,16 @@ starts <- starts[complete.cases(starts)] paths <- flowPath(elevAnt, starts) paths -plot(paths) +plot(elevAnt, legend = FALSE, main = "Flow path for each point") +plot(paths, add = TRUE) plot(starts, pch = 1, add = TRUE) # Calculate flow paths with cell values indicating the number # of cells from each start: seqs <- flowPath(elevAnt, starts, return = "seq") -plot(seqs) +plot(elevAnt, legend = FALSE, main = "Sequentially-numbered flow paths") +plot(seqs, add = TRUE) plot(starts, pch = 1, add = TRUE) # We can convert flow paths to lines: diff --git a/man/examples/ex_global.r b/man/examples/ex_global.r index bb255345..5bddc043 100644 --- a/man/examples/ex_global.r +++ b/man/examples/ex_global.r @@ -9,12 +9,13 @@ madElev <- fastData("madElev") # Convert a SpatRaster to a GRaster: elev <- fast(madElev) +# What functions can we use with global()? +global() + # Calculate global statistics: global(elev, fun = c("mean", "var", "varpop")) global(elev, "quantile", probs = c(0.25, 0.5, 0.75)) global(elev, "*") # calculate all available functions -global() # vector of all functions - } diff --git a/man/examples/ex_grassGUI.r b/man/examples/ex_grassGUI.r new file mode 100644 index 00000000..cfa1aac9 --- /dev/null +++ b/man/examples/ex_grassGUI.r @@ -0,0 +1,7 @@ +if (grassStarted()) { + +# Starting the GRASS GUI and making changes to rasters or vectors can "break" +# the GRasters and GVectors they are associated with in R. +if (interactive() & FALSE) grassGUI() + +} diff --git a/man/examples/ex_grassHelp.r b/man/examples/ex_grassHelp.r new file mode 100644 index 00000000..0015bc1c --- /dev/null +++ b/man/examples/ex_grassHelp.r @@ -0,0 +1,13 @@ +if (grassStarted() & interactive()) { + +# Open help pages for `r.mapcalc` and `r.sun`: +grassHelp("r.mapcalc") +grassHelp("r.sun") + +# Open topics page: +grassHelp("topics") + +# Open index page: +grassHelp("index") + +} diff --git a/man/examples/ex_init.r b/man/examples/ex_init.r new file mode 100644 index 00000000..eff2faa5 --- /dev/null +++ b/man/examples/ex_init.r @@ -0,0 +1,50 @@ +if (grassStarted()) { + +# Setup +library(terra) + +# Elevation raster, rivers vector +madElev <- fastData("madElev") + +# Convert to a GRaster +elev <- fast(madElev) + +# Cell coordinates +init(elev, "x") +init(elev, "y") + +# Cell row or column +init(elev, "row") +init(elev, "col") + +# Chess +elevAgg <- aggregate(elev, 32) # make cells bigger so we can see + +chessOdd <- init(elevAgg, "chess") +chessEven <- init(elevAgg, "chess", odd = FALSE) + +chess <- c(chessOdd, chessEven) +names(chess) <- c("odd", "even") +plot(chess) + +# Chess with user-defined values +elevAgg <- aggregate(elev, 32) # make cells bigger so we can see + +chessOdd13 <- init(elevAgg, "chess", vals = c(0, 13)) +chessEven13 <- init(elevAgg, "chess", odd = FALSE, vals = c(0, 13)) + +chess13 <- c(chessOdd13, chessEven13) +names(chess13) <- c("odd", "even") +plot(chess13) + +# Regular +elevAgg <- aggregate(elev, 32) # make cells bigger so we can see + +regOdd <- init(elevAgg, "regular") +regEven <- init(elevAgg, "regular", odd = FALSE) + +reg <- c(regOdd, regEven) +names(reg) <- c("odd", "even") +plot(reg) + +} diff --git a/man/examples/ex_location_mapset.r b/man/examples/ex_location_mapset.r index c594e38c..d769c42a 100644 --- a/man/examples/ex_location_mapset.r +++ b/man/examples/ex_location_mapset.r @@ -14,32 +14,36 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } diff --git a/man/examples/ex_noise_denoise.r b/man/examples/ex_noise_denoise.r index e696a94e..9e91ecdb 100644 --- a/man/examples/ex_noise_denoise.r +++ b/man/examples/ex_noise_denoise.r @@ -10,7 +10,7 @@ madChelsa <- fastData("madChelsa") chelsa <- fast(madChelsa) # Generate raster with layers representing principal component predictions: -pcRast <- pca(chelsa, scale = TRUE) +pcRast <- princomp(chelsa, scale = TRUE) plot(pcRast) # Get information on the PCA: diff --git a/man/examples/ex_plot.r b/man/examples/ex_plot.r index 796ddef6..71dfb779 100644 --- a/man/examples/ex_plot.r +++ b/man/examples/ex_plot.r @@ -1,8 +1,5 @@ if (grassStarted()) { -# Setup -library(terra) - # Example data madElev <- fastData("madElev") # elevation raster madLANDSAT <- fastData("madLANDSAT") # multi-layer raster diff --git a/man/examples/ex_pca.r b/man/examples/ex_princomp.r similarity index 89% rename from man/examples/ex_pca.r rename to man/examples/ex_princomp.r index e696a94e..9e91ecdb 100644 --- a/man/examples/ex_pca.r +++ b/man/examples/ex_princomp.r @@ -10,7 +10,7 @@ madChelsa <- fastData("madChelsa") chelsa <- fast(madChelsa) # Generate raster with layers representing principal component predictions: -pcRast <- pca(chelsa, scale = TRUE) +pcRast <- princomp(chelsa, scale = TRUE) plot(pcRast) # Get information on the PCA: diff --git a/man/examples/ex_segregate.r b/man/examples/ex_segregate.r new file mode 100644 index 00000000..f414aaa0 --- /dev/null +++ b/man/examples/ex_segregate.r @@ -0,0 +1,26 @@ +if (grassStarted()) { + +# Setup +library(terra) + +# Elevation and land cover raster +madElev <- fastData("madElev") # integer raster +madCover <- fastData("madCover") # categorical raster + +# Convert to GRasters +elev <- fast(madElev) +cover <- fast(madCover) + +# Subset elevation raster to just a few values to make example faster: +elevSubset <- elev[elev <= 3] +segregate(elevSubset) +segregate(elevSubset, keep = TRUE, other = -1) + +# Segregate the factor raster +segregate(cover) + +classes <- c("Grassland with mosaic forest", "Mosaic cropland/vegetation") +seg <- segregate(cover, classes = classes) +plot(seg) + +} diff --git a/man/extract.Rd b/man/extract.Rd index 238dada2..28965862 100644 --- a/man/extract.Rd +++ b/man/extract.Rd @@ -22,7 +22,8 @@ overlap = TRUE, xy = FALSE, cats = TRUE, - verbose = FALSE + verbose = FALSE, + ... ) \S4method{extract}{GRaster,data.frame}(x, y, xy = FALSE, cats = TRUE) @@ -33,13 +34,13 @@ \S4method{extract}{GRaster,numeric}(x, y, xy = FALSE, cats = TRUE) -\S4method{extract}{GVector,GVector}(x, y, xy = FALSE) +\S4method{extract}{GVector,GVector}(x, y, xy = FALSE, verbose = TRUE) -\S4method{extract}{GVector,data.frame}(x, y, xy = FALSE) +\S4method{extract}{GVector,data.frame}(x, y, xy = FALSE, verbose = TRUE) -\S4method{extract}{GVector,data.table}(x, y, xy = FALSE) +\S4method{extract}{GVector,data.table}(x, y, xy = FALSE, verbose = TRUE) -\S4method{extract}{GVector,matrix}(x, y, xy = FALSE) +\S4method{extract}{GVector,matrix}(x, y, xy = FALSE, verbose = TRUE) \S4method{extract}{GVector,numeric}(x, y, xy = FALSE) } @@ -75,7 +76,9 @@ \item{cats}{Logical (extracting from a raster): If \code{TRUE} (default) and \code{x} is a categorical \code{GRaster}, then return the category labels instead of the values.} -\item{verbose}{Logical: If \code{TRUE}, display progress (will only function when extracting from points on a \code{GRaster} when the number of \code{GRaster}s is large).} +\item{verbose}{Logical: If \code{TRUE}, display progress (will only function when extracting from points on a \code{GRaster} when the number of \code{GRaster}s is large, or when extracting using a "points" \code{GVector} with lots of points).} + +\item{...}{Arguments to pass to \code{\link[=project]{project()}}. This is used only if extracting from a \code{GRaster} at locations specified by a \code{GVector}, and they have a different coordinate reference system. In this case, users should specify the \code{wrap} argument to \code{\link[=project]{project()}}.} } \value{ A \code{data.frame} or \code{data.table}. @@ -115,9 +118,8 @@ coast <- fast(madCoast4) # polygons vector extract(elev, dypsis, xy = TRUE) # Extract from categorical raster at points: -dypsisWGS84 <- project(dypsis, cover) # Convert to same CRS -categories <- extract(cover, dypsisWGS84) -categoryValues <- extract(cover, dypsisWGS84, cats = FALSE) +categories <- extract(cover, dypsis) +categoryValues <- extract(cover, dypsis, cats = FALSE) categories categoryValues @@ -128,8 +130,8 @@ extract(elev, coast, fun = c("sum", "mean", "countNonNA"), overlap = FALSE) extract(elev, rivers, fun = c("sum", "mean", "countNonNA"), overlap = FALSE) # Extract from a polygons vector at a points vector: -table <- extract(coast, dypsis, xy = TRUE) -head(table) # first 3 are outside polygons vector, next 3 are inside +polysFromPoints <- extract(coast, dypsis, xy = TRUE) +head(polysFromPoints) # first 3 are outside polygons vector, next 3 are inside } } diff --git a/man/fast.Rd b/man/fast.Rd index baa3dd46..33341c7a 100644 --- a/man/fast.Rd +++ b/man/fast.Rd @@ -49,8 +49,8 @@ snap = NULL, area = NULL, steps = 10, - dropTable = FALSE, resolve = NA, + dropTable = FALSE, verbose = TRUE ) @@ -124,7 +124,7 @@ A \code{GRaster} or \code{GVector}. \description{ \code{fast()} creates a \code{GRaster} or \code{GVector} from 1) a file; 2) from a \code{SpatRaster}, \code{SpatVector}, or \code{sf} vector; or 3) from a numeric vector, \code{matrix}, \code{data.frame}, or \code{data.table}. Behind the scenes, this function will also create a connection to \strong{GRASS} if none has yet been made yet. -\strong{GRASS} supports loading from disk a variety of raster formats (see the \strong{GRASS} manual page for \href{https://grass.osgeo.org/grass84/manuals/r.in.gdal.html}{\code{r.in.gdal}}) and vector formats (\href{https://grass.osgeo.org/grass84/manuals/v.in.ogr.html}{\code{v.in.ogr}}), though not all of them will work with this function. +\strong{GRASS} supports loading from disk a variety of raster formats (see the \strong{GRASS} manual page for \code{r.in.gdal} (see \code{grassHelp("r.in.gdal")}) and vector formats \code{v.in.ogr} (see grassHelp("v.in.ogr")`), though not all of them will work with this function. Note that \code{GVectors} may fail to be created if they contain issues that do not coincide with the topological data model used by \strong{GRASS}. The most common of these is overlapping polygons. See \emph{Details} on how to fix these kinds of issues. @@ -231,5 +231,5 @@ mat <- fast(mat, crs = "epsg:4326", keepgeom = TRUE) # WGS84 } } \seealso{ -\code{\link[rgrass:readRAST]{rgrass::read_RAST()}} and \code{\link[rgrass:readVECT]{rgrass::read_VECT()}}, \link[=breakPolys]{vector cleaning}, \code{\link[=fillHoles]{fillHoles()}}, plus modules \href{https://grass.osgeo.org/grass84/manuals/v.in.ogr.html}{\code{v.in.ogr}} and \href{https://grass.osgeo.org/grass84/manuals/r.import.html}{\code{r.import}} in \strong{GRASS}. +\code{\link[rgrass:readRAST]{rgrass::read_RAST()}} and \code{\link[rgrass:readVECT]{rgrass::read_VECT()}}, \link[=breakPolys]{vector cleaning}, \code{\link[=fillHoles]{fillHoles()}}, plus \strong{GRASS} modules \code{v.in.ogr} (see \code{grassHelp("v.in.ogr")}) and \code{r.import} (see \code{grassHelp("r.import")}) } diff --git a/man/faster.Rd b/man/faster.Rd index fdfdad2b..2a7848e8 100644 --- a/man/faster.Rd +++ b/man/faster.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/03_options.r \name{faster} \alias{faster} -\title{Set or get options shared across "fasterRaster" functions} +\title{Set or get options shared across fasterRaster functions} \usage{ faster(..., default = FALSE, restore = FALSE) } @@ -18,17 +18,17 @@ Options include: \itemize{ \item \code{grassDir} (character): The folder in which \strong{GRASS} is installed on your computer. Typically, this option is set when you run \code{\link[=faster]{faster()}}. Depending on your operating system, your install directory will look something like this: \itemize{ -\item Windows: \code{"C:/Program Files/GRASS GIS 8.3"} -\item Mac OS: \code{"/Applications/GRASS-8.3.app/Contents/Resources"} +\item Windows: \code{"C:/Program Files/GRASS GIS 8.4"} +\item Mac OS: \code{"/Applications/GRASS-8.4.app/Contents/Resources"} \item Linux: \code{"/usr/local/grass"} } \item \code{addonsDir} (character): Folder in which \strong{GRASS} addons are stored. If \code{NA} and \code{grassDir} is not \code{NA}, this will be assumed to be \code{file.path(grassDir, "addons")}. The default values is \code{NA}. \item \code{cores} (integer/numeric integer): Number of processor cores to use on a task. The default is 2. Some \strong{GRASS} modules are parallelized. \item \code{memory} (integer/numeric): The amount of memory to allocate to a task, in GB, for \strong{GRASS}. The default is 2048 MB (i.e., 2 GB). Some \strong{GRASS} modules can take advantage of more memory. -\item \code{clean} (logical): If \code{TRUE} (default), remove temporary files created internally by functions. If not deleted, they can eventually fill up hard drive space, but deleting them takes a little bit of time (usually <1 second for each function). +\item \code{clean} (logical): If \code{TRUE} (default), remove temporary files created internally by functions. If not deleted, they can eventually fill up hard drive space, but deleting them takes a little bit of time (usually <1 second for each function). See also \code{\link[=mow]{mow()}}. \item \code{useDataTable} (logical): If \code{FALSE} (default), functions that return tabular output produce \code{data.frame}s. If \code{TRUE}, output will be \code{data.table}s from the \strong{data.table} package. This can be much faster, but it might require you to know how to use \code{data.table}s if you want to manipulate them in \strong{R}. You can always convert them to \code{data.frame}s using \code{\link[base:as.data.frame]{base::as.data.frame()}}. \item \code{verbose} (logical): If \code{TRUE}, show \strong{GRASS} messages and otherwise hidden slots in classes. This is mainly used for debugging, so most users will want to keep this at its default, \code{FALSE}. -\item \code{workDir} (character): The folder in which \strong{GRASS} rasters, vectors, and other objects are created and manipulated. By default, this is given by \code{\link[=tempdir]{tempdir()}}. +\item \code{workDir} (character): The folder in which \strong{GRASS} rasters, vectors, and other objects are created and manipulated. By default, this is given by \code{\link[=tempdir]{tempdir()}}. Note that on some systems, changing the default folder to somewhere else can cause problems with \strong{fasterRaster} being able to find rasters in \strong{GRASS} that have been created. }} \item{default}{Logical: Return the default value(s) of the option(s). The default value of \code{default} is \code{FALSE}.} diff --git a/man/fasterRaster.Rd b/man/fasterRaster.Rd index 5ff23df7..2f9763be 100644 --- a/man/fasterRaster.Rd +++ b/man/fasterRaster.Rd @@ -9,9 +9,9 @@ \strong{fasterRaster}: Processing of large-in-memory/-on disk rasters and spatial vectors in using \strong{GRASS GIS}. Most functions in the \strong{terra} and \strong{sf} packages are recreated. Processing of medium-sized and smaller spatial objects will nearly always be faster using \strong{terra} or \strong{sf}. To use most of the functions you must have the stand-alone version of \strong{GRASS GIS} version 8.3 or higher (not the \strong{OSGeoW4} installer version). Note that due to differences in how \strong{GRASS}, \strong{terra}, and \strong{sf} were implemented, results will not always be strictly comparable between functions for the same operation. \subsection{Most useful tutorials and functions:}{ \itemize{ -\item The quick-start guide to getting started with \strong{fasterRaster} , accessible using \code{vignette("fasterRaster", package = "fasterRaster")} -\item The vignette on types of \code{GRaster}s, accessible using \code{vignette("GRasters", package = "fasterRaster")} -\item The vignette on how to speed up \strong{fasterRaster}, accessible using \code{vignette("faster_fasterRaster", package = "fasterRaster")} +\item The quick-start guide to getting started with \strong{fasterRaster}, accessible using \code{vignette("fasterRaster", package = "fasterRaster")} +\item Types of \code{GRaster}s, accessible using \code{vignette("GRasters", package = "fasterRaster")} +\item How to speed up \strong{fasterRaster}, accessible using \code{vignette("faster_fasterRaster", package = "fasterRaster")} \item \code{\link[=faster]{faster()}}: Set the directory where \strong{GRASS} is installed on your system, and set or get other package-wide options. This function must be run once before using most \strong{fasterRaster} functions. \item \code{\link[=fast]{fast()}}: Convert a \code{SpatRaster}, \code{SpatVector}, or \code{sf} vector to \strong{fasterRaster}'s raster format (\code{GRaster}s) or vector format (\code{GVector}s), or load one from a file \item \code{\link[=rast]{rast()}}, \code{\link[=vect]{vect()}}, and \code{\link[=st_as_sf]{st_as_sf()}}: Convert \code{GRaster}s and \code{GVector}s to \code{SpatRaster}s, \code{SpatVector}s, or \code{sf} vectors @@ -42,7 +42,7 @@ \item \code{\link[=nonnacell]{nonnacell()}}: Number of non-\code{NA} cells \item \code{\link[=nrow]{nrow()}}: Number of rows \item \code{\link[=nlevels]{nlevels()}}: Number of categories -\item \code{\link[=res]{res()}}, \code{\link[=xres]{xres()}}, \code{\link[=yres]{yres()}}, and \code{\link[=zres]{zres()}}: Spatial resolution +\item \code{\link[=res]{res()}}, \code{\link[=res3d]{res3d()}}, \code{\link[=xres]{xres()}}, \code{\link[=yres]{yres()}}, and \code{\link[=zres]{zres()}}: Spatial resolution \item \code{\link[=sources]{sources()}}: Name of the \code{GRaster} in \strong{GRASS} \item \item \code{\link[=zext]{zext()}}: Vertical extent @@ -57,7 +57,7 @@ \item \link[=Logic-methods]{Logical operators}: \code{|}and \code{&} } -Single-layer mathematical functions (applied to each layer of a \code{GRaster}): +Mathematical functions that are applied to each layer of a \code{GRaster}: \itemize{ \item Working with \code{NA}s: \code{\link[=is.na]{is.na()}}, \code{\link[=not.na]{not.na()}}, and \code{\link[=maskNA]{maskNA()}} \item Trigonometry: \code{\link[=sin]{sin()}}, \code{\link[=cos]{cos()}}, \code{\link[=tan]{tan()}}, \code{\link[=asin]{asin()}}, \code{\link[=acos]{acos()}}, \code{\link[=atan]{atan()}}, \code{\link[=atan2]{atan2()}} @@ -66,17 +66,24 @@ Single-layer mathematical functions (applied to each layer of a \code{GRaster}): \item Signs: \code{\link[=abs]{abs()}} } -Multi-layer functions (applied across layers of a "stack" of \code{GRaster}s): +Mathematical functions that are applied across layers of multi-layered \code{GRaster}s: \itemize{ \item Numeration: \code{\link[=sum]{sum()}}, \code{\link[=count]{count()}} \item Central tendency: \code{\link[=mean]{mean()}}, \code{\link[=mmode]{mmode()}}, \code{\link[=median]{median()}} \item Dispersion: \code{\link[=stdev]{stdev()}}, \code{\link[=var]{var()}}, \code{\link[=varpop]{varpop()}}, \code{\link[=nunique]{nunique()}}, \code{\link[=range]{range()}}, \code{\link[=quantile]{quantile()}}, \code{\link[=skewness]{skewness()}}, \code{\link[=kurtosis]{kurtosis()}} \item Extremes: \code{\link[=min]{min()}}, \code{\link[=max]{max()}}, \code{\link[=which.min]{which.min()}}, \code{\link[=which.max]{which.max()}} +\item \code{NA}s: \code{\link[=allNA]{allNA()}}, \code{\link[=anyNA]{anyNA()}} } -The operators \link{$} and \code{\link[fasterRaster]{[[}} can be used to subset or remove specific layers of a \code{GRaster}. -The \code{\link[fasterRaster]{[<-}} operator can be used to replace values of cells of a \code{GRaster}. -The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster]{[[<-}}, and \code{\link[fasterRaster]{add<-}}, can be used to replace specific layers of a \code{GRaster}. +Subsetting, assigning, and replacing \code{GRaster} layers +\itemize{ +\item \link{$}, \code{\link[fasterRaster]{[[}}, or \code{\link[=subset]{subset()}}: Subset or remove specific layers of a \code{GRaster} +\item \code{\link[fasterRaster]{[<-}}: Replace values of cells of a \code{GRaster} +\item \code{\link[fasterRaster]{[[<-}}: Replace specific layers of a \code{GRaster} +\item \code{\link[fasterRaster]{add<-}}: Replace specific layers of a \code{GRaster} +} + +Operations on \code{GRaster}s \itemize{ \item \code{\link[=as.int]{as.int()}}, \code{\link[=as.float]{as.float()}}, \code{\link[=as.doub]{as.doub()}}: Change data type (integer/float/double) \item \code{\link[=as.lines]{as.lines()}}: Convert a \code{GRaster} to a "lines" vector @@ -90,8 +97,8 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] \item \code{\link[=cellSize]{cellSize()}}: Cell area \item \code{\link[=classify]{classify()}}: Partition cell values into strata \item \code{\link[=clump]{clump()}}: Group adjacent cells with similar values -\item \code{\link[=combineCats]{combineCats()}}: Combine values from two or more categorical and/or integer rasters \item \code{\link[=combineLevels]{combineLevels()}}: Combine the "levels" tables of two or more categorical \code{GRaster}s +\item \code{\link[=concats]{concats()}}: Combine values from two or more categorical and/or integer rasters by concatenating them \item \code{\link[=crop]{crop()}}: Remove parts of a \code{GRaster} \item \code{\link[=denoise]{denoise()}}: Remove "noise" from a \code{GRaster} using a principal components analysis (PCA) \item \code{\link[=distance]{distance()}}: Distance to non-\code{NA} cells, or vice versa @@ -105,25 +112,26 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] \item \code{\link[=interpIDW]{interpIDW()}}: Interpolate values at points to a \code{GRaster} \item \code{\link[=kernel]{kernel()}}: Kernel density estimator of points \item \code{\link[=layerCor]{layerCor()}}: Correlation or covariance between two or more \code{GRaster} layers -\item \code{\link[=longlat]{longlat()}}: Create longitude/latitude rasters \item \code{\link[=mask]{mask()}}: Remove values in a \code{GRaster} based on values in another \code{GRaster} or vector \item \code{\link[=maskNA]{maskNA()}}: Mask all non-NA cells or all NA cells \item \code{\link[=match]{match()}}, \code{\link[fasterRaster]{\%in\%}}, and \code{\link[fasterRaster]{\%notin\%}}: Find which cells of a \code{GRaster} match or do not match certain values \item \code{\link[=merge]{merge()}}: Combine two or more rasters with different extents and fill in \code{NA}s -\code{\link[fasterRaster]{names<-}}: Assign names to a \code{GRaster} +\item \code{\link[fasterRaster]{names<-}}: Assign names to a \code{GRaster} \item \code{\link[=noise]{noise()}}: Remove coarse-scale trends from a \code{GRaster}, leaving just fine-scale "noise" \item \code{\link[=pairs]{pairs()}}: Plot correlations between \code{GRaster} layers -\item \code{\link[=pca]{pca()}}: Apply a principal components analysis (PCA) to a \code{GRaster} -\item \code{\link[=pcs]{pcs()}}: Retrieve a principal components model from a PCA \code{GRaster} generated using \code{pca()} +\item \code{\link[=pcs]{pcs()}}: Retrieve a principal components model from a PCA \code{GRaster} generated using \code{princomp()} \item \code{\link[=plot]{plot()}}: Display a \code{GRaster} -\item \code{\link[=plotRGB]{plotRGB()}}: Display a multispectral \code{GRaster} using red, blue, green, and alpha channels \item \code{\link[=project]{project()}}: Change coordinate reference system and cell size \item \code{\link[=predict]{predict()}}: Make predictions to a \code{GRaster} from a linear model or generalized linear model +\item \code{\link[=princomp]{princomp()}}: Apply a principal components analysis (PCA) to a \code{GRaster} +\item \code{\link[=regress]{regress()}}: Regression intercept, slope, r2, and t-value across each set of cells \item \code{\link[=resample]{resample()}}: Change cell size \item \code{\link[=reorient]{reorient()}}: Convert degrees between 'north-orientation' and 'east orientation' +\item \code{\link[=sampleRast]{sampleRast()}}: Randomly sample cells from a \code{GRaster} \item \code{\link[=scale]{scale()}}, \code{\link[=scalepop]{scalepop()}}, and \code{\link[=unscale]{unscale()}}: Subtract means and divide by standard deviations, or inverse of that \item \code{\link[=selectRange]{selectRange()}}: Select values from rasters in a stack based on values in another \code{GRaster} \item \code{\link[=spatSample]{spatSample()}}: Randomly points from a \code{GRaster} +\item \code{\link[=stretch]{stretch()}}: Rescale values in a GRaster \item \code{\link[=subst]{subst()}}: Re-assign cell values \item \code{\link[=thinLines]{thinLines()}}: Reduce linear features on a \code{GRaster} so linear features are 1 cell wide \item \code{\link[=tiles]{tiles()}}: Divide a \code{GRaster} into spatially exclusive subsets (though with possible overlap) @@ -133,9 +141,11 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] } } -\subsection{Functions for creating \code{GRaster}s \emph{de novo}}{ +\subsection{Creating \code{GRaster}s \emph{de novo}}{ \itemize{ \item \code{\link[=fractalRast]{fractalRast()}}: Create a fractal \code{GRaster} +\item \code{\link[=init]{init()}}: GRaster with values equal to row, column, coordinate, regular, or "chess" +\item \code{\link[=longlat]{longlat()}}: Create longitude/latitude rasters \item \code{\link[=rnormRast]{rnormRast()}}: A random \code{GRaster} with values drawn from a normal distribution \item \code{\link[=rSpatialDepRast]{rSpatialDepRast()}}: Create a random \code{GRaster} with or without spatial dependence \item \code{\link[=runifRast]{runifRast()}}: A random \code{GRaster} with values drawn from a uniform distribution @@ -143,7 +153,7 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] } } -\subsection{Functions for analysis of terrain and flow of water across landscapes}{ +\subsection{Analysis of terrain and hydrology}{ \itemize{ \item \code{\link[=as.contour]{as.contour()}}: Contour lines from a \code{GRaster} \item \code{\link[=flow]{flow()}}: Identify watershed basins and direction and accumulation of flow @@ -159,10 +169,9 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] } } -\subsection{Functions operating on categorical (factor) rasters}{ - -\code{\link[fasterRaster]{\%in\%}}, and \code{\link[fasterRaster]{\%notin\%}}: Mask cells that match or do not match a given category +\subsection{Operations on categorical (factor) \code{GRaster}s}{ \itemize{ +\item \code{\link[fasterRaster]{\%in\%}}, and \code{\link[fasterRaster]{\%notin\%}}: Mask cells that match or do not match a given category \item \code{\link[=activeCat]{activeCat()}} and \code{\link[=activeCats]{activeCats()}}: Column(s) that defines category labels \code{\link[fasterRaster]{activeCat<-}}: Set column that defines category labels \item \code{\link[=addCats]{addCats()}}: Add new columns to a "levels" table @@ -170,30 +179,33 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] \item \code{\link[=categories]{categories()}}: Set "levels" table for specific layers of a categorical raster \item \code{\link[=catNames]{catNames()}}: Column names of each "levels" table \item \code{\link[=cats]{cats()}}: "Levels" table of a categorical raster -\item \code{\link[=combineCats]{combineCats()}}: Combine categories from two or more categorical rasters \item \code{\link[=combineLevels]{combineLevels()}}: Combine the "levels" tables of two or more categorical \code{GRaster}s \item \code{\link[=complete.cases]{complete.cases()}}: Find rows of a categorical \code{GRaster}'s "levels" table that have no \code{NA}s in them +\item \code{\link[=concats]{concats()}}: Combine categories from two or more categorical rasters by concatenating them \item \code{\link[=droplevels]{droplevels()}}: Remove one or more levels \item \code{\link[=freq]{freq()}}: Frequency of each category across cells of a raster \item \code{\link[=is.factor]{is.factor()}}: Is a raster categorical? \item \code{\link[=levels]{levels()}}: "Levels" table of a categorical raster -\code{\link[fasterRaster]{levels<-}}: Set "levels" table of a categorical raster +\item \code{\link[fasterRaster]{levels<-}}: Set "levels" table of a categorical raster \item \code{\link[=match]{match()}}, \code{\link[fasterRaster]{\%in\%}}, and \code{\link[fasterRaster]{\%notin\%}}: Find which cells of a \code{GRaster} match or do not match certain category labels \item \code{\link[=minmax]{minmax()}}: "Lowest" and "highest" category values of categorical rasters (when argument \code{levels = TRUE}) \item \code{\link[=missing.cases]{missing.cases()}}: Find rows of a categorical \code{GRaster}'s "levels" table that have at least one \code{NA} in them \item \code{\link[=missingCats]{missingCats()}}: Values that have no category assigned to them \item \code{\link[=nlevels]{nlevels()}}: Number of levels +\item \code{\link[=segregate]{segregate()}}: Create one GRaster layer per unique value in a GRaster \item \code{\link[=subst]{subst()}}: Re-assign category levels \item \code{\link[=zonalGeog]{zonalGeog()}}: Geographic statistics (area, perimeter, fractal dimension, etc.) for sets of cells with the same values } } -\subsection{Functions for analysis of remote sensing rasters}{ +\subsection{Analysis of remote sensing rasters}{ \itemize{ \item \code{\link[=compositeRGB]{compositeRGB()}}: Combine red, green, and blue color bands to make a composite \code{GRaster} \item \code{\link[=plotRGB]{plotRGB()}}: Display a multispectral \code{GRaster} using red, blue, green, and alpha channels \item \code{\link[=vegIndex]{vegIndex()}}: Vegetation indices from surface reflectance } +} + \subsection{Functions that operate on \strong{terra} \code{SpatRaster}s}{ \itemize{ \item \code{\link[=bioclims]{bioclims()}}: BIOCLIM rasters (classic set and extended set) @@ -201,8 +213,6 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] } } -} - \subsection{Properties of \code{GVector}s}{ \itemize{ \item \code{\link[=crs]{crs()}}: Coordinate reference system @@ -225,12 +235,17 @@ The assign operators, \code{\link[fasterRaster]{$<-}}, \code{\link[fasterRaster] } } -\subsection{Functions that operate on or create \code{GVector}s}{ +\subsection{Subsetting and assigning geometries or rows and columns of \code{GVector}s}{ +\itemize{ +\item \link{$} or \code{\link[fasterRaster]{[[}}: Subset columns of a \code{GVector}'s data table +\item \code{\link[fasterRaster]{[}} or \code{\link[=subset]{subset()}}: Subset geometries of a \code{GVector} +\item \code{\link[fasterRaster]{$<-}}: Replace specific columns of a \code{GVector}'s data table or add columns +\item \code{\link[fasterRaster]{addTable<-}}: Add a data table to a \code{GVector} +\item \code{\link[=dropTable]{dropTable()}}: Remove a \code{GVector}s data table +} +} -The \code{\link[fasterRaster]{[}} operator can be used to subset geometries of a \code{GVector}. -The \link{$} and \code{\link[fasterRaster]{[[}} operators can be used to get columns of a \code{GVector}'s data table. -The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific columns of a \code{GVector}'s data table or to add columns. -\code{\link[fasterRaster]{addTable<-}}: Add a data table to a \code{GVector} +\subsection{Operations on \code{GVector}s}{ \itemize{ \item \code{\link[=aggregate]{aggregate()}}: Combine \code{GVector} geometries \item \code{\link[=as.data.frame]{as.data.frame()}}: Convert a \code{GVector}'s attribute table to a \code{data.frame} @@ -247,7 +262,6 @@ The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific col \item \code{\link[=delaunay]{delaunay()}}: Delaunay triangulation \item \code{\link[=disagg]{disagg()}}: Separate multipart geometries into singlepart geometries \item \code{\link[=distance]{distance()}}: Distance between geometries in two \code{GVector}, or from a \code{GVector} to cells of a \code{GRaster} -\item \code{\link[=dropTable]{dropTable()}}: Remove the data table from a \code{GVector} \item \code{\link[=erase]{erase()}} or \code{-}: Remove part of a \code{GVector} that overlaps with another \item \code{\link[=expanse]{expanse()}}: Area of polygons or length of lines \item \code{\link[=extract]{extract()}}: Extract values from a \code{GVector} at specific points @@ -256,8 +270,8 @@ The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific col \item \code{\link[=hexagons]{hexagons()}}: Create a hexagonal grid \item \code{\link[=interpIDW]{interpIDW()}}: Interpolate values at points to a \code{GRaster} using inverse-distance weighting \item \code{\link[=interpSplines]{interpSplines()}}: Interpolate values at points to a \code{GRaster} using splines -\item \code{\link[=intersect]{intersect()}} or \code{*}: Intersection of two \code{GVectors}. -\item \code{\link[=kernel]{kernel()}}: Kernel density estimator of points. +\item \code{\link[=intersect]{intersect()}} or \code{*}: Intersection of two \code{GVectors} +\item \code{\link[=kernel]{kernel()}}: Kernel density estimator of points \item \code{\link[=missing.cases]{missing.cases()}}: Find rows of a \code{GVector}'s data table that have at least \code{NA} in them \code{\link[fasterRaster]{names<-}}: Assign names to columns of a \code{GVector}s data table \item \code{\link[=project]{project()}}: Change coordinate reference system @@ -270,13 +284,20 @@ The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific col \item \code{\link[=tail]{tail()}}: Last rows of a \code{GVector}'s data table \item \code{\link[=thinPoints]{thinPoints()}}: Reduce number of points in same raster cell \item \code{\link[=union]{union()}} or \code{+}: Combine two \code{GVector}s -\item \code{\link[=xor]{xor()}} or \verb{/``: Select parts of polygons not shared by two }GVector`s +\item \code{\link[=voronoi]{voronoi()}}: Voronoi tessellation +\item \code{\link[=xor]{xor()}} or \code{/}: Select parts of polygons not shared by two \code{GVector}s +} +} + +\subsection{Creating \code{GVector}s \emph{de novo}}{ +\itemize{ +\item \code{\link[=rvoronoi]{rvoronoi()}}: Random Voronoi tesselation } } -\subsection{Functions for fixing issues with \code{GVector}s}{ +\subsection{Fixing issues with \code{GVector}s}{ -(See also tools that can be used during \code{GVector} creation/loading in \code{\link[=fast]{fast()}}.) +(See also \emph{Details} \code{\link[=fast]{fast()}}.) \itemize{ \item \code{\link[=breakPolys]{breakPolys()}}: Break topologically clean areas \item \code{\link[=fillHoles]{fillHoles()}}: Fill "holes" of a \code{GVector} @@ -303,8 +324,8 @@ The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific col \item \code{\link[=as.float]{as.float()}}: Convert a \code{GRaster} to a floating-point raster (\strong{GRASS} data type \code{FCELL}) \item \code{\link[=as.int]{as.int()}}: Convert a \code{GRaster} to an integer raster (\strong{GRASS} data type \code{CELL}) \item \code{\link[=as.points]{as.points()}}, \code{\link[=as.lines]{as.lines()}}, and \code{\link[=as.polygons]{as.polygons()}}: Convert a \code{GRaster} to a \code{GVector} +\item \code{\link[=categories]{categories()}} and \code{\link[fasterRaster]{levels<-}}: Convert an integer raster to a categorical ("factor") raster. \item \code{\link[=fast]{fast()}}: Convert a \code{SpatRaster} to a \code{GRaster}; a \code{SpatVector}, \code{sf} vector, numeric vector, \code{matrix}, \code{data.frame}, or \code{data.table} to a \code{GVector}; or load a vector or raster from a file -\item \code{\link[=categories]{categories()}} and \link{levels<-}: Convert an integer raster to a categorical ("factor") raster. \item \code{\link[=rast]{rast()}}: Convert a \code{GRaster} to a \code{SpatRaster} \item \code{\link[=rasterize]{rasterize()}}: Convert a \code{GVector} to a \code{GRaster} \item \code{\link[=st_as_sf]{st_as_sf()}}: Convert a \code{GVector} to a \code{sf} vector @@ -316,17 +337,22 @@ The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific col \itemize{ \item \code{\link[=compareGeom]{compareGeom()}}: Determine if geographic metadata is same between \code{GRaster}s and/or \code{GVector}s \item \code{\link[=dropRows]{dropRows()}}: Remove rows from a \code{data.frame} or \code{data.table} +\item \code{\link[=grassGUI]{grassGUI()}}: Start the \strong{GRASS} GUI (not recommended for most users!!!) +\item \code{\link[=grassHelp]{grassHelp()}}: Open the help page for a \strong{GRASS} module. \item \code{\link[=grassInfo]{grassInfo()}}: \strong{GRASS} version and citation +\item \code{\link[=grassStarted]{grassStarted()}}: Has a connection \strong{GRASS} been made within the current \strong{R} session? \item \code{\link[=mow]{mow()}}: Remove unused rasters and vectors from the \strong{GRASS} cache \item \code{\link[=reorient]{reorient()}}: Convert degrees between 'north-orientation' and 'east orientation' \item \code{\link[=replaceNAs]{replaceNAs()}}: Replace \code{NA}s in columns of a \code{data.table} or \code{data.frame}, or in a vector \item \code{\link[=seqToSQL]{seqToSQL()}}: Format a numeric series into an SQL value call +\item \code{\link[=workDir]{workDir()}}: \item \code{\link[=update]{update()}}: Refresh metadata in a \code{GRaster} or \code{GVector} object } } \subsection{Data objects}{ \itemize{ +\item \code{\link[=fastData]{fastData()}}: Helper function to quickly obtain example rasters and vectors \item \link{appFunsTable} (see also \code{\link[=appFuns]{appFuns()}}): Functions usable by the \code{\link[=app]{app()}} function \item \link{madChelsa}: Climate rasters for of a portion of eastern Madagascar \item \link{madCoast0}, \link{madCoast4}, and \link{madCoast}: Borders of an eastern portion of Madagascar @@ -338,25 +364,33 @@ The \code{\link[fasterRaster]{$<-}} operator can be used to replace specific col \item \link{madLANDSAT}: Surface reflectance in 2023 \item \link{madPpt}, \link{madTmin}, \link{madTmax}: Rasters of mean monthly precipitation, and minimum and maximum temperature \item \link{madRivers}: Rivers vector -\item \link{vegIndices}: Vegetation indices that can be calculated using \code{\link[=vegIndex]{vegIndex()}}. +\item \link{vegIndices}: Vegetation indices that can be calculated using \code{\link[=vegIndex]{vegIndex()}} } } \subsection{Esoteric tutorials and arcane notes}{ +\itemize{ +\item Comparisons between \code{GRegion}s can be performed using the \code{==} and \code{!=} operators. +\item Vignette on \strong{GRASS} "projects/locations" and "mapsets": \code{vignette("projects_mapsets", package = "fasterRaster")} +\item Vignette on \strong{GRASS} "regions": \code{vignette("regions", package = "fasterRaster")} +\item Vignette on \strong{fasteRaster} hidden functions: \code{vignette("hidden_functions", package = "fasterRaster")} +} +} -Comparisons between \code{GRegion}s can be performed using the \code{==} and \code{!=} operators. -Vignette on \strong{GRASS} "projects/locations" and "mapsets": \verb{vignette("projects_mapsets", package = "fasterRaster"}) -Vignette on \strong{GRASS} "regions": \code{vignette("regions", package = "fasterRaster")} -Vignette on \strong{fasteRaster} hidden functions: \code{vignette("hidden_functions", package = "fasterRaster")} +\subsection{Classes}{ \itemize{ -\item \code{\link[=grassStarted]{grassStarted()}}: Has a connection \strong{GRASS} been made within the current \strong{R} session? +\item \code{\link{GLocation}}: Fundamental class; points to a "location/project" in \strong{GRASS} +\item \code{\link{GSpatial}}: Basic class of any spatial object +\item \code{\link{GRegion}}: Points to a "region" of a "location/project" in \strong{GRASS} +\item \code{\link{GRaster}}: Raster class +\item \code{\link{GVector}}: Spatial vector class } } } \seealso{ Useful links: \itemize{ - \item \url{http://www.earthSkySea.org} + \item \url{https://github.com/adamlilith/fasterRaster} \item \url{https://adamlilith.github.io/fasterRaster/} \item Report bugs at \url{https://github.com/adamlilith/fasterRaster/issues} } diff --git a/man/fillHoles.Rd b/man/fillHoles.Rd index 25cf5919..70ccbe5a 100644 --- a/man/fillHoles.Rd +++ b/man/fillHoles.Rd @@ -10,7 +10,7 @@ \arguments{ \item{x}{A \code{GVector}.} -\item{fail}{Logical: If \code{TRUE} (default), and \strong{GRASS 8.4} or higher is not installed, cause an error. If \code{FALSE}, a warning will be displayed and a \code{NULL} value will be returned. This function requires \strong{GRASS 8.4} or higher to be installed.} +\item{fail}{Logical: If \code{TRUE} (default), and \strong{GRASS 8.3} or higher is not installed, cause an error. If \code{FALSE}, a warning will be displayed and a \code{NULL} value will be returned. This function requires \strong{GRASS 8.3} or higher to be installed.} } \value{ A \code{GVector}. diff --git a/man/fillNAs.Rd b/man/fillNAs.Rd index f4d88a83..36271944 100644 --- a/man/fillNAs.Rd +++ b/man/fillNAs.Rd @@ -21,7 +21,7 @@ \item{method}{Character: Type of spline, either "\code{bilinear}" (default), "\code{bicubic}", or "\code{RST}" (regularized splines with tension). Partial matching is used and case is ignored. -\strong{Note}: The RST method will often display warnings, but thesecan be ignored.} +\strong{Note}: The RST method will often display warnings, but these can be ignored.} \item{min, max}{Numeric: Lowest and highest values allowed in the interpolated values. Values outside these bounds will be truncated to the minimum/maximum value(s) allowed. The default imposes no constraints. For multi-layered rasters, you can supply a single value for \code{min} and/or \code{max}, or multiple values (one per layer). Values will be recycled if there are fewer than one or them per layer in the raster.} @@ -71,5 +71,5 @@ plot(maps) } } \seealso{ -\code{\link[terra:interpNear]{terra::interpNear()}}; module \href{https://grass.osgeo.org/grass84/manuals/r.fillnulls.html}{r.fillnulls} in \strong{GRASS} +\code{\link[terra:interpNear]{terra::interpNear()}}, \strong{GRASS} module \code{r.fillnulls} (see \code{grassHelp("r.fillnulls")}) } diff --git a/man/flow.Rd b/man/flow.Rd index f2f6a85a..1ed5194b 100644 --- a/man/flow.Rd +++ b/man/flow.Rd @@ -10,7 +10,7 @@ direction = "multi", return = "accumulation", dirThreshold = Inf, - scratchDir = tempdir() + scratchDir = NULL ) } \arguments{ @@ -30,7 +30,7 @@ \item{dirThreshold}{Numeric (default is \code{Inf}): For the multi-direction flow model, this indicates the amount of accumulated flow above which the single-direction flow rule is used to locate the egress of water from a cell. This is the \code{d8cut} parameter in \code{r.stream.extract}.} -\item{scratchDir}{Character: Directory in which to store temporary files. The \strong{GRASS} module \code{r.terraflow} makes a lot of temporary files. The default is given by \code{\link[=tempdir]{tempdir()}}.} +\item{scratchDir}{Character or \code{NULL} (default): Directory in which to store temporary files. The \strong{GRASS} module \code{r.terraflow} makes a lot of temporary files. If this is \code{NULL}, then a temporary folder in the user's working directory will be used (see \code{\link[=getwd]{getwd()}}).} } \value{ A \code{GRaster}. @@ -45,7 +45,7 @@ The \code{flow()} function uses a raster representing elevation to compute other \item Topographic convergence (log of flow accumulation divided by local slope). } -More details about the computations can be found at the help page for the \href{https://grass.osgeo.org/grass84/manuals/r.terraflow.html}{\code{r.terraflow}} module for \strong{GRASS}. +More details about the computations can be found at the help page for the \strong{GRASS} module \code{r.terraflow}] (see \code{grassHelp("r.terraflow")}) } \examples{ if (grassStarted()) { @@ -67,5 +67,5 @@ plot(elevWater) } } \seealso{ -\code{\link[=flowPath]{flowPath()}}, \code{\link[=streams]{streams()}}, the \href{https://grass.osgeo.org/grass84/manuals/r.terraflow.html}{\code{r.terraflow}} module for \strong{GRASS} +\code{\link[=flowPath]{flowPath()}}, \code{\link[=streams]{streams()}}, the \strong{GRASS} module \code{r.terraflow} (see \code{grassHelp("r.terraflow")}) } diff --git a/man/flowPath.Rd b/man/flowPath.Rd index 5f57df16..589a4003 100644 --- a/man/flowPath.Rd +++ b/man/flowPath.Rd @@ -44,7 +44,7 @@ ant <- coast4[coast4$NAME_4 == "Antanambe"] elevAnt <- crop(elev, ant) # Create a set of random points to serve as starting points: -starts <- spatSample(elevAnt, 10, as.points = TRUE, seed = 1) +starts <- spatSample(elevAnt, 10, as.points = TRUE, seed = 2) # Remove points in water: starts <- starts[complete.cases(starts)] @@ -53,14 +53,16 @@ starts <- starts[complete.cases(starts)] paths <- flowPath(elevAnt, starts) paths -plot(paths) +plot(elevAnt, legend = FALSE, main = "Flow path for each point") +plot(paths, add = TRUE) plot(starts, pch = 1, add = TRUE) # Calculate flow paths with cell values indicating the number # of cells from each start: seqs <- flowPath(elevAnt, starts, return = "seq") -plot(seqs) +plot(elevAnt, legend = FALSE, main = "Sequentially-numbered flow paths") +plot(seqs, add = TRUE) plot(starts, pch = 1, add = TRUE) # We can convert flow paths to lines: @@ -71,5 +73,5 @@ seqLines } } \seealso{ -\code{\link[=flow]{flow()}}, \code{\link[=streams]{streams()}}, the \href{https://grass.osgeo.org/grass84/manuals/r.drain.html}{\code{r.drain}} module for \strong{GRASS} +\code{\link[=flow]{flow()}}, \code{\link[=streams]{streams()}}, the \strong{GRASS} module \code{r.drain} (see \code{grassHelp("r.drain")}) } diff --git a/man/focal.Rd b/man/focal.Rd index 42cd97c6..f1724b96 100644 --- a/man/focal.Rd +++ b/man/focal.Rd @@ -22,7 +22,7 @@ \item "\code{mean}" (default) \item "\code{median}" \item "\code{mode}" -\item "\code{min}" or "\code{max}": Minumum or maximum. Should not use a weights matrix. +\item "\code{min}" or "\code{max}": Minimum or maximum. Should not use a weights matrix. \item "\code{range}": Difference between the maximum and minimum. Should not use a weights matrix. \item "\code{sd}": Sample standard deviation. NB: This is the same as the \code{\link[stats:sd]{stats::sd()}} function. \item "\code{sdpop}": Population standard deviation. NB: This is the same as the function "stddev" in the \strong{GRASS} module \code{r.neighbors}. diff --git a/man/functions.Rd b/man/functions.Rd index 08664e1b..f5d65f7f 100644 --- a/man/functions.Rd +++ b/man/functions.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/06_GRaster_functions_acrossLayers.r +% Please edit documentation in R/06_GRaster_functions_across_layers.r \name{mean,GRaster-method} \alias{mean,GRaster-method} \alias{mean} @@ -34,18 +34,14 @@ \alias{skewness} \alias{kurtosis,GRaster-method} \alias{kurtosis} -\alias{slope,GRaster-method} -\alias{slope} -\alias{intercept,GRaster-method} -\alias{intercept} -\alias{r2,GRaster-method} -\alias{r2} -\alias{tvalue,GRaster-method} -\alias{tvalue} \alias{range,GRaster-method} \alias{range} \alias{quantile,GRaster-method} \alias{quantile} +\alias{anyNA,GRaster-method} +\alias{anyNA} +\alias{allNA,GRaster-method} +\alias{allNA} \title{Mathematical operations on two or more GRasters} \usage{ \S4method{mean}{GRaster}(x, na.rm = FALSE) @@ -82,17 +78,13 @@ \S4method{kurtosis}{GRaster}(x, na.rm = FALSE) -\S4method{slope}{GRaster}(x, na.rm = FALSE) - -\S4method{intercept}{GRaster}(x, na.rm = FALSE) - -\S4method{r2}{GRaster}(x, na.rm = FALSE) - -\S4method{tvalue}{GRaster}(x, na.rm = FALSE) - \S4method{range}{GRaster}(x, na.rm = FALSE) \S4method{quantile}{GRaster}(x, prob, na.rm = FALSE) + +\S4method{anyNA}{GRaster}(x) + +\S4method{allNA}{GRaster}(x) } \arguments{ \item{x}{A \code{GRaster}. Typically, this raster will have two or more layers. Values will be calculated within cells across rasters.} @@ -113,7 +105,7 @@ These functions can be applied to a "stack" of \code{GRaster}s with two or more \item Central tendency: \code{mean()}, \code{mmode()} (mode), \code{median()}. \item Extremes: \code{min()}, \code{max()}, \code{which.min()} (index of raster with the minimum value), \code{which.max()} (index of the raster with the maximum value) \item Dispersion: \code{range()}, \code{stdev()} (standard deviation), \code{var()} (sample variance), \code{varpop()} (population variance), \code{nunique()} (number of unique values), \code{quantile()} (use argument \code{probs}), \code{skewness()}, and \code{kurtosis()}. -\item Regression: Assuming we calculate a linear regression for each set of cells through all values of the cells, we can calculate its \code{slope()}, \code{intercept()}, \code{r2()}, and \code{tvalue()}. +\item \code{NA}s: \code{anyNA()} (any cells are \code{NA}?), \code{allNA()} (are all cells \code{NA}?) } } \examples{ @@ -124,157 +116,57 @@ library(sf) library(terra) # Example data -madElev <- fastData("madElev") +madChelsa <- fastData("madChelsa") # Convert a SpatRaster to a GRaster -elev <- fast(madElev) -elevs <- c(elev, elev, log10(elev) - 1, sqrt(elev)) -names(elevs) <- c("elev1", "elev2", "log_elev", "sqrt_elev") - -elev -elevs - -# do some math -elev + 100 -elev - 100 -elev * 100 -elev / 100 -elev ^ 2 -elev \%/\% 100 # divide then round down -elev \%\% 100 # modulus - -100 + elev -100 \%/\% elev -100 \%\% elev - -elevs + 100 -100 + elevs - -# math with logicals -elev + TRUE -elev - TRUE -elev * TRUE -elev / TRUE -elev ^ TRUE -elev \%/\% TRUE # divide then round down -elev \%\% TRUE # modulus - -elevs + TRUE -TRUE + elevs - -# Raster interacting with raster(s): -elev + elev -elev - elev -elev * elev -elev / elev -elev ^ log(elev) -elev \%/\% sqrt(elev) # divide then round down -elev \%\% sqrt(elev) # modulus - -elevs + elev -elev * elevs - -# sign -abs(-1 * elev) -abs(elevs) - -# powers -sqrt(elevs) - -# trigonometry -sin(elev) -cos(elev) -tan(elev) - -asin(elev) -acos(elev) -atan(elev) - -atan(elevs) -atan2(elev, elev^1.2) -atan2(elevs, elev^1.2) -atan2(elev, elevs^1.2) -atan2(elevs, elevs^1.2) - -# logarithms -exp(elev) -log(elev) -ln(elev) -log2(elev) -log1p(elev) -log10(elev) -log10p(elev) -log(elev, 3) - -log(elevs) - -# rounding -round(elev + 0.5) -floor(elev + 0.5) -ceiling(elev + 0.5) -trunc(elev + 0.5) - -# comparison -elev < 100 -elev <= 100 -elev == 100 -elev != 100 -elev > 100 -elev >= 100 - -elev + 100 < 2 * elev - -elevs > 10 -10 > elevs - -# logic -elev < 10 | elev > 200 -elev < 10 | cos(elev) > 0.9 - -elev < 10 | TRUE -TRUE | elev > 200 - -elev < 10 | FALSE -FALSE | elev > 200 - -elev < 10 & cos(elev) > 0.9 - -elev < 10 & TRUE -TRUE & elev > 200 - -elev < 10 & FALSE -FALSE & elev > 200 - -# Mathematical functions on GRasters with >= 2 layers: -mean(elevs) -mmode(elevs) -median(elevs) -nunique(elevs) - -sum(elevs) -count(elevs) -min(elevs) -max(elevs) -range(elevs) -skewness(elevs) -kurtosis(elevs) - -which.min(elevs) -which.max(elevs) - -slope(elevs) -intercept(elevs) -r2(elevs) -tvalue(elevs) - -stdev(elevs) -stdev(elevs, pop = FALSE) -var(elevs) -varpop(elevs) +chelsa <- fast(madChelsa) +chelsa # 4 layers + +# Central tendency +mean(chelsa) +mmode(chelsa) +median(chelsa) + +# Statistics +nunique(chelsa) +sum(chelsa) +count(chelsa) +min(chelsa) +max(chelsa) +range(chelsa) +skewness(chelsa) +kurtosis(chelsa) + +stdev(chelsa) +stdev(chelsa, pop = FALSE) +var(chelsa) +varpop(chelsa) + +# Which layers have maximum/minimum? +which.min(chelsa) +which.max(chelsa) + +# Regression +# Note the intercept is different for fasterRaster::regress(). +regress(chelsa) +regress(madChelsa, 1:nlyr(madChelsa)) # Note: To get quantiles for each layer, use # global(x, "quantile", probs = 0.2). -quantile(elevs, 0.1) +quantile(chelsa, 0.1) + +# NAs +madForest2000 <- fastData("madForest2000") +forest2000 <- fast(madForest2000) +forest2000 <- project(forest2000, chelsa, method = "near") + +chelsaForest <- c(chelsa, forest2000) + +nas <- anyNA(chelsaForest) +plot(nas) + +allNas <- allNA(chelsaForest) +plot(allNas) } } diff --git a/man/geomorphons.Rd b/man/geomorphons.Rd index bb9a245d..3cd113b5 100644 --- a/man/geomorphons.Rd +++ b/man/geomorphons.Rd @@ -28,7 +28,7 @@ \item{mode}{Character: Method for implementing the zenith/line-of-site search. Partial matching is used: \itemize{ -\item \code{"1"} (default): The "original" geomorphon mode (in \strong{GRASS} module \href{https://grass.osgeo.org/grass84/manuals/r.geomorphon.html}{\code{r.geomorphon}}, the "anglev1" method) +\item \code{"1"} (default): The "original" geomorphon mode (in \strong{GRASS} module \code{r.geomorphon}, the "anglev1" method) \item \code{"2"}: Better handling of cases with equal zenith/nadir angles (the "anglev2" method) \item \code{"2d"}: As \code{"2"}, but takes into account zenith/nadir distance ("anglev2_distance" method) }} @@ -37,7 +37,7 @@ A categorical \code{GRaster} where each geomorphon is a category (see \code{vignette("GRasters", package = "fasterRaster")}). } \description{ -Geomorphons are idealized terrain types calculated from an elevator raster based on a moving window of a given size. The window is a torus (which can have an inner radius of 0, so can also be a circle), which allows it to identify geomorphons of a given size while ignoring ones larger or smaller. There are 10 basic geomorphons. Consult the The \strong{GRASS} module \href{https://grass.osgeo.org/grass84/manuals/r.geomorphon.html}{\code{r.geomorphon}} for more details and diagrams of each type of geomorphon. They include: +Geomorphons are idealized terrain types calculated from an elevator raster based on a moving window of a given size. The window is a torus (which can have an inner radius of 0, so can also be a circle), which allows it to identify geomorphons of a given size while ignoring ones larger or smaller. There are 10 basic geomorphons. Consult the the manual for \strong{GRASS} module \code{r.geomorphon} using \code{grassHelp("r.geomorphon")} for more details and diagrams of each type of geomorphon. Geomorphon types include: \enumerate{ \item Flat areas: Focal area has approximately the same elevation as surrounding areas \item Pits: An area is lower than all other surrounding areas @@ -76,5 +76,5 @@ plot(geos, col = col) } } \seealso{ -Module \href{https://grass.osgeo.org/grass84/manuals/r.geomorphon.html}{\code{r.geomorphon}} in \strong{GRASS} +\strong{GRASS} module \code{r.geomorphon} (see \code{grassHelp("r.geomorphon")}) } diff --git a/man/global.Rd b/man/global.Rd index 5bb6d859..b61c4f5b 100644 --- a/man/global.Rd +++ b/man/global.Rd @@ -53,14 +53,15 @@ madElev <- fastData("madElev") # Convert a SpatRaster to a GRaster: elev <- fast(madElev) +# What functions can we use with global()? +global() + # Calculate global statistics: global(elev, fun = c("mean", "var", "varpop")) global(elev, "quantile", probs = c(0.25, 0.5, 0.75)) global(elev, "*") # calculate all available functions -global() # vector of all functions - } } \seealso{ diff --git a/man/grassGUI.Rd b/man/grassGUI.Rd new file mode 100644 index 00000000..3359fa25 --- /dev/null +++ b/man/grassGUI.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/grassGUI.r +\name{grassGUI,missing-method} +\alias{grassGUI,missing-method} +\alias{grassGUI} +\title{Start the GRASS GUI (potentially dangerous!)} +\usage{ +\S4method{grassGUI}{missing}() +} +\value{ +Nothing (starts the \strong{GRASS} GUI). +} +\description{ +This function starts the \strong{GRASS} GUI. It is provided merely as a utility... in most cases, it should \emph{not} be used if you are doing any kind of analysis of rasters or vectors using \strong{fasterRaster}. The reason for this prohibition is that \strong{fasterRaster} objects, like \code{GRaster}s and \code{GVector}s, are really "pointers" to objects in \strong{GRASS}. If \strong{fasterRaster} points to a \strong{GRASS} object that is changed in \strong{GRASS} but not \strong{R}, then \strong{fasterRaster} will not "know" about it, so changed won't be reflected in the \strong{fasterRaster} object. + +One aspect of the GUI that is useful but will not change objects is to use it to plot rasters and vectors. However, the a \strong{fasterRaster} object in \strong{R} will have a different name in \strong{GRASS}. The name in \strong{GRASS} of a \code{GVector} or \code{GRaster} is given by \code{\link[=sources]{sources()}}. +} +\examples{ +if (grassStarted()) { + +# Starting the GRASS GUI and making changes to rasters or vectors can "break" +# the GRasters and GVectors they are associated with in R. +if (interactive() & FALSE) grassGUI() + +} +} +\seealso{ +\code{\link[=mow]{mow()}} +} diff --git a/man/grassHelp.Rd b/man/grassHelp.Rd new file mode 100644 index 00000000..91598896 --- /dev/null +++ b/man/grassHelp.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/grassHelp.r +\name{grassHelp} +\alias{grassHelp} +\title{Open the help page for a GRASS module} +\usage{ +grassHelp(x, online = FALSE) +} +\arguments{ +\item{x}{Character: Any of: +\itemize{ +\item The name of a \strong{GRASS} module (e.g., \code{"r.mapcalc"}). +\item \code{"type"}: Display a page wherein modules are classified by types. +\item \code{"topics"}: Display an index of topics. +}} + +\item{online}{Logical: If \code{FALSE} (default), show the manual page that was included with your installation of \strong{GRASS} on your computer. If \code{FALSE}, show the manual page online (requires an Internet connection). In either case, the manual page will display for the version of \strong{GRASS} you have installed.} +} +\value{ +Nothing (opens a web page). +} +\description{ +This function opens the manual page for a \strong{GRASS} module (function) in your browser. +} +\examples{ +if (grassStarted() & interactive()) { + +# Open help pages for `r.mapcalc` and `r.sun`: +grassHelp("r.mapcalc") +grassHelp("r.sun") + +# Open topics page: +grassHelp("topics") + +# Open index page: +grassHelp("index") + +} +} diff --git a/man/grassInfo.Rd b/man/grassInfo.Rd index f99f424a..c15dd565 100644 --- a/man/grassInfo.Rd +++ b/man/grassInfo.Rd @@ -12,7 +12,7 @@ grassInfo(x = "citation") \item \code{"citation"} (default) \item \code{"copyright"}: Copyright information \item \code{"version"}: Version number and release year -\item \code{"versionNumber"}: Version number as numeric, major and minor only (e.g., 8.3) +\item \code{"versionNumber"}: Version number as numeric, major and minor only (e.g., 8.4) } Partial matching is used and case is ignored.} diff --git a/man/grassStarted.Rd b/man/grassStarted.Rd index fdbdb86b..b7568650 100644 --- a/man/grassStarted.Rd +++ b/man/grassStarted.Rd @@ -10,7 +10,7 @@ grassStarted() Logical. } \description{ -Returns \code{TRUE} or \code{FALSE}, depending on whether a \strong{GRASS} connection has been made or not within the current \strong{R} session. Usually used only by developers. +Returns \code{TRUE} or \code{FALSE}, depending on whether a \strong{GRASS} connection has been made or not within the current \strong{R} session. Usually used only by developers. \strong{GRASS} is started the first time \code{\link[=fast]{fast()}} is used. } \examples{ diff --git a/man/hist.Rd b/man/hist.Rd index 764d60ae..9c5c25a9 100644 --- a/man/hist.Rd +++ b/man/hist.Rd @@ -29,9 +29,6 @@ This function creates a histogram of values in \code{GRaster}. The function is m \examples{ if (grassStarted()) { -# Setup -library(terra) - # Example data madElev <- fastData("madElev") # elevation raster madLANDSAT <- fastData("madLANDSAT") # multi-layer raster diff --git a/man/init.Rd b/man/init.Rd new file mode 100644 index 00000000..032641d6 --- /dev/null +++ b/man/init.Rd @@ -0,0 +1,87 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/init.r +\name{init,GRaster-method} +\alias{init,GRaster-method} +\alias{init} +\title{GRaster with values equal to row, column, coordinate, regular, or "chess"} +\usage{ +\S4method{init}{GRaster}(x, fun, odd = TRUE, vals = c(0, 1)) +} +\arguments{ +\item{x}{A \code{GRaster} to be used as a template.} + +\item{fun}{Character: Any of: +\itemize{ +\item \code{"x"} or \code{"y"}: Cell longitude or latitude +\item \code{"row"} or \code{"col"}: Cell row or column +\item \code{"chess"}: Alternating values. +\item \code{"regular"}: Evenly-spaced cells with the same value. +}} + +\item{odd}{Logical: If \code{TRUE} (default), and \code{fun} is \code{"chess"}, then the top left cell in the raster will be a "negative" cell. If \code{FALSE}, then the top left cell with be "positive".} + +\item{vals}{Vector of two numeric values: If \code{fun} is \code{"chess"} or \code{"regular"}, then assign the first value to "positive" cells and the second value to "negative" cells. The default is \code{c(1, 0)}} + +\item{every}{Numeric or integer: If \code{fun} is \code{"regular"}, then make every \code{every} cell a "positive" cell, and interstitial cells "negative." The default is 2 (every other cell).} +} +\value{ +A \code{GRaster} with as many layers as \code{x}. +} +\description{ +This function can be used to make a \code{GRaster} with cell values equal to the cell center's longitude, latitude, row, or column, or in a "chess"-like or "regular" pattern. +} +\examples{ +if (grassStarted()) { + +# Setup +library(terra) + +# Elevation raster, rivers vector +madElev <- fastData("madElev") + +# Convert to a GRaster +elev <- fast(madElev) + +# Cell coordinates +init(elev, "x") +init(elev, "y") + +# Cell row or column +init(elev, "row") +init(elev, "col") + +# Chess +elevAgg <- aggregate(elev, 32) # make cells bigger so we can see + +chessOdd <- init(elevAgg, "chess") +chessEven <- init(elevAgg, "chess", odd = FALSE) + +chess <- c(chessOdd, chessEven) +names(chess) <- c("odd", "even") +plot(chess) + +# Chess with user-defined values +elevAgg <- aggregate(elev, 32) # make cells bigger so we can see + +chessOdd13 <- init(elevAgg, "chess", vals = c(0, 13)) +chessEven13 <- init(elevAgg, "chess", odd = FALSE, vals = c(0, 13)) + +chess13 <- c(chessOdd13, chessEven13) +names(chess13) <- c("odd", "even") +plot(chess13) + +# Regular +elevAgg <- aggregate(elev, 32) # make cells bigger so we can see + +regOdd <- init(elevAgg, "regular") +regEven <- init(elevAgg, "regular", odd = FALSE) + +reg <- c(regOdd, regEven) +names(reg) <- c("odd", "even") +plot(reg) + +} +} +\seealso{ +\code{\link[terra:init]{terra::init()}}, \code{\link[=longlat]{longlat()}} +} diff --git a/man/interpIDW.Rd b/man/interpIDW.Rd index 940e3371..df1a71a6 100644 --- a/man/interpIDW.Rd +++ b/man/interpIDW.Rd @@ -25,5 +25,5 @@ A \code{GRaster}. This function interpolates values from a set of points to a raster using inverse distance weighting (IDW). } \seealso{ -\code{\link[terra:interpIDW]{terra::interpIDW()}}, \code{\link[=interpSplines]{interpSplines()}}, \code{\link[=fillNAs]{fillNAs()}}, module \href{https://grass.osgeo.org/grass84/manuals/v.surf.idw.html}{\code{v.surf.idw}} in \strong{GRASS} +\code{\link[terra:interpIDW]{terra::interpIDW()}}, \code{\link[=interpSplines]{interpSplines()}}, \code{\link[=fillNAs]{fillNAs()}}, \strong{GRASS} module \code{v.surf.idw} (se \code{grasshelp("v.surf.idw")}) } diff --git a/man/interpSplines.Rd b/man/interpSplines.Rd index d8bb9708..c0214592 100644 --- a/man/interpSplines.Rd +++ b/man/interpSplines.Rd @@ -54,5 +54,5 @@ If you receive the error, "No data within this subregion. Consider increasing sp If cross-validation takes too long, or other warnings/errors persist, you can randomly subsample \code{x} to ~100 points to get an optimum value of \code{lambda} (using \code{interpolate = FALSE}), then use this value in the same function again without cross-validation (setting \code{lambda} equal to this value and \code{interpolate = TRUE}). } \seealso{ -\code{\link[=interpIDW]{interpIDW()}}, \code{\link[=fillNAs]{fillNAs()}}, module \href{https://grass.osgeo.org/grass84/manuals/v.surf.bspline.html}{\code{v.surf.bspline}} in \strong{GRASS} +\code{\link[=interpIDW]{interpIDW()}}, \code{\link[=fillNAs]{fillNAs()}}, \strong{GRASS} module \code{v.surf.bspline} (see \code{grassHelp("v.surf.bspline")}) } diff --git a/man/is.lonlat.Rd b/man/is.lonlat.Rd index 1362a125..7cf5d366 100644 --- a/man/is.lonlat.Rd +++ b/man/is.lonlat.Rd @@ -20,7 +20,7 @@ Logical (\code{TRUE} if unprojected, \code{FALSE} otherwise). } \description{ -\code{is.lonlat()} attempst to determine if a coordinate reference system is unprojected (e.g., WGS84, NAD83, NAD27, etc.). For \code{GRaster}s and \code{GVector}s, the function should always be correct. For WKT character strings and \code{sf} vectors, it does this by looking for the "CONVERSION[" tag in the WKT string (or the object's WKT string), and if it finds one, returns \code{FALSE}. This may not be truthful in all cases. +\code{is.lonlat()} attempts to determine if a coordinate reference system is unprojected (e.g., WGS84, NAD83, NAD27, etc.). For \code{GRaster}s and \code{GVector}s, the function should always be correct. For WKT character strings and \code{sf} vectors, it does this by looking for the "CONVERSION[" tag in the WKT string (or the object's WKT string), and if it finds one, returns \code{FALSE}. This may not be truthful in all cases. } \seealso{ \code{\link[terra:is.lonlat]{terra::is.lonlat()}} diff --git a/man/levels.Rd b/man/levels.Rd index 6e76fce3..70aa30ec 100644 --- a/man/levels.Rd +++ b/man/levels.Rd @@ -167,12 +167,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/location.Rd b/man/location.Rd index 21a4dc55..3927fc45 100644 --- a/man/location.Rd +++ b/man/location.Rd @@ -53,33 +53,37 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } if (grassStarted()) { @@ -98,33 +102,37 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } } diff --git a/man/locationCreate.Rd b/man/locationCreate.Rd index 677798ef..e6c37935 100644 --- a/man/locationCreate.Rd +++ b/man/locationCreate.Rd @@ -53,33 +53,37 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } } diff --git a/man/locationFind.Rd b/man/locationFind.Rd index c72056ff..1d64f1a5 100644 --- a/man/locationFind.Rd +++ b/man/locationFind.Rd @@ -26,15 +26,15 @@ \itemize{ \item Missing: Returns names and coordinate reference system strings of all "locations". \item A character representing a coordinate reference system in WKT format -\item A \code{SpatRaster}, \code{SpatVector}, or \code{sf} vector +\item A \code{SpatRaster}, \code{SpatVector}, or \code{sf} vector with a coordinate reference system \item A \code{GSpatial} object (usually a \code{GRaster} or \code{GVector}) }} \item{return}{Either: \itemize{ \item \code{"name"} (default): Returns the name of the "location" with a coordinate reference system the same as \code{x}. -\item \code{"index"}: Returns the index of this "location". -\item \code{"crs"}: Returns the coordinate reference system of this "location". +\item \code{"index"}: Returns the index of this "location" in \code{.fasterRaster$locations} of the \code{.fasterRaster} environment. +\item \code{"crs"}: Returns the coordinate reference system of this "project/location". }} \item{match}{Character: Method used to find the location. If \code{match} is "\code{name}"" (default), then the name of the location is used. If \code{match} is "\code{crs}", then the coordinate reference system of each location is checked for a match.} @@ -43,7 +43,7 @@ Character, integer, or \code{NULL} (if no match is found). } \description{ -The function searches the set of available \strong{GRASS} "locations" for one that has a coordinate reference system matching a \code{GSpatial} object. If none are found, or if no connection with \strong{GRASS} has yet been made, then it returns \code{NULL}. Otherwise, it returns either the index or the name of the matching location. +The function searches the set of available \strong{GRASS} "projects" (previously known as "locations") for one that has a coordinate reference system matching a \code{GSpatial} object. If none are found, or if no connection with \strong{GRASS} has yet been made, then it returns \code{NULL}. Otherwise, it returns either the index or the name of the matching location. } \examples{ if (grassStarted()) { @@ -62,33 +62,37 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } } diff --git a/man/locationRestore.Rd b/man/locationRestore.Rd index ae7d5694..4a67c1bb 100644 --- a/man/locationRestore.Rd +++ b/man/locationRestore.Rd @@ -49,33 +49,37 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } } diff --git a/man/locations.Rd b/man/locations.Rd index e4dd0aee..3c3467b6 100644 --- a/man/locations.Rd +++ b/man/locations.Rd @@ -34,33 +34,37 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } } diff --git a/man/longlat.Rd b/man/longlat.Rd index 290e82d8..0497ecaa 100644 --- a/man/longlat.Rd +++ b/man/longlat.Rd @@ -14,7 +14,7 @@ A \code{GRaster} stack. } \description{ -\code{longlat()} creates two rasters, one with cell values equal to the longitude of the cell centers, and one with cell values equal to the latitude of the cell centers. Values will be in decimal degrees, regardless of the projection of the raster. +\code{longlat()} creates two rasters, one with cell values equal to the longitude of the cell centers, and one with cell values equal to the latitude of the cell centers. Values will be in decimal degrees, regardless of the projection of the raster. If you want projected coordinates, use \code{\link[=init]{init()}}. } \examples{ if (grassStarted()) { @@ -34,3 +34,6 @@ ll # note units of cell values! } } +\seealso{ +\code{\link[=init]{init()}} +} diff --git a/man/madChelsa.Rd b/man/madChelsa.Rd index 1b5a73b1..d0ef388e 100644 --- a/man/madChelsa.Rd +++ b/man/madChelsa.Rd @@ -92,7 +92,7 @@ catNames(madCover) # names of categories table plot(madCover) } \references{ -Karger, D.N., Conrad, O., Böhner, J., Kawohl, T., Kreft, H., Soria-Auza, R.W., Zimmermann, N.E., Linder, H.P., and Kessler, M. 2017. Climatologies at high resolution for the earth's land surface areas. \emph{Scientific Data} 4:170122. \doi{10.1038/sdata.2017.122} +Karger, D.N., Conrad, O., Bohner, J., Kawohl, T., Kreft, H., Soria-Auza, R.W., Zimmermann, N.E., Linder, H.P., and Kessler, M. 2017. Climatologies at high resolution for the earth's land surface areas. \emph{Scientific Data} 4:170122. \doi{10.1038/sdata.2017.122} } \keyword{Madagascar} \keyword{climate} diff --git a/man/mapset.Rd b/man/mapset.Rd index 4be3bc8c..b1abcf29 100644 --- a/man/mapset.Rd +++ b/man/mapset.Rd @@ -40,33 +40,37 @@ elev <- fast(madElev) chelsa1 <- fast(madChelsa1) # Name of the currently active location -.location() -.location(elev) -.location(chelsa1) +if (FALSE) { + + .location() + .location(elev) + .location(chelsa1) -# All available GRASS locations -.locations() + # All available GRASS locations + .locations() -# Find location of an object among all active locations -.locationFind(elev) -.locationFind(chelsa1) -.locationFind(chelsa1, return = "index") -.locationFind(chelsa1, return = "crs") + # Find location of an object among all active locations + .locationFind(elev) + .locationFind(chelsa1) + .locationFind(chelsa1, return = "index") + .locationFind(chelsa1, return = "crs") -# Switch between locations -.locationRestore(elev) -.locationRestore(chelsa1) + # Switch between locations + .locationRestore(elev) + .locationRestore(chelsa1) -loc <- .location(elev) -.locationRestore(loc) + loc <- .location(elev) + .locationRestore(loc) -# We could use .locationDelete(elev) to delete -# the location where "elev" is stored. + # Delete the location where "elev" is stored. + if (FALSE) .locationDelete(elev) # dangerous! -# Mapsets are always "PERMANENT" in fasterRaster -.mapset() -.mapset(elev) -.mapset(chelsa1) + # Mapsets are always "PERMANENT" in fasterRaster + .mapset() + .mapset(elev) + .mapset(chelsa1) + +} } } diff --git a/man/math.Rd b/man/math.Rd index bc4102f3..f1372b04 100644 --- a/man/math.Rd +++ b/man/math.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/05_GRaster_functions_byLayer.r +% Please edit documentation in R/05_GRaster_functions_by_layer.r \name{is.na,GRaster-method} \alias{is.na,GRaster-method} \alias{is.na} @@ -244,67 +244,5 @@ floor(elev + 0.5) ceiling(elev + 0.5) trunc(elev + 0.5) -# comparison -elev < 100 -elev <= 100 -elev == 100 -elev != 100 -elev > 100 -elev >= 100 - -elev + 100 < 2 * elev - -elevs > 10 -10 > elevs - -# logic -elev < 10 | elev > 200 -elev < 10 | cos(elev) > 0.9 - -elev < 10 | TRUE -TRUE | elev > 200 - -elev < 10 | FALSE -FALSE | elev > 200 - -elev < 10 & cos(elev) > 0.9 - -elev < 10 & TRUE -TRUE & elev > 200 - -elev < 10 & FALSE -FALSE & elev > 200 - -# Mathematical functions on GRasters with >= 2 layers: -mean(elevs) -mmode(elevs) -median(elevs) -nunique(elevs) - -sum(elevs) -count(elevs) -min(elevs) -max(elevs) -range(elevs) -skewness(elevs) -kurtosis(elevs) - -which.min(elevs) -which.max(elevs) - -slope(elevs) -intercept(elevs) -r2(elevs) -tvalue(elevs) - -stdev(elevs) -stdev(elevs, pop = FALSE) -var(elevs) -varpop(elevs) - -# Note: To get quantiles for each layer, use -# global(x, "quantile", probs = 0.2). -quantile(elevs, 0.1) - } } diff --git a/man/missingCats.Rd b/man/missingCats.Rd index 211088b0..d00a5065 100644 --- a/man/missingCats.Rd +++ b/man/missingCats.Rd @@ -133,12 +133,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/mow.Rd b/man/mow.Rd index a6b73110..2edbde7f 100644 --- a/man/mow.Rd +++ b/man/mow.Rd @@ -4,13 +4,15 @@ \alias{mow} \title{Remove unused rasters and vectors from the GRASS cache} \usage{ -mow(x, type = NULL, verbose = TRUE, ask = TRUE) +mow(x, type = NULL, keep = NULL, verbose = TRUE, ask = TRUE) } \arguments{ \item{x}{Either missing (default) or an environment.} \item{type}{Either \code{NULL} or a character vector. If \code{NULL}, all rasters and vectors in the \strong{GRASS} cache are candidates for deletion. Otherwise, this can be either \code{"raster"}, \code{"vector"}, or both.} +\item{keep}{Either \code{NULL} (default) or a \code{list()} of \code{GRaster}s and/or \code{GVector}s that you want to retain. The rasters and vectors in \strong{GRASS} pointed to by these objects will not be deleted.} + \item{verbose}{Logical: If \code{TRUE} (default), report progress.} \item{ask}{Logical: If \code{TRUE} (default), prompt for reassurance.} @@ -19,11 +21,9 @@ mow(x, type = NULL, verbose = TRUE, ask = TRUE) Invisibly returns a list with the number of rasters and vectors deleted. } \description{ -\strong{fasterRaster} attempts to remove intermediate rasters and vectors from the \strong{GRASS} cache as they are not needed, but files can still accumulate, especially if you remove \code{GRaster}s or \code{GVector}s from the \strong{R} working environment (e.g., by using \code{\link[=rm]{rm()}} or simply using the same variable name for different rasters/vectors). This function will a) search the \strong{GRASS} cache for all rasters/vectors there; and b) remove any of them that are not pointed to by an object in the active \strong{R} environment. - -Note that calling this function inside another function's environment can be very dangerous, as it will only be able to see objects in that environment, and thus delete any rasters/vectors outside that environment. +\strong{fasterRaster} attempts to delete rasters and vectors in the \strong{GRASS} cache. This function will a) search the current \strong{GRASS} "project/location" cache for all rasters/vectors there; and b) remove any of them that are not pointed to by an object in the active \strong{R} environment. Only objects in the currently active \strong{GRASS} project/location will be removed (see \code{vignette("project_mapset", package = "fasterRaster")}). -Note also that this function will only clean the current \strong{GRASS} "project"/"location" (see \code{vignette("projects_mapsets", package = "fasterRaster")}). +Note that calling this function inside another function's environment without providing an argument for \code{x} can be very \strong{dangerous}, as it will detect objects outside that environment, and thus delete any rasters/vectors outside that environment. } \examples{ if (grassStarted()) { @@ -33,5 +33,5 @@ if (FALSE) mow() } } \seealso{ -Option \code{clean} in \code{\link[=faster]{faster()}} +Option \code{clean} in \code{\link[=faster]{faster()}}; \code{\link[=grass]{grass()}} } diff --git a/man/nlevels.Rd b/man/nlevels.Rd index c0eb7e80..2f6c5814 100644 --- a/man/nlevels.Rd +++ b/man/nlevels.Rd @@ -129,12 +129,12 @@ levs <- data.frame( levels(elevCat) <- list(levs) # Combine levels: -combined <- combineCats(cover, elevCat) +combined <- concats(cover, elevCat) combined levels(combined) # Combine levels, treating value/NA combinations as new categories: -combinedNA <- combineCats(cover, elevCat, na.rm = FALSE) +combinedNA <- concats(cover, elevCat, na.rm = FALSE) combinedNA levels(combinedNA) diff --git a/man/pcs.Rd b/man/pcs.Rd index 5bda1687..bfedd09c 100644 --- a/man/pcs.Rd +++ b/man/pcs.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pca.r +% Please edit documentation in R/princomp.r \name{pcs} \alias{pcs} \title{Retrieve a principal components model from a PCA GRaster} @@ -7,7 +7,7 @@ pcs(x) } \arguments{ -\item{x}{A \code{GRaster} created by \code{\link[=pca]{pca()}}} +\item{x}{A \code{GRaster} created by \code{\link[=princomp]{princomp()}}} } \value{ An object of class \code{prcomp}. @@ -28,7 +28,7 @@ madChelsa <- fastData("madChelsa") chelsa <- fast(madChelsa) # Generate raster with layers representing principal component predictions: -pcRast <- pca(chelsa, scale = TRUE) +pcRast <- princomp(chelsa, scale = TRUE) plot(pcRast) # Get information on the PCA: @@ -41,5 +41,5 @@ plot(prinComp) } } \seealso{ -\code{\link[=pca]{pca()}}, \code{\link[stats:prcomp]{stats::prcomp()}}, module \code{i.pca} in \strong{GRASS} +\code{\link[=princomp]{princomp()}}, \code{\link[terra:princomp]{terra::princomp()}}, module \code{i.pca} in \strong{GRASS} } diff --git a/man/plot.Rd b/man/plot.Rd index 0f804ef9..480bbc2c 100644 --- a/man/plot.Rd +++ b/man/plot.Rd @@ -32,9 +32,6 @@ This function is essentially a hack, as it it not possible to dependably call th \examples{ if (grassStarted()) { -# Setup -library(terra) - # Example data madElev <- fastData("madElev") # elevation raster madLANDSAT <- fastData("madLANDSAT") # multi-layer raster diff --git a/man/plotRGB.Rd b/man/plotRGB.Rd index 24726c87..74c3c3f9 100644 --- a/man/plotRGB.Rd +++ b/man/plotRGB.Rd @@ -27,9 +27,6 @@ This function takes as its main argument a \code{GRaster} with at least three la \examples{ if (grassStarted()) { -# Setup -library(terra) - # Example data madElev <- fastData("madElev") # elevation raster madLANDSAT <- fastData("madLANDSAT") # multi-layer raster diff --git a/man/predict.Rd b/man/predict.Rd index 54750d94..5c5719ad 100644 --- a/man/predict.Rd +++ b/man/predict.Rd @@ -25,7 +25,7 @@ The model must be either a linear model, which is of class \code{lm} and typical This \code{predict()} function can handle: \itemize{ \item Linear predictors and intercepts like \code{y ~ 1 + x}; -\item Quadratic terms like \code{y ~ x^2} (or, in \strong{R} formular notation, \code{y ~ I(x^2)}); +\item Quadratic terms like \code{y ~ x^2} (or, in \strong{R} formula notation, \code{y ~ I(x^2)}); \item Two-way interaction terms between scalars like \code{y ~ x1:x2} and \code{y ~ x1 * x2}; \item Categorical predictors (i.e., categorical \code{GRaster}s; see \code{vignette("GRasters", package = "fasterRaster")})); \item Two-way interactions between a categorical predictor and a scalar predictor; and diff --git a/man/pca.Rd b/man/princomp.Rd similarity index 82% rename from man/pca.Rd rename to man/princomp.Rd index 4b9ef564..813487f7 100644 --- a/man/pca.Rd +++ b/man/princomp.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pca.r -\name{pca,GRaster-method} -\alias{pca,GRaster-method} -\alias{pca} +% Please edit documentation in R/princomp.r +\name{princomp,GRaster-method} +\alias{princomp,GRaster-method} +\alias{princomp} \title{Apply a principal component analysis (PCA) to layers of a GRaster} \usage{ -\S4method{pca}{GRaster}(x, scale = TRUE, scores = FALSE) +\S4method{princomp}{GRaster}(x, scale = TRUE, scores = FALSE) } \arguments{ \item{x}{A \code{GRaster} with two or more layers.} @@ -33,7 +33,7 @@ madChelsa <- fastData("madChelsa") chelsa <- fast(madChelsa) # Generate raster with layers representing principal component predictions: -pcRast <- pca(chelsa, scale = TRUE) +pcRast <- princomp(chelsa, scale = TRUE) plot(pcRast) # Get information on the PCA: @@ -46,5 +46,5 @@ plot(prinComp) } } \seealso{ -\code{\link[stats:prcomp]{stats::prcomp()}}; module \code{i.pca} in \strong{GRASS} +\code{\link[terra:princomp]{terra::princomp()}}, \code{\link[terra:prcomp]{terra::prcomp()}} } diff --git a/man/rasterize.Rd b/man/rasterize.Rd index 9eaac06d..483cbd8a 100644 --- a/man/rasterize.Rd +++ b/man/rasterize.Rd @@ -69,5 +69,5 @@ plot(byRiver) } } \seealso{ -\code{\link[terra:rasterize]{terra::rasterize()}}, module \href{https://grass.osgeo.org/grass84/manuals/v.to.rast.html}{\code{v.to.rast}} in \strong{GRASS} +\code{\link[terra:rasterize]{terra::rasterize()}}, \strong{GRASS} module \code{v.to.rast} (see \code{grassHelp("v.to.rast")}) } diff --git a/man/regress.Rd b/man/regress.Rd new file mode 100644 index 00000000..4f34709e --- /dev/null +++ b/man/regress.Rd @@ -0,0 +1,87 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/regress.r +\name{regress,GRaster,missing-method} +\alias{regress,GRaster,missing-method} +\alias{regress} +\title{Regression intercept, slope, r2, and t-value across each set of cells} +\usage{ +\S4method{regress}{GRaster,missing}(y, x, na.rm = FALSE) +} +\arguments{ +\item{y}{A multi-layer \code{GRaster}.} + +\item{x}{Ignored.} + +\item{na.rm}{Logical: If \code{FALSE}, any series of cells with \code{NA} in at least one cell results in an \code{NA} in the output.} +} +\value{ +A multi-layer \code{GRaster}. +} +\description{ +This function performs a regression on each set of cells in a multi-layered \code{GRaster}. The output is a \code{GRaster} with the intercept, slope, r^2 value, and Student's t value. The regression formula is as \code{y ~ 1 + x}, where \code{x} is the layer number of each layer (e.g., 1 for the first or top layer in the input \code{GRaster}, 2 for the second or second-to-top layer, etc.). Note that this is restricted version of the functionality in \code{\link[terra:regress]{terra::regress()}}. +} +\examples{ +if (grassStarted()) { + +# Setup +library(sf) +library(terra) + +# Example data +madChelsa <- fastData("madChelsa") + +# Convert a SpatRaster to a GRaster +chelsa <- fast(madChelsa) +chelsa # 4 layers + +# Central tendency +mean(chelsa) +mmode(chelsa) +median(chelsa) + +# Statistics +nunique(chelsa) +sum(chelsa) +count(chelsa) +min(chelsa) +max(chelsa) +range(chelsa) +skewness(chelsa) +kurtosis(chelsa) + +stdev(chelsa) +stdev(chelsa, pop = FALSE) +var(chelsa) +varpop(chelsa) + +# Which layers have maximum/minimum? +which.min(chelsa) +which.max(chelsa) + +# Regression +# Note the intercept is different for fasterRaster::regress(). +regress(chelsa) +regress(madChelsa, 1:nlyr(madChelsa)) + +# Note: To get quantiles for each layer, use +# global(x, "quantile", probs = 0.2). +quantile(chelsa, 0.1) + +# NAs +madForest2000 <- fastData("madForest2000") +forest2000 <- fast(madForest2000) +forest2000 <- project(forest2000, chelsa, method = "near") + +chelsaForest <- c(chelsa, forest2000) + +nas <- anyNA(chelsaForest) +plot(nas) + +allNas <- allNA(chelsaForest) +plot(allNas) + +} +} +\seealso{ +\code{\link[terra:regress]{terra::regress()}} +} diff --git a/man/replace_dollar.Rd b/man/replace_dollar.Rd index 60f8f1e2..aa7e7590 100644 --- a/man/replace_dollar.Rd +++ b/man/replace_dollar.Rd @@ -70,7 +70,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 diff --git a/man/replace_double_square_brackets.Rd b/man/replace_double_square_brackets.Rd index f7a5f978..5901826a 100644 --- a/man/replace_double_square_brackets.Rd +++ b/man/replace_double_square_brackets.Rd @@ -64,7 +64,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 diff --git a/man/replace_single_square_bracket.Rd b/man/replace_single_square_bracket.Rd index 3ee66edd..54987c9d 100644 --- a/man/replace_single_square_bracket.Rd +++ b/man/replace_single_square_bracket.Rd @@ -24,7 +24,7 @@ A \code{GRaster}. } \description{ -The \verb{[<-} operator can be used to replace all of the values of a \code{GRaster}, or specific values depending on the expression in \code{i}. For example, you could use \code{rast[] <- 10} to assign 10 to all cells, or \code{rast[rast > 0] <- 10} to assign all cells with values >0 to 10. +The \verb{[<-} operator can be used to replace all of the values of a \code{GRaster}, or specific values depending on the expression in \code{i}. For example, you could use \code{rast[] <- 10} to assign 10 to all cells, or \code{rast[rast > 0] <- 10} to assign all cells with values >0 to 10. You can also use one raster to set values in another, as in \code{rast1[rast2 > 0] <- 10}. } \examples{ if (grassStarted()) { @@ -72,7 +72,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 diff --git a/man/res.Rd b/man/res.Rd index 42717504..c216481c 100644 --- a/man/res.Rd +++ b/man/res.Rd @@ -48,7 +48,7 @@ A numeric vector. For both \code{res()} and \code{res3d()}, the first value is t Spatial resolution of a \code{GRaster}: \itemize{ \item \code{res()}: 2-dimensional resolution (x and y).\cr\cr -\item \code{res3d()}: 3-dimensinal resolution (z, y, and z).\cr\cr +\item \code{res3d()}: 3-dimensional resolution (z, y, and z).\cr\cr \item \code{xres()}, \code{yres()}, and \code{zres()}: East-west resolution, north-south resolution, and top-bottom resolution. } } @@ -176,3 +176,4 @@ layerCor(landsat, fun = 'cov') # covariance \seealso{ \code{\link[terra:dimensions]{terra::res()}} } +\keyword{res} diff --git a/man/resample.Rd b/man/resample.Rd index 03c08588..330a2999 100644 --- a/man/resample.Rd +++ b/man/resample.Rd @@ -105,5 +105,5 @@ plot(terraLanczos, add=TRUE) } } \seealso{ -\code{\link[terra:resample]{terra::resample()}}, modules \href{https://grass.osgeo.org/grass84/manuals/r.resample.html}{\code{r.resample}} and \href{https://grass.osgeo.org/grass84/manuals/r.resamp.interp.html}{\code{r.resamp.interp}} in \strong{GRASS} +\code{\link[terra:resample]{terra::resample()}}, \strong{GRASS} modules \code{r.resample} and \code{r.resamp.interp} (see \verb{grassHelp("}r.resample\verb{") and }grassHelp("\code{r.resamp.interp}")`) } diff --git a/man/segregate.Rd b/man/segregate.Rd new file mode 100644 index 00000000..0658ffee --- /dev/null +++ b/man/segregate.Rd @@ -0,0 +1,59 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/segregate.r +\name{segregate,GRaster-method} +\alias{segregate,GRaster-method} +\alias{segregate} +\title{Create one GRaster layer per unique value in a GRaster} +\usage{ +\S4method{segregate}{GRaster}(x, classes = NULL, keep = FALSE, other = 0, bins = 100, digits = 3) +} +\arguments{ +\item{x}{A \code{GRaster}.} + +\item{classes}{Either \code{NULL} (default) or a character vector with category labels for which to create outputs. If the input is not a categorical/factor or \code{integer} \code{GRaster}, this is ignored.} + +\item{keep}{Logical: If \code{FALSE} (default), then the original value in the input \code{GRaster} will be retained in the each of the output \code{GRaster} layers wherever the input had the respective value. Other cells will be assigned a value of \code{other}.} + +\item{other}{Numeric or \code{NA}: Value to assign to cells that do not have the target value.} + +\item{bins}{Numeric: Number of bins in which to put values. This is only used for \code{GRaster}s that are not categorical/factor rasters or \code{integer} rasters.} + +\item{digits}{Numeric: Number of digits to which to round input if it is a \code{numeric} or \code{double} \code{GRaster} (see \code{vignettes("GRasters", package = "fasterRaster")}).} +} +\value{ +If the input \code{x} is a single-layered \code{GRaster}, the output will be a multi-layered \code{GRaster} with one layer per value in the input, or one layer per values in \code{classes}. If the input is a multi-layered \code{GRaster}, the output will be a \code{list} of multi-layered \code{GRaster}s. +} +\description{ +This function creates a multi-layered \code{GRaster} for every unique values in an input \code{GRaster}. By default, the output will have a value of 1 wherever the input has the given value, and 0 elsewhere. This is useful for creating dummy variable \code{GRaster} layers for use with models that have factors, especially if the input \code{GRaster} is categorical. Note that the \code{\link[=predict]{predict()}} function in \strong{fasterRaster} usually does not need this treatment of \code{GRaster}s since it can handle categorical rasters already. +} +\examples{ +if (grassStarted()) { + +# Setup +library(terra) + +# Elevation and land cover raster +madElev <- fastData("madElev") # integer raster +madCover <- fastData("madCover") # categorical raster + +# Convert to GRasters +elev <- fast(madElev) +cover <- fast(madCover) + +# Subset elevation raster to just a few values to make example faster: +elevSubset <- elev[elev <= 3] +segregate(elevSubset) +segregate(elevSubset, keep = TRUE, other = -1) + +# Segregate the factor raster +segregate(cover) + +classes <- c("Grassland with mosaic forest", "Mosaic cropland/vegetation") +seg <- segregate(cover, classes = classes) +plot(seg) + +} +} +\seealso{ +\code{\link[terra:segregate]{terra::segregate()}} +} diff --git a/man/streams.Rd b/man/streams.Rd index 494eb973..d803dd21 100644 --- a/man/streams.Rd +++ b/man/streams.Rd @@ -34,7 +34,7 @@ A \code{GRaster}. } \description{ -This function estimates the course of streams and rivers from an elevation raster. It is based on the \strong{GRASS} module \verb{\\href\{https://grass.osgeo.org/grass84/manuals/r.stream.extract.html\}\{r.stream.extract\}}, where more details can be found. +This function estimates the course of streams and rivers from an elevation raster. It is based on the \strong{GRASS} module \code{r.stream.extract}, where more details can be found (see \code{grassHelp("r.stream.extract")}) } \examples{ if (grassStarted()) { @@ -55,5 +55,5 @@ plot(streams) } } \seealso{ -\code{\link[=flow]{flow()}}, \code{\link[=flowPath]{flowPath()}}, the \verb{\\href\{https://grass.osgeo.org/grass84/manuals/r.stream.extract.html\}\{r.stream.extract\}} module in \strong{GRASS} +\code{\link[=flow]{flow()}}, \code{\link[=flowPath]{flowPath()}}, \strong{GRASS} module \code{r.stream.extract} (see \code{grassHelp("r.stream.extract")}) } diff --git a/man/stretch.Rd b/man/stretch.Rd index caa2609a..f65ed648 100644 --- a/man/stretch.Rd +++ b/man/stretch.Rd @@ -3,7 +3,7 @@ \name{stretch,GRaster-method} \alias{stretch,GRaster-method} \alias{stretch} -\title{Rescale values in a raster} +\title{Rescale values in a GRaster} \usage{ \S4method{stretch}{GRaster}(x, minv = 0, maxv = 255, minq = 0, maxq = 1, smin = NA, smax = NA) } diff --git a/man/subset.Rd b/man/subset.Rd new file mode 100644 index 00000000..a3faccac --- /dev/null +++ b/man/subset.Rd @@ -0,0 +1,136 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/subset.r +\docType{methods} +\name{subset,GRaster-method} +\alias{subset,GRaster-method} +\alias{subset} +\alias{subset,GVector-method} +\title{Subset layers from a GRaster, or specific rows from a GVector} +\usage{ +\S4method{subset}{GRaster}(x, subset, negate = FALSE) + +\S4method{subset}{GVector}(x, subset, negate = FALSE) +} +\arguments{ +\item{x}{A \code{GRaster} or \code{GVector}.} + +\item{subset}{Numeric integer, integer, logical, or character: Indicates the layer(s) of a \code{GRaster} to subset, or the rows(s) of a \code{GVector} to return.} + +\item{negate}{Logical: If \code{TRUE}, all layers or rows in \code{subset} will be \emph{removed} from the output. Default is \code{FALSE}.} +} +\value{ +A \code{GRaster} or \code{GVector}. +} +\description{ +\code{subset()} can be used to subset or remove one or more layers from a \code{GRaster}. It can also be used to subset or remove rows from a \code{GVector} with a data table. +} +\examples{ +if (grassStarted()) { + +# Setup +library(terra) + +### GRasters +############ + +# Example data +madElev <- fastData("madElev") # elevation raster +madForest2000 <- fastData("madForest2000") # forest raster +madForest2014 <- fastData("madForest2014") # forest raster + +# Convert SpatRasters to GRasters +elev <- fast(madElev) +forest2000 <- fast(madForest2000) +forest2014 <- fast(madForest2014) + +### Re-assigning values of a GRaster +constant <- elev +constant[] <- pi +names(constant) <- "pi_raster" +constant + +### Re-assigning specific values of a raster +replace <- elev +replace[replace == 1] <- -20 +replace + +### Subsetting specific values of a raster based on another raster +elevInForest <- elev[forest2000 == 1] +plot(c(elev, forest2000, elevInForest), nr = 1) + +### Adding and replacing layers of a GRaster +rasts <- c(elev, constant, forest2000) + +# Combine with another layer: +add(rasts) <- forest2014 # one way +rasts + +rasts <- c(rasts, forest2014) # another way + +### Subsetting GRaster layers + +# Subset: +rasts <- c(elev, forest2000, forest2014) +rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) +rasts[[c("madForest2000", "madElev")]] +rasts$madForest2000 + +# Get every other layer: +rasts[[c(FALSE, TRUE)]] + +### Replacing layers of a GRaster + +# Replace a layer +logElev <- log(elev) +names(logElev) <- "logElev" +rasts$madForest2014 <- logElev +rasts + +# Replace a layer: +rasts[[3]] <- forest2000 +rasts + +### GVectors +############ + +# example data +madDypsis <- fastData("madDypsis") # vector of points + +# Convert SpatVector to GVector +dypsis <- fast(madDypsis) + +### Retrieving GVector columns + +dypsis$species # Returns the column + +dypsis[[c("year", "species")]] # Returns a GRaster with these columns +dypsis[ , c("year", "species")] # Same as above + +### Subsetting GVector geometries + +# Subset first three geometries +dypsis[1:3] +dypsis[1:3, "species"] + +# Get geometries by data table condition +dypsis[dypsis$species == "Dypsis betsimisarakae"] + +### (Re)assigning GVector column values + +# New column +dypsis$pi <- pi + +# Re-assign values +dypsis$pi <- "pie" + +# Re-assign specific values +dypsis$institutionCode[dypsis$institutionCode == "MO"] <- + "Missouri Botanical Garden" + +} +} +\seealso{ +\code{\link[fasterRaster]{[[}}, \code{\link[fasterRaster]{[}} +} diff --git a/man/subset_dollar.Rd b/man/subset_dollar.Rd index 336e58c0..3074ecd0 100644 --- a/man/subset_dollar.Rd +++ b/man/subset_dollar.Rd @@ -68,7 +68,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 @@ -127,5 +130,5 @@ dypsis$institutionCode[dypsis$institutionCode == "MO"] <- } } \seealso{ -\code{\link[fasterRaster]{[}}, \code{\link[fasterRaster]{[[}} +\code{\link[=subset]{subset()}}, \code{\link[fasterRaster]{[}}, \code{\link[fasterRaster]{[[}} } diff --git a/man/subset_double_square_brackets.Rd b/man/subset_double_square_brackets.Rd index a254a791..bdac7600 100644 --- a/man/subset_double_square_brackets.Rd +++ b/man/subset_double_square_brackets.Rd @@ -70,7 +70,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 @@ -128,3 +131,6 @@ dypsis$institutionCode[dypsis$institutionCode == "MO"] <- } } +\seealso{ +\code{\link[=subset]{subset()}} +} diff --git a/man/subset_single_bracket.Rd b/man/subset_single_bracket.Rd index 30ac8f11..9d933160 100644 --- a/man/subset_single_bracket.Rd +++ b/man/subset_single_bracket.Rd @@ -72,7 +72,10 @@ rasts <- c(rasts, forest2014) # another way ### Subsetting GRaster layers # Subset: +rasts <- c(elev, forest2000, forest2014) rasts[[2:3]] +subset(rasts, 2:3) +subset(rasts, c("madForest2000", "madElev")) rasts[[c("madForest2000", "madElev")]] rasts$madForest2000 @@ -131,5 +134,5 @@ dypsis$institutionCode[dypsis$institutionCode == "MO"] <- } } \seealso{ -\link{$}, \code{\link[fasterRaster]{[[}} +\code{\link[=subset]{subset()}}, \link{$}, \code{\link[fasterRaster]{[[}} } diff --git a/man/sun.Rd b/man/sun.Rd index 6c54ab55..06411cb5 100644 --- a/man/sun.Rd +++ b/man/sun.Rd @@ -46,7 +46,7 @@ sun( \item{albedo}{A \code{GRaster} or a numeric value: This is either a raster with values of ground albedo or a numeric value (in which case albedo is assumed to be the same everywhere). Albedo is unit-less, and the default value is 0.2.} -\item{linke}{A \code{GRaster} or a numeric value: This is either a raster with values of the Linke atmospheric turbidity coefficient or a numeric value (in which case the same value is assumed for all locations). The Linke coefficient is unit-less. The default value is 3, but see also the \strong{GRASS} manual page for module \href{https://grass.osgeo.org/grass84/manuals/r.sun.html}{\code{r.sun}}.} +\item{linke}{A \code{GRaster} or a numeric value: This is either a raster with values of the Linke atmospheric turbidity coefficient or a numeric value (in which case the same value is assumed for all locations). The Linke coefficient is unit-less. The default value is 3, but see also the \strong{GRASS} manual page for module \code{r.sun} (\code{grassHelp("r.sun")}).} \item{day}{Positive integer between 1 to 365, inclusive: Day of year for which to calculate ir/radiation. Default is 1 (January 1st).} @@ -83,7 +83,7 @@ A raster or raster stack stack with the same extent, resolution, and coordinate } } \description{ -The \code{sun()} function calculates beam (direct), diffuse and ground reflected solar irradiation for a given day and set of topographic and atmospheric conditions. The function relies on the \strong{GRASS} module \href{https://grass.osgeo.org/grass84/manuals/r.sun.html}{\code{r.sun}}, which contains a detailed explanation. +The \code{sun()} function calculates beam (direct), diffuse and ground reflected solar irradiation for a given day and set of topographic and atmospheric conditions. The function relies on the \strong{GRASS} module \code{r.sun}, the manual page for which contains a detailed explanation (see \code{grassHelp("r.sun")}) } \examples{ if (grassStarted()) { @@ -146,5 +146,5 @@ solar } } \seealso{ -\code{\link[=terrain]{terrain()}}, \code{\link[=horizonHeight]{horizonHeight()}}, module \href{https://grass.osgeo.org/grass84/manuals/r.sun.html}{\code{r.sun}} in \strong{GRASS} +\code{\link[=terrain]{terrain()}}, \code{\link[=horizonHeight]{horizonHeight()}}, \strong{GRASS} module \code{r.sun}(see \code{grassHelp("r.sun")}) } diff --git a/man/vAttachDatabase.Rd b/man/vAttachDatabase.Rd index f5f27842..ed655a8a 100644 --- a/man/vAttachDatabase.Rd +++ b/man/vAttachDatabase.Rd @@ -11,9 +11,9 @@ \item{table}{Either \code{NULL} (default), or a \code{data.frame} or \code{data.table}, or a numeric or integer vector: \itemize{ -\item If \code{NULL}, then a bare minimal table will be created with a column named \code{frid}, holding sequential integer values. -\item If a \code{data.frame} or \code{data.table} and no column is named \code{frid}, one will be created with sequential integer values. If the table does have a column named \code{frid}, then it should have integer (not just numeric) values. -\item If a \code{vector}, then these are coerced to type \code{integer} and used to define the \code{frid} column. +\item If \code{NULL}, then a bare minimal table will be created with a column named \code{cat}, holding sequential integer values. +\item If a \code{data.frame} or \code{data.table} and no column is named \code{cat}, one will be created with sequential integer values. If the table does have a column named \code{cat}, then it should have integer (not just numeric) values. +\item If a \code{vector}, then these are coerced to type \code{integer} and used to define the \code{cat} column. } There should be one row/value per geometry in \code{x}.} @@ -26,6 +26,6 @@ There should be one row/value per geometry in \code{x}.} Invisibly returns the \code{\link[=sources]{sources()}} name of a vector in \strong{GRASS}. } \description{ -\code{.vAttachDatabase()} adds a table to a \strong{GRASS} vector. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the \code{GVector} slot `@table``. Some functions require tables (e.g., \code{\link[=extract]{extract()}} and \code{\link[=spatSample]{spatSample()}}). \strong{This function is mostly of use to developers.} +\code{.vAttachDatabase()} adds a table to a \strong{GRASS} vector. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the \code{GVector} slot \verb{@table}. Some functions require tables (e.g., \code{\link[=extract]{extract()}} and \code{\link[=spatSample]{spatSample()}}). \strong{This function is mostly of use to developers.} } \keyword{internal} diff --git a/man/vDetachDatabase.Rd b/man/vDetachDatabase.Rd index 0385ff0a..f0b5893e 100644 --- a/man/vDetachDatabase.Rd +++ b/man/vDetachDatabase.Rd @@ -13,6 +13,6 @@ Invisibly returns the \code{\link[=sources]{sources()}} name of a vector in \strong{GRASS}. } \description{ -\code{.vDetachDatabase()} detaches the database from a \strong{GRASS} vector and deletes it. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the \code{GVector} slot `@table``. Some functions do require tables (e.g., \code{\link[=extract]{extract()}} and \code{\link[=spatSample]{spatSample()}}). \strong{This function is mostly of use to developers.} +\code{.vDetachDatabase()} detaches the database from a \strong{GRASS} vector and deletes it. This table is meant to be "invisible" to most users--they should use interact with attribute tables using the \code{GVector} slot \verb{@table}. Some functions do require tables (e.g., \code{\link[=extract]{extract()}} and \code{\link[=spatSample]{spatSample()}}). \strong{This function is mostly of use to developers.} } \keyword{internal} diff --git a/man/wetness.Rd b/man/wetness.Rd index ce44af4c..6f8e2980 100644 --- a/man/wetness.Rd +++ b/man/wetness.Rd @@ -39,5 +39,5 @@ plot(c(elev, twi)) } } \seealso{ -\code{\link[=terrain]{terrain()}}, \code{\link[=ruggedness]{ruggedness()}}, \code{\link[=geomorphons]{geomorphons()}}, module \href{https://grass.osgeo.org/grass84/manuals/r.topidx.html}{\code{r.topidx}} in \strong{GRASS} +\code{\link[=terrain]{terrain()}}, \code{\link[=ruggedness]{ruggedness()}}, \code{\link[=geomorphons]{geomorphons()}}, \strong{GRASS} module \code{r.topidx} (see \code{grassHelp("r.topidx")}) } diff --git a/man/workDir.Rd b/man/workDir.Rd index 8402712a..113e9550 100644 --- a/man/workDir.Rd +++ b/man/workDir.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/workDir.r -\name{workDir,GLocation-method} -\alias{workDir,GLocation-method} -\alias{workDir} +\name{.workDir,GLocation-method} +\alias{.workDir,GLocation-method} +\alias{.workDir} \title{Get a GLocation's working directory} \usage{ -\S4method{workDir}{GLocation}(x) +\S4method{.workDir}{GLocation}(x) } \arguments{ \item{x}{A \code{GLocation} object.} @@ -16,3 +16,4 @@ Character. \description{ This function returns the working directory of a \code{GLocation} object. } +\keyword{internal} diff --git a/man/writeRaster.Rd b/man/writeRaster.Rd index 8d3b89a8..de7f1b6f 100644 --- a/man/writeRaster.Rd +++ b/man/writeRaster.Rd @@ -80,7 +80,7 @@ A \code{GRaster} (invisibly). A raster is also saved to disk. \description{ This function saves a \code{GRaster} to disk directly from a \strong{GRASS} session. It is faster than using \code{\link[=rast]{rast()}}, then saving the output of that to disk (because \code{rast()} actually save the raster to disk, anyway). -The function will attempt to ascertain the file type to be ascertained from the file extension, but you can specify the format using the \code{format} argument (see entry for \code{...}). You can see a list of supported formats by simply using this function with no arguments, as in \code{writeRaster()}, or by consulting the online help page for the \strong{GRASS} module \href{https://grass.osgeo.org/grass84/manuals/r.out.gdal.html}{\code{r.out.gdal}}. Only the \code{GeoTIFF} file format is guaranteed to work for multi-layered rasters. +The function will attempt to ascertain the file type to be ascertained from the file extension, but you can specify the format using the \code{format} argument (see entry for \code{...}). You can see a list of supported formats by simply using this function with no arguments, as in \code{writeRaster()}, or by consulting the online help page for the \strong{GRASS} module \code{r.out.gdal} (see \code{grassHelp("r.out.gdal")}). Only the \code{GeoTIFF} file format is guaranteed to work for multi-layered rasters. The function will attempt to optimize the \code{datatype} argument, but this can take a long time. You can speed this up by setting \code{datatype} manually. Note that if you are saving a "stack" of \code{GRaster}s with different \code{datatype}s, the one with the highest information density will be used (e.g., low-bit integer < high-bit integer < floating-point < double-floating point). This can make rasters with lower datatypes much larger on disk. In these cases, it make be best to save rasters with similar \code{datatype}s together. } @@ -128,5 +128,5 @@ chelsaBio1 } } \seealso{ -\code{\link[terra:writeRaster]{terra::writeRaster()}}, module \href{https://grass.osgeo.org/grass84/manuals/r.out.gdal.html}{\code{r.out.gdal}} in \strong{GRASS} +\code{\link[terra:writeRaster]{terra::writeRaster()}}, \strong{GRASS} module \code{r.out.gdal} (see \code{grassHelp("r.out.gdal")}) } diff --git a/man/writeVector.Rd b/man/writeVector.Rd index 9cb0d377..dc2d08cb 100644 --- a/man/writeVector.Rd +++ b/man/writeVector.Rd @@ -37,7 +37,7 @@ \item{attachTable}{Logical: If \code{TRUE} (default), attach the attribute to table to the vector before saving it. If \code{FALSE}, the attribute table will not be attached.} -\item{...}{Additional arguments to send to \strong{GRASS} module \href{https://grass.osgeo.org/grass84/manuals/v.out.ogr.html}{\code{v.out.ogr}} in \strong{GRASS}.} +\item{...}{Additional arguments to send to \strong{GRASS} module \code{v.out.ogr} (see \code{grassHelp("v.out.ogr")}).} } \value{ Invisibly returns a \code{GRaster} (the input, \code{x}). Also saves the vector to disk. @@ -45,7 +45,7 @@ Invisibly returns a \code{GRaster} (the input, \code{x}). Also saves the vector \description{ This function saves a \code{GVector} to disk directly from a \strong{GRASS} session. -By default, files will be of OGC GeoPackage format (extension "\code{.gpkg}"), but this can be changed with the \code{format} argument. You can see a list of supported formats by simply using this function with no arguments, as in \code{writeVector()}, or by consulting the online help page for \strong{GRASS} module \href{https://grass.osgeo.org/grass84/manuals/v.out.ogr.html}{\code{v.out.ogr}}. +By default, files will be of OGC GeoPackage format (extension "\code{.gpkg}"), but this can be changed with the \code{format} argument. You can see a list of supported formats by simply using this function with no arguments, as in \code{writeVector()}, or by consulting the online help page for \strong{GRASS} module \code{v.out.ogr} (see \code{grassHelp("v.out.ogr")}). Note that if the vector has a data table attached and at least one numeric or integer column has an \code{NA} or \code{NaN} value, the function will yield a warning like: @@ -97,7 +97,7 @@ writeVector(rivers, filename) } } \seealso{ -\code{\link[terra:writeVector]{terra::writeVector()}}, \code{\link[sf:st_write]{sf::st_write()}}, module \href{https://grass.osgeo.org/grass84/manuals/v.out.ogr.html}{\code{v.out.ogr}} in \strong{GRASS} +\code{\link[terra:writeVector]{terra::writeVector()}}, \code{\link[sf:st_write]{sf::st_write()}}, \strong{GRASS} module \code{v.out.ogr} (see \code{grassHelp("v.out.ogr")}) \code{\link[terra:writeVector]{terra::writeVector()}} } diff --git a/man/xor.Rd b/man/xor.Rd index 5c1da819..06cd28b0 100644 --- a/man/xor.Rd +++ b/man/xor.Rd @@ -14,7 +14,7 @@ A \code{GVector}. } \description{ -The \code{xor()} function selects the area that does not overlap between two "polygon" \code{GVector}s. You can also use the \code{/} operator, as in \verb{vect 1 / vect2}. +The \code{xor()} function selects the area that does \emph{not} overlap between two "polygon" \code{GVector}s. You can also use the \code{/} operator, as in \code{vect1 / vect2}. } \examples{ if (grassStarted()) { @@ -68,5 +68,5 @@ minus <- coast4 - hull # same as erase() } } \seealso{ -\code{\link[=c]{c()}}, \code{\link[=aggregate]{aggregate()}}, \code{\link[=crop]{crop()}}, \code{\link[=intersect]{intersect()}}, \code{\link[=union]{union()}}, \code{\link[=erase]{erase()}} +\code{\link[=crop]{crop()}}, \code{\link[=intersect]{intersect()}}, \code{\link[=union]{union()}}, \code{\link[=erase]{erase()}} } diff --git a/vignettes/GRasters.Rmd b/vignettes/GRasters.Rmd index d5cfb776..98fabe35 100644 --- a/vignettes/GRasters.Rmd +++ b/vignettes/GRasters.Rmd @@ -14,20 +14,21 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +fig.path = 'man/figures/' ``` -**fasterRaster** `GRaster`s can represent double-floating point numeric values, integers, or categorical data. +**fasterRaster** `GRaster`s can represent double-floating point numeric values, integers, or categorical/factor data. -## Double-floating point values +## Double-floating point value Double-floating point values are accurate to about the 15th to 17th decimal place. These are called "double" rasters in **fasterRaster** and `DCELL` rasters in **GRASS**. These rasters typically take the most memory. All `numeric` values in **R** are double-floating point values. -## Floating point values +## Floating point value Less common that double-floating point rasters, floating point rasters are accurate to about the 7th decimal place. These are called "float" rasters in **fasterRaster** and `FCELL` rasters in **GRASS**. These rasters typically take less memory than double-floating point rasters. -## Integers +## Integer Rasters that represent integers are called "integer" rasters in **fasterRaster** and `CELL` rasters in **GRASS**. You can force a raster to be an integer using [`as.int()`](https://adamlilith.github.io/fasterRaster/reference/as.int.html). Some of the functions in [`app()`](https://adamlilith.github.io/fasterRaster/reference/app.html) function will also return integer-type rasters. Integer rasters typically take the least memory. -## Categories +## Categorical/factor Categorical rasters (also called "factor" rasters) are actually integer rasters, but have an associated attribute table that maps each integer value to a category label, such as "wetland" or "forest". The table has at least two columns. The first is integer values, and (by default) the second is category names. This second column is the "active" category column that is used for plotting and in some functions. The active column can be changed using [`activeCat<-`](https://adamlilith.github.io/fasterRaster/reference/activeCat.html). ## Functions relevant to raster data types @@ -46,9 +47,9 @@ Categorical rasters (also called "factor" rasters) are actually integer rasters, * [`addCats<-`](https://adamlilith.github.io/fasterRaster/reference/addCats.html) add new levels to a "levels" table. * [`catNames()`](https://adamlilith.github.io/fasterRaster/reference/catNames.html) reports the column names of the "levels" table of each layer of a raster. * [`cats()`](https://adamlilith.github.io/fasterRaster/reference/cats.html) returns the entire "levels" table of a categorical raster. -* [`combineCats()`](https://adamlilith.github.io/fasterRaster/reference/combineCats.html) combines levels of two or more categorical or integer rasters. * [`combineLevels()`](https://adamlilith.github.io/fasterRaster/reference/combineLevels.html): Combine the "levels" tables of two or more categorical `GRaster`s. * [`complete.cases()`](https://adamlilith.github.io/fasterRaster/reference/complete.cases.html) finds rows in the levels table that have no `NA`s. +* [`concats()`](https://adamlilith.github.io/fasterRaster/reference/combineCats.html) combines levels of two or more categorical or integer rasters by concatenating them. * [`droplevels()`](https://adamlilith.github.io/fasterRaster/reference/dropevels.html) removes "unused" levels in a "levels" table. * [`levels()`](https://adamlilith.github.io/fasterRaster/reference/levels.html) returns the "levels" table of a categorical raster (just the value column and the active column). * [`levels<-`](https://adamlilith.github.io/fasterRaster/reference/levels.html) and [`categories()`](https://adamlilith.github.io/fasterRaster/reference/categories.html) can be used to assign categories to an integer raster and make it categorical (i.e., a "factor" raster). diff --git a/vignettes/fasterRaster.Rmd b/vignettes/fasterRaster.Rmd index 150aa45a..af2c6ee5 100644 --- a/vignettes/fasterRaster.Rmd +++ b/vignettes/fasterRaster.Rmd @@ -17,6 +17,7 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +fig.path = 'man/figures/' ``` **fasterRaster** interfaces with **GRASS GIS** to process rasters and spatial vector data. It is intended as an add-on to the **terra** and **sf** packages, and relies heavily upon them. For most rasters and vectors that are small or medium-sized in memory/disk, those packages will almost always be faster. They may also be faster for very large objects. But when they aren't, **fasterRaster** can step in. @@ -152,7 +153,7 @@ You can do operations on `GRaster`s and `GVector`s as if they were `SpatRaster`s plot(elev) plot(rivers, col = 'lightblue', add = TRUE) ``` -![](man/figures/elev_rivers.png) +![Elevation and rivers](./images/elev_rivers.png) You can use mathematical operators and functions: @@ -190,7 +191,7 @@ max. value : 2.75587485567249 You can also use the many **fasterRaster** functions. In general, these functions have the same names as their **terra** counterparts and often the same arguments. Note that even many **terra** and **fasterRaster** functions have the same name, they do not necessarily produce the exact same output. Much care has been taken to ensure they do, but sometimes there are multiple ways to do the same task, so choices made by the authors of **terra** and **GRASS** can lead to differences. -The following code creates a a) raster where cell values reflect the distance between them and the nearest river; b) creates a buffer around the rivers; then c) plots the output: +The following code 1) creates a raster where cell values reflect the distance between them and the nearest river; b) makes a buffer around the rivers; then c) plots the output: ```{r distance_buffers, eval = FALSE} dist <- distance(elev, rivers) dist @@ -223,7 +224,7 @@ plot(dist) plot(rivers, col = 'lightblue', add = TRUE) plot(river_buff, border = 'white', add = TRUE) ``` -![](man/figures/dist_to_rivers.png) +![Distance between each cell and nearest major river](./images/dist_to_rivers.png) And that's how you get started! Now that you have a raster and a vector in your **fasterRaster** "location", you can start doing manipulations and analyses using any of the **fasterRaster** functions! To see an annotated list of these functions, use `?fasterRaster`. diff --git a/vignettes/faster_fasterRaster.Rmd b/vignettes/faster_fasterRaster.Rmd index 0e2421c2..f665c94e 100644 --- a/vignettes/faster_fasterRaster.Rmd +++ b/vignettes/faster_fasterRaster.Rmd @@ -14,6 +14,7 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +fig.path = 'man/figures/' ``` There are several ways to speed up **fasterRaster** functions. These are listed below in order of their most likely gains, with the first few being potentially the largest. @@ -24,8 +25,8 @@ There are several ways to speed up **fasterRaster** functions. These are listed 3. **Increase memory and the number of cores usable by GRASS:** By default, `fasterRaster` use 2 cores and 2048 MB (2 GB) of memory for `GRASS` modules that allow users to specify these values. You can set these to higher values using [`faster()`](https://adamlilith.github.io/fasterRaster/reference/faster.html) and thus potentially speed up some calculations. Functions in newer versions of `GRASS` have more capacity to use these options, so updating `GRASS` to the latest version can help, too. -4. **Turn off automatic removal of temporary files in the disk cache:** To obviate problems with disk space filling up, by default most **fasterRaster** functions delete intermediate files. However, if you are not creating a lot of very big `GRaster`s or `GVector`s, you can skip this time-taking step by setting the `clean` option to `FALSE` using `faster(clean = FALSE)`. By default, this setting is `TRUE`. +4. **Turn off automatic removal of temporary files in the disk cache:** To obviate problems with disk space filling up, by default most **fasterRaster** functions delete intermediate files. However, if you are not creating a lot of very big `GRaster`s or `GVector`s, you can skip this time-taking step by setting the `clean` option to `FALSE` using `faster(clean = FALSE)`. By default, this setting is `TRUE`. This can save a few seconds of runtime for functions that create temporary files. -5. **Do operation on `GRaster`s and `GVector`s in the same coordinate reference system together:** Every time you switch between using a `GRaster` or `GVector` with a different coordinate reference system (CRS), `GRASS` has to spend a few second changing to that CRS. So, you can save some time by doing as much work as possible with objects in one CRS, then switching to work on objects in another CRS. +5. **Do operations on `GRaster`s and `GVector`s in the same coordinate reference system together:** Every time you switch between using a `GRaster` or `GVector` with a different coordinate reference system (CRS), `GRASS` has to spend a few seconds changing to that CRS. You can save some time by doing as much work as possible with objects in one CRS, then switching to work on objects in another CRS. ~ FINIS ~ diff --git a/vignettes/hidden_functions.Rmd b/vignettes/hidden_functions.Rmd index 5a7b3f42..586f5874 100644 --- a/vignettes/hidden_functions.Rmd +++ b/vignettes/hidden_functions.Rmd @@ -14,39 +14,34 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +fig.path = 'man/figures/' ``` **fasterRaster** contains a set of "private" functions that users can access using `fasterRaster:::functionName`. These functions are useful for power users and developers. Not all hidden functions are listed here. Often, a method will have a hidden function of the same name that starts with a period (e.g., `.plot()`). This "period" function is intended to be supplied the [`sources()`](https://adamlilith.github.io/fasterRaster/reference/sources.html) name of a `GRaster` or `GVector` from other functions so that the calling function does not need to spend the time creating the `GRaster` or `GVector` pointer before calling the function. "Period" functions will, though, often work on `GRaster`s or `GVector`s, though some error-checking and region re-definition is not conducted. -* `.aggDisaggVect()`: Aggregate or disaggregate a vector using its [`sources()`](https://adamlilith.github.io/fasterRaster/reference/sources.html) name. -* `.copyGSpatial()`: Make a copy of the **GRASS** file pointed to by a `GRaster` or `GVector` +## General +* `.addLocationProject()`: Add a "location" or "project" argument to a list to be passed to [rgrass::execGRASS()] +* `.backdoor()`: Calls [faster()] and sets **GRASS** folder to "C:/Program Files/GRASS GIS X.Y", plus other options useful for development. * `.fileExt()`: Get file extension +* `.ls()`: Lists the `sources` of all objects in the active **GRASS** "project/location" +* `.message()`: Display a warning or message if the given warning has not been displayed since **fasterRaster** was attached or if a given number of hours has passed +* `.quiet()`: Returns "quiet" if `faster("verbose")` is `TRUE` +* `.workDir()`: Working directory of a `GLocation` object + +## Rasters and vectors +* `.copyGSpatial()`: Make a copy of the **GRASS** file pointed to by a `GRaster` or `GVector` * `.exists()`: Does the **GRASS** file of a `GRaster` or `GVector` exist? * `.ext()`: Extent from the [`sources()`](https://adamlilith.github.io/fasterRaster/reference/sources.html) name of a `GRaster` or `GVector` -* `.geomtype()`: Geometry type ("point", "line", or "area") from the [`sources()`](https://adamlilith.github.io/fasterRaster/reference/sources.html) name of a `GVector` -* `.layerIndex()`: Gets the index of `GRaster` layers from a numeric, integer, character, or logical vector -* `.locationCreate()` Make a connection to **GRASS** (i.e., start **GRASS** from within **R**) and create a location -* `.locationDelete()` Deletes all files associated with a **GRASS** "location" and mapset -* `.locationFind()`: Find a specific **GRASS** "location" that already exists -* `.locationRestore()` Reconnect **GRASS** to a previously-created **GRASS** "location" -* `.locations()`: List of all available "locations" -* `.ls()`: Lists the `sources` of all objects in the active **GRASS** "location" -* `.makeGRaster()` and `.makeGVector()`: Make `GRaster`s or `GVector`s from a vector of `sources`, which are pointers to files in **GRASS** * `.makeSourceNames()`: Makes one or more statistically unique strings that can be used as file names to represent rasters or vectors in **GRASS** -* `.mapset()`: **GRASS** "mapset" of an object or the active session -* `.message()`: Display a warning or message if the given warning has not been displayed since **fasterRaster** was attached or if a given number or hours has passed since then -* `.minVal()` and `.maxVal()`: Values in the `@minVal` and `@maxVal` slots in a `GRaster` -* `.nlevels()`: Number of levels in a `SpatVector`, `data.frame`, `data.table`, empty string, or a list of `data.frame`s, `data.table`s, and/or empty strings. * `.plot()`: Plot using the [`sources()`](https://adamlilith.github.io/fasterRaster/reference/sources.html) name of a `GRaster` or `GVector` * `.projection()`: Value of the `@projection` slot in a `GRaster` or `GVector` -* `.quiet()`: Returns "quiet" if `faster("verbose")` is `TRUE` * `.rastInfo()` and `.vectInfo()`: Metadata for a **GRASS** raster or vector -* `.region()`: Change or report the active region's extent and resolution -* `.regionDim()]`: Change or report the active region's resolution (also [`dim()`](https://adamlilith.github.io/fasterRaster/reference/dim.html) and related functions, with no arguments) -* `.regionExt()`: Change or report the active region's extent (also [`ext()`](https://adamlilith.github.io/fasterRaster/reference/ext.html) and related functions, with no arguments) -* `.regionRes()`: Change or report the active region's dimensions (also [`res()`](https://adamlilith.github.io/fasterRaster/reference/res.html) and related functions, with no arguments) * `.rename()`: Rename a **GRASS** raster or vector * `.rm()`: Delete rasters or vectors in **GRASS** + +## Vectors +* `.aggDisaggVect()`: Aggregate or disaggregate a vector using its [`sources()`](https://adamlilith.github.io/fasterRaster/reference/sources.html) name. +* `.geomtype()`: Geometry type ("point", "line", or "area") from the [`sources()`](https://adamlilith.github.io/fasterRaster/reference/sources.html) name of a `GVector` * `.validVector()`: Test if a `GVector` is valid. * `.vAsDataTable()`: Convert the attribute table linked to a vector in **GRASS** to a `data.table`. This table is distinct from the attribute table attached to a `GVector` * `.vAttachDatabase()`: Add a database table to the **GRASS** representation of a `GVector` @@ -58,5 +53,24 @@ knitr::opts_chunk$set( * `.vRecat()`: Change **GRASS** category indices of a **GRASS** vector * `.vValidCats()`: Are category values of a vector valid? -~ FINIS ~ +## Rasters +* `.layerIndex()`: Gets the index of `GRaster` layers from a numeric, integer, character, or logical vector +* `.makeGRaster()` and `.makeGVector()`: Make `GRaster`s or `GVector`s from a vector of `sources`, which are pointers to files in **GRASS** +* `.minVal()` and `.maxVal()`: Values in the `@minVal` and `@maxVal` slots in a `GRaster` +* `.nlevels()`: Number of levels in a `SpatVector`, `data.frame`, `data.table`, empty string, or a list of `data.frame`s, `data.table`s, and/or empty strings. +## **GRAS** "Projects" ("locations") and "mapsets" +* `.locationCreate()` Make a connection to **GRASS** (i.e., start **GRASS** from within **R**) and create a location +* `.locationDelete()` Deletes all files associated with a **GRASS** "location" and mapset +* `.locationFind()`: Find a specific **GRASS** "location" that already exists +* `.locationRestore()` Reconnect **GRASS** to a previously-created **GRASS** "location" +* `.locations()`: List of all available "locations" +* `.mapset()`: **GRASS** "mapset" of an object or the active session + +## **GRASS** "regions" +* `.region()`: Change or report the active region's extent and resolution +* `.regionDim()]`: Change or report the active region's resolution (also [`dim()`](https://adamlilith.github.io/fasterRaster/reference/dim.html) and related functions, with no arguments) +* `.regionExt()`: Change or report the active region's extent (also [`ext()`](https://adamlilith.github.io/fasterRaster/reference/ext.html) and related functions, with no arguments) +* `.regionRes()`: Change or report the active region's dimensions (also [`res()`](https://adamlilith.github.io/fasterRaster/reference/res.html) and related functions, with no arguments) + +~ FINIS ~ diff --git a/vignettes/images/dist_to_rivers.png b/vignettes/images/dist_to_rivers.png new file mode 100644 index 00000000..76fd527c Binary files /dev/null and b/vignettes/images/dist_to_rivers.png differ diff --git a/vignettes/images/elev_rivers.png b/vignettes/images/elev_rivers.png new file mode 100644 index 00000000..ccdc4166 Binary files /dev/null and b/vignettes/images/elev_rivers.png differ diff --git a/vignettes/projects_mapsets.Rmd b/vignettes/projects_mapsets.Rmd index 910f7ed7..02bfb51f 100644 --- a/vignettes/projects_mapsets.Rmd +++ b/vignettes/projects_mapsets.Rmd @@ -14,6 +14,7 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +fig.path = 'man/figures/' ``` **GRASS GIS** uses "projects" (which used to be called "locations" before **GRASS** 8.4), and "mapsets" to store files (rasters, vectors, etc.). **fasterRaster** uses projects and mapsets, too, but in a manner that is invisibly to most users. Thus, this tutorial is mostly of interest to developers and other curious people. diff --git a/vignettes/regions.Rmd b/vignettes/regions.Rmd index b3acd752..03df0fbf 100644 --- a/vignettes/regions.Rmd +++ b/vignettes/regions.Rmd @@ -14,6 +14,7 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +fig.path = 'man/figures/' ``` A **GRASS** *region* is a data structure like a raster in that it is composed of a grid, but different in that "cells" in this grid do not contain values. Rather, their resolution and the extent of the region influence how rasters are imported, created, processed, and exported. In most cases, whenever a raster undergoes one of these processes using a **GRASS** module, the raster will be resampled and/or crop/extend it so that matches the region"s extent and resolution. If ignored, this can cause unintended side effects if the region's geometry doesn't match the raster being processed.