Skip to content

Commit

Permalink
Merge branch 'master' into mutate-profile-dynnames
Browse files Browse the repository at this point in the history
  • Loading branch information
brownag committed Oct 15, 2024
2 parents dfc34f4 + 8b31518 commit 36678c7
Show file tree
Hide file tree
Showing 122 changed files with 4,678 additions and 1,203 deletions.
22 changes: 11 additions & 11 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ jobs:
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
RSPM: ${{ matrix.config.rspm }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}

steps:
- uses: actions/checkout@v4

- uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
Expand All @@ -52,15 +51,8 @@ jobs:
brew install --cask xquartz
- uses: r-lib/actions/setup-r-dependencies@v2
if: matrix.config.r == '3.6'
with:
extra-packages: any::rcmdcheck, soiltexture=?ignore-before-r=4.3.0, markovchain=?ignore-before-r=4.0.0, Hmisc=?ignore
needs: check

- uses: r-lib/actions/setup-r-dependencies@v2
if: matrix.config.r != '3.6'
with:
extra-packages: any::rcmdcheck, markovchain=?ignore-before-r=4.0.0
extra-packages: any::rcmdcheck, soiltexture=?ignore-before-r=4.3.0, sf=?ignore-before-r=4.0.0, markovchain=?ignore-before-r=4.0.0, Hmisc=?ignore, knitr=?ignore-before-r=4.0.0, rmarkdown=?ignore-before-r=4.0.0, testthat=?ignore-before-r=4.0.0,
needs: check

- name: Install soilDB from r-universe (R-devel only)
Expand All @@ -70,6 +62,14 @@ jobs:
shell: Rscript {0}

- uses: r-lib/actions/check-r-package@v2
if: matrix.config.r != '3.6'
with:
upload-snapshots: true

- uses: r-lib/actions/check-r-package@v2
if: matrix.config.r == '3.6'
with:
args: 'c("--no-manual", "--as-cran", "--ignore-vignettes", "--no-tests")'
build_args: 'c("--no-manual", "--no-build-vignettes")'
upload-snapshots: true

8 changes: 4 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Package: aqp
Version: 2.0.3
Version: 2.1.0
Title: Algorithms for Quantitative Pedology
Authors@R: c(person(given="Dylan", family="Beaudette", role = c("aut", "cre"), email = "[email protected]"), person(given="Pierre", family="Roudier", email="[email protected]", role = c("aut", "ctb")), person(given="Andrew", family="Brown", email="[email protected]", role = c("aut", "ctb")))
Author: Dylan Beaudette [aut, cre], Pierre Roudier [aut, ctb], Andrew Brown [aut, ctb]
Maintainer: Dylan Beaudette <[email protected]>
Depends: R (>= 3.5.0)
Imports: grDevices, graphics, stats, utils, methods, grid, lattice, cluster, sp, stringr, data.table, farver
Suggests: mvtnorm, colorspace, ape, soilDB, sf, latticeExtra, tactile, compositions, sharpshootR, markovchain, xtable, testthat, Gmedian, Hmisc, tibble, RColorBrewer, scales, digest, MASS, mpspline2, soiltexture, gower, knitr, rmarkdown, plyr
Imports: grDevices, graphics, stats, utils, methods, grid, lattice, cluster, stringr, data.table, farver
Suggests: mvtnorm, colorspace, ape, soilDB, sp, sf, latticeExtra, tactile, compositions, sharpshootR, markovchain, xtable, testthat, Gmedian, Hmisc, tibble, RColorBrewer, scales, digest, MASS, mpspline2, soiltexture, gower, knitr, rmarkdown, plyr
Description: The Algorithms for Quantitative Pedology (AQP) project was started in 2009 to organize a loosely-related set of concepts and source code on the topic of soil profile visualization, aggregation, and classification into this package (aqp). Over the past 8 years, the project has grown into a suite of related R packages that enhance and simplify the quantitative analysis of soil profile data. Central to the AQP project is a new vocabulary of specialized functions and data structures that can accommodate the inherent complexity of soil profile information; freeing the scientist to focus on ideas rather than boilerplate data processing tasks <doi:10.1016/j.cageo.2012.10.020>. These functions and data structures have been extensively tested and documented, applied to projects involving hundreds of thousands of soil profiles, and deeply integrated into widely used tools such as SoilWeb <https://casoilresource.lawr.ucdavis.edu/soilweb-apps>. Components of the AQP project (aqp, soilDB, sharpshootR, soilReports packages) serve an important role in routine data analysis within the USDA-NRCS Soil Science Division. The AQP suite of R packages offer a convenient platform for bridging the gap between pedometric theory and practice.
License: GPL (>= 3)
LazyLoad: yes
Expand All @@ -15,6 +15,6 @@ URL: https://github.com/ncss-tech/aqp, https://ncss-tech.github.io/AQP/
BugReports: https://github.com/ncss-tech/aqp/issues
Language: en-US
Encoding: UTF-8
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
Roxygen: list(markdown = TRUE)
VignetteBuilder: knitr
17 changes: 10 additions & 7 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export(buntley.westin.index)
export(checkHzDepthLogic)
export(checkSPC)
export(col2Munsell)
export(collapseHz)
export(colorChart)
export(colorContrast)
export(colorContrastPlot)
Expand Down Expand Up @@ -95,7 +96,13 @@ export(hzOffset)
export(hzTopographyCodeToLineType)
export(hzTopographyCodeToOffset)
export(hzTransitionProbabilities)
export(hz_dissolve)
export(hz_intersect)
export(hz_lag)
export(hz_segment)
export(hz_to_taxpartsize)
export(invertLabelColor)
export(lookup_taxpartsize)
export(lunique)
export(maxDepthOf)
export(minDepthOf)
Expand Down Expand Up @@ -139,6 +146,7 @@ export(slice.fast)
export(slicedHSD)
export(soilColorSignature)
export(soilPalette)
export(soilTextureColorPal)
export(spc_in_sync)
export(spec2Munsell)
export(splitLogicErrors)
Expand Down Expand Up @@ -170,6 +178,7 @@ exportMethods("horizons<-")
exportMethods("hzID<-")
exportMethods("hzdesgnname<-")
exportMethods("hzidname<-")
exportMethods("hzmetaname<-")
exportMethods("hztexclname<-")
exportMethods("initSpatial<-")
exportMethods("metadata<-")
Expand Down Expand Up @@ -202,6 +211,7 @@ exportMethods(hzID)
exportMethods(hzMetadata)
exportMethods(hzdesgnname)
exportMethods(hzidname)
exportMethods(hzmetaname)
exportMethods(hztexclname)
exportMethods(idname)
exportMethods(isEmpty)
Expand Down Expand Up @@ -234,8 +244,6 @@ exportMethods(trunc)
exportMethods(unique)
exportMethods(validSpatialData)
import(data.table)
importClassesFrom(sp,SpatialPoints)
importClassesFrom(sp,SpatialPointsDataFrame)
importFrom(cluster,daisy)
importFrom(cluster,pam)
importFrom(cluster,silhouette)
Expand Down Expand Up @@ -299,11 +307,6 @@ importFrom(methods,setOldClass)
importFrom(methods,setReplaceMethod)
importFrom(methods,slot)
importFrom(methods,slotNames)
importFrom(sp,"coordinates<-")
importFrom(sp,"proj4string<-")
importFrom(sp,SpatialPoints)
importFrom(sp,coordinates)
importFrom(sp,proj4string)
importFrom(stats,TukeyHSD)
importFrom(stats,aggregate)
importFrom(stats,aov)
Expand Down
14 changes: 14 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# aqp 2.1.0 (2024-10-10)
* added Munsell values of 8.5 and 9.5 to Munsell look up table and (interpolated) reference spectra (#318)
* `munsell2rgb()` now safely selects the closest Munsell value and chroma to those available in the package LUT
* new function `soilTextureColorPal()` for suggesting a color palette suitable for soil texture class
* **Breaking Change**: `@sp` slot of the SoilProfileCollection object, and dependency on sp package, has been removed.
* Any SoilProfileCollection objects previously written to file (.rda, .rds) with aqp <2.1.x will need to be rebuilt using `rebuildSPC()` due to changes to S4 object structure
* `estimatePSCS()` gains argument `"lieutex"` for in lieu textures which are used in the new routine for identification of the particle size control section of organic soils
* new function `collapseHz()` combines and aggregates data for adjacent horizons matching a pattern or sharing a common ID

# aqp 2.0.4 (2024-07-30)
* CRAN release
* ragged bottom lines in `plotSPC()` now adjusted as function of number of profiles and device width
* additional metadata from `plotSPC()` saved to `last_spc_plot` in `aqp.env`

# aqp 2.0.3 (2024-04-18)
* CRAN release
* `simulateColor()` gains new method `mvnorm` for simulating plausible colors
Expand Down
1 change: 0 additions & 1 deletion R/AAAA.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ aqp.env <- new.env(hash = TRUE, parent = parent.frame())
# register options for later use
.onLoad <- function(libname, pkgname) {
options(.aqp.show.n.cols = 10)

}

# no longer needed since it is imported
Expand Down
52 changes: 26 additions & 26 deletions R/Class-SoilProfileCollection.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,24 @@
#' @slot metadata list.
#' @slot horizons data.frame.
#' @slot site data.frame.
#' @slot sp SpatialPoints.
#' @slot diagnostic data.frame.
#' @slot restrictions data.frame.
#'
#' @details
#' After aqp 2.0.2, the `@sp` slot was removed from the SoilProfileCollection object. If you run into errors related to old object definitions, use `rebuildSPC()` on the problematic object.
#'
#' @aliases SoilProfileCollection-class
#' @rdname SoilProfileCollection-class
#' @importFrom sp SpatialPoints proj4string coordinates proj4string<- coordinates<-
#' @importClassesFrom sp SpatialPoints SpatialPointsDataFrame
setClass(
Class = 'SoilProfileCollection',
representation = representation(
idcol = 'character', # column name containing IDs
hzidcol = 'character', # column name containing unique horizon IDs
depthcols = 'character', # 2 element vector with column names for hz top, bottom

metadata = 'list', # list with key-value mapping

horizons = 'data.frame', # all horizons sorted by ID & top depth

site = 'data.frame', # data about the sampling sites

sp = 'SpatialPoints', # spatial data stored here, initialized as 'empty' sp object

# sp = 'NULL', # no longer used, formerly 'empty' sp object
diagnostic = 'data.frame',# (optional) diagnostic horizons are stored here
restrictions = 'data.frame' # (optional) restrictions are stored here
),
Expand All @@ -47,7 +43,7 @@ setClass(
top = numeric(0), bottom = numeric(0),
stringsAsFactors = FALSE),
site = data.frame(id = character(0), stringsAsFactors = FALSE),
sp = sp::SpatialPoints(data.frame(x = 0, y = 0))[-1, ],
# sp = NULL,
diagnostic = data.frame(stringsAsFactors = FALSE),
restrictions = data.frame(stringsAsFactors = FALSE)
),
Expand All @@ -61,18 +57,18 @@ setClass(
# c/o: https://gis.stackexchange.com/questions/291069/creating-empty-spatialpoints-or-spatialpointsdataframe-in-r
# old: new('SpatialPoints')
# new: SpatialPoints(data.frame(x = 0, y = 0))[-1,]
# new new: NULL

#' Constructor for the SoilProfileCollection object
#'
#' @param idcol character Profile ID Column Name
#' @param hzidcol character Horizon ID Column Name
#' @param depthcols character, length 2 Top and Bottom Depth Column Names
#' @param metadata list, metadata including data.frame class in use and depth units
#' @param horizons data.frame An object inheriting from data.frame containing Horizon data.
#' @param site data.frame An object inheriting from data.frame containing Site data.
#' @param sp SpatialPoints A SpatialPoints object. No longer used in aqp 2+, see `?initSpatial`
#' @param diagnostic data.frame An object inheriting from data.frame containing diagnostic feature data. Must contain profile ID. See \code{diagnostic_hz()}
#' @param restrictions data.frame An object inheriting from data.frame containing restrictive feature data. Must contain profile ID. See \code{restrictions()}
#' @param idcol character. Profile ID Column Name
#' @param hzidcol character. Horizon ID Column Name
#' @param depthcols character. length 2 Top and Bottom Depth Column Names
#' @param metadata list. metadata including data.frame class in use and depth units
#' @param horizons data.frame. An object inheriting from data.frame containing Horizon data.
#' @param site data.frame. An object inheriting from data.frame containing Site data.
#' @param diagnostic data.frame. An object inheriting from data.frame containing diagnostic feature data. Must contain profile ID. See \code{diagnostic_hz()}
#' @param restrictions data.frame. An object inheriting from data.frame containing restrictive feature data. Must contain profile ID. See \code{restrictions()}
#'
#' @description In general, one should use \code{depths()} to initiate a SoilProfileCollection object from data. However, sometimes there are instances where either an empty, or very specific, object is needed. If that is the case, the general constructor \code{SoilProfileCollection} is available.
#'
Expand Down Expand Up @@ -184,7 +180,7 @@ setClass(
stringsAsFactors = FALSE
),
site = data.frame(id = character(0), stringsAsFactors = FALSE),
sp = new('SpatialPoints'),
# sp = NULL,
diagnostic = data.frame(stringsAsFactors = FALSE),
restrictions = data.frame(stringsAsFactors = FALSE)) {

Expand Down Expand Up @@ -227,7 +223,7 @@ setClass(
metadata = metadata,
horizons = .as.data.frame.aqp(horizons, hzclass),
site = .as.data.frame.aqp(site, hzclass),
sp = sp,
# sp = sp,
diagnostic = .as.data.frame.aqp(diagnostic, hzclass),
restrictions = .as.data.frame.aqp(restrictions, hzclass)
)
Expand Down Expand Up @@ -948,10 +944,12 @@ setMethod("site", signature(object = "SoilProfileCollection"),
setGeneric("diagnostic_hz", function(object, ...)
standardGeneric("diagnostic_hz"))

#' Retrieve diagnostic data from SoilProfileCollection
#'
#' @description Get diagnostic feature data from SoilProfileCollection. Result is returned in the same \code{data.frame} class used to initially construct the SoilProfileCollection.
#' Get or Set Diagnostic Horizon data in a SoilProfileCollection
#'
#' @description Diagnostic horizons describe features of the soil relevant to taxonomic classification. A single profile may have multiple diagnostic features or horizons, each of which may be comprised of multiple horizons.
#'
#' - `diagnostic_hz()` (get method): Get diagnostic feature data from a SoilProfileCollection.
#'
#' @param object a SoilProfileCollection
#'
#' @docType methods
Expand All @@ -968,9 +966,11 @@ setMethod(f = 'diagnostic_hz', signature(object = 'SoilProfileCollection'),
setGeneric("restrictions", function(object, ...)
standardGeneric("restrictions"))

#' Retrieve restriction data from SoilProfileCollection
#' Get or Set Restriction data in a SoilProfileCollection
#'
#' @description Get restriction data from SoilProfileCollection. Result is returned in the same \code{data.frame} class used to initially construct the SoilProfileCollection.
#' @description Restrictions describe root-limiting features in the soil. A single profile may have multiple restrictions.
#'
#' - `restrictions()` (get method): Get restriction data from a SoilProfileCollection.
#'
#' @param object a SoilProfileCollection
#' @docType methods
Expand Down
18 changes: 13 additions & 5 deletions R/SoilProfileCollection-coercion.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#' @docType methods
#' @rdname coercion-methods
#'
#' @examples
#' @examples
#' # load example data stored as SoilProfileCollection
#' data(sp5)
#'
Expand All @@ -30,11 +30,19 @@
#' sp5$x <- sp5$y <- rnorm(length(sp5))
#' initSpatial(sp5, crs = "OGC:CRS84") <- ~ x + y
#'
#' # SpatialPointsDataFrame output
#' str(as(sp5, 'SpatialPointsDataFrame'))
#' if (requireNamespace("sf")) {
#'
#' # sf output
#' str(as(sp5, 'sf'))
#'
#' # SpatialPointsDataFrame output
#' str(as(sp5, 'SpatialPointsDataFrame'))
#'
#' # SpatialPoints output
#' str(as(sp5, 'SpatialPoints'))
#'
#' }
#'
#' # SpatialPoints output
#' str(as(sp5, 'SpatialPoints'))
setAs("SoilProfileCollection", "list", function(from) {

# get slot names from prototype
Expand Down
73 changes: 72 additions & 1 deletion R/SoilProfileCollection-metadata.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

# transfer attributes https://github.com/ncss-tech/aqp/issues/204
customattr <- attributes(src)
customattr <- customattr[!names(customattr) %in% names(attributes(SoilProfileCollection()))]
customattr <- customattr[!names(customattr) %in% c("sp", names(attributes(SoilProfileCollection())))]
attributes(dest)[names(customattr)] <- attributes(src)[names(customattr)]

# original.order metadata no longer created, not transferred
Expand Down Expand Up @@ -293,3 +293,74 @@ setReplaceMethod("GHL",
allowednames = "horizon"
)
})

setGeneric("hzmetaname", function(object, attr, required = FALSE)
standardGeneric("hzmetaname"))

#' @title Get or Set Horizon Metadata Column Name
#' @name hzmetaname
#' @aliases hzmetaname hzmetaname,SoilProfileCollection-method hzmetaname<- hzmetaname,SoilProfileCollection-method
#' @details Store the column name containing a specific type of horizon data in the metadata slot of the SoilProfileCollection.
#' @description `hzmetaname()`: Get column name containing horizon data of interest
#' @param object a SoilProfileCollection
#' @param attr character. Base name for attribute to be stored in metadata. This is prefixed with `"aqp_hz"` for horizon-level metadata for column attributes. e.g. `attr="clay"` results in metadata value retrieved from `"aqp_hzclay"`.
#' @param required logical, is this attribute required? If it is, set to `TRUE` to trigger error on invalid result
#' @docType methods
#' @rdname hzmetaname
#' @export
setMethod("hzmetaname", signature(object = "SoilProfileCollection"),
function(object, attr, required = FALSE) {
.require.metadata.aqp(object,
attr = paste0("aqp_hz", attr),
attrlabel = paste0("Horizon metadata (", attr, ") column"),
message = "\nSee ??hzmetaname",
required = required)
})

setGeneric('hzmetaname<-', function(object, attr, required = FALSE, value)
standardGeneric('hzmetaname<-'))

#' @description `hzmetaname<-`: Set horizon designation column name
#' @param object A _SoilProfileCollection_
#' @param attr _character_. Base name for attribute to be stored in metadata. This is prefixed with `"aqp_hz"` for horizon-level metadata for column attributes. e.g. `attr="clay"` results in metadata value retrieved from `"aqp_hzclay"`.
#' @param value _character_. Name of horizon-level column containing data corresponding to `attr`.
#' @param required _logical_. Is this attribute required? If it is, set to `TRUE` to trigger error on invalid `value`.
#' @docType methods
#' @seealso [guessHzAttrName()]
#' @rdname hzmetaname
#' @export
#' @examples
#'
#' data(sp1)
#'
#' # promote to SPC
#' depths(sp1) <- id ~ top + bottom
#'
#' # set important metadata columns
#' hzdesgnname(sp1) <- "name"
#' hztexclname(sp1) <- "texture"
#'
#' # set custom horizon property (clay content) column
#' hzmetaname(sp1, "clay") <- "prop"
#'
#' # inspect metadata list
#' metadata(sp1)
#'
#' # get horizon clay content column
#' hzmetaname(sp1, "clay")
#'
#' # uses hzdesgname(), hztexclname(), hzmetaname(attr="clay") in function definition
#' estimatePSCS(sp1)
setReplaceMethod("hzmetaname",
signature(object = "SoilProfileCollection"),
function(object, attr, required = FALSE, value) {
.set.metadata.aqp(
object = object,
value = value,
required = required,
attr = paste0("aqp_hz", attr),
attrlabel = paste0("Horizon metadata (", attr, ") column"),
message = "\nSee ??hzmetaname",
allowednames = "horizon"
)
})
Loading

0 comments on commit 36678c7

Please sign in to comment.