Skip to content

Commit

Permalink
hardening to missing suggests, like sharpshootR
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanbeaudette committed Feb 6, 2025
1 parent 8a60208 commit 5c83e0b
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 159 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# aqp 2.2 (2025-02-04)
# aqp 2.2 (2025-02-06)
* CRAN release
* fix for `hz_segment()` and `NCSP()` with _data.table_ `SoilProfileCollection` objects (#320)
* fix for `generalize.hz()` to handle missing depths better and added `na.rm` argument (#321)
Expand Down
6 changes: 4 additions & 2 deletions R/aggregateColor.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@
#' a <- aggregateColor(s, groups = 'slice', col = 'soil_color')
#'
#' # optionally plot with helper function
#' if(require(sharpshootR))
#' aggregateColorPlot(a)
#' # from sharpshootR package
#' if(requireNamespace('sharpshootR')) {
#' sharpshootR::aggregateColorPlot(a)
#' }
#'
#' # a more interesting example
#' data(loafercreek, package = 'soilDB')
Expand Down
35 changes: 0 additions & 35 deletions R/hzTransitionProbabilities.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,41 +44,6 @@
#' (tp <- hzTransitionProbabilities(sp4, 'name'))
#'
#'
#' \dontrun{
#' ## plot TP matrix with functions from sharpshootR package
#' library(sharpshootR)
#' par(mar=c(0,0,0,0), mfcol=c(1,2))
#' plotSPC(sp4, name = 'name', name.style = 'center-center')
#' plotSoilRelationGraph(tp, graph.mode = 'directed', edge.arrow.size=0.5)
#'
#' ## demonstrate genhzTableToAdjMat usage
#' data(loafercreek, package='soilDB')
#'
#' # convert contingency table -> adj matrix / TP matrix
#' tab <- table(loafercreek$hzname, loafercreek$genhz)
#' m <- genhzTableToAdjMat(tab)
#'
#' # plot
#' par(mar=c(0,0,0,0), mfcol=c(1,1))
#' plotSoilRelationGraph(m, graph.mode = 'directed', edge.arrow.size=0.5)
#'
#'
#' ## demonstrate markovchain integration
#' library(markovchain)
#' tp.loops <- hzTransitionProbabilities(sp4, 'name', loopTerminalStates = TRUE)
#'
#' # init new markovchain from TP matrix
#' mc <- new("markovchain", states=dimnames(tp.loops)[[1]], transitionMatrix = tp.loops)
#'
#' # simple plot
#' plot(mc, edge.arrow.size=0.5)
#'
#' # check absorbing states
#' absorbingStates(mc)
#'
#' # steady-state:
#' steadyStates(mc)
#' }
#'
hzTransitionProbabilities <- function(x, name = GHL(x, required = TRUE), loopTerminalStates = FALSE) {

Expand Down
4 changes: 3 additions & 1 deletion man/aggregateColor.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 0 additions & 35 deletions man/hzTransitionProbabilities.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

166 changes: 81 additions & 85 deletions vignettes/Introduction-to-SoilProfileCollection-Objects.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ vignette: >
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

```{r setup, echo=FALSE, results='hide', warning=FALSE}
knitr::opts_chunk$set(
message = FALSE,
warning = FALSE,
background = '#F7F7F7',
fig.align = 'center',
dev = 'png',
comment = "#>"
message = FALSE,
warning = FALSE,
background = '#F7F7F7',
fig.align = 'center',
dev = 'png',
comment = "#>"
)
options(width = 100, stringsAsFactors = FALSE, timeout = 600)
Expand Down Expand Up @@ -75,9 +75,9 @@ print(sp4)

`SoilProfileCollection` objects are typically created by "promoting" `data.frame` objects (rectangular tables of data) that contain at least three essential columns:

1. an ID column uniquely identifying groups of horizons (e.g. pedons)
2. horizon top boundaries
3. horizon bottom boundaries
1. an ID column uniquely identifying groups of horizons (e.g. pedons)
2. horizon top boundaries
3. horizon bottom boundaries

The `data.frame` is sorted internally according to the profile ID and horizon top boundary. Formula notation is used to define the columns used to promote a `data.frame` object:

Expand All @@ -88,10 +88,10 @@ idcolumn ~ hz_top_column + hz_bottom_column
## Rapid Templating
Small collections of soil profiles can be described using text "templates" and `quickSPC()`. Templates take the form of:

* `ID:AAA|BBB|CCCCCC`: relative thickness specified by horizon designations, split by "|" symbol
* `ID:A-B-C`: horizons of random thickness specified by horizon designations, split by "-" symbol
* `ID:AAA|BBB|CCCCCC`: relative thickness specified by horizon designations, split by "|" symbol

* `ID:A-B-C`: horizons of random thickness specified by horizon designations, split by "-" symbol

The "ID:" prefix is optional, with unique IDs generated by the digest package when omitted.

```{r fig.width = 6}
Expand All @@ -118,35 +118,35 @@ plotSPC(s, name.style = 'center-center',

"Accessor" functions are used to extract specific components from within `SoilProfileCollection` objects.

* Methods that return a column name. These are useful for extracting depths, horizon designations, IDs, etc. before taking an SPC apart for a specific task.

+ `idname(sp4)`: extract profile ID name (column name used to init SPC)
+ `horizonDepths(sp4)`: horizon top / bottom depth names (used to init SPC)
+ `hzidname(sp4)`: horizon ID name (typically automatically built at init time)
+ `hzdesgnname(sp4)`: horizon designation name (if set)
+ `hztexclname(sp4)`: horizon texture class name (if set)

* Methods that return a vector of values.

+ `profile_id(sp4)`: profile IDs, in order
+ `hzID(sp4)`: horizon IDs, in order
+ `hzDesgn(sp4)`: horizon designations, in order

* Methods that return site/horizon attribute column names.

+ `names(sp4)`: site + horizon names concatenated into a single vector
+ `horizonNames(sp4)`: horizon names
+ `siteNames(sp4)`: site names

* Profile and horizon totals.

+ `length(sp4)`: number of profiles in collection
+ `nrow(sp4)`: number of horizons in collection
* Methods that return a column name. These are useful for extracting depths, horizon designations, IDs, etc. before taking an SPC apart for a specific task.

+ `idname(sp4)`: extract profile ID name (column name used to init SPC)
+ `horizonDepths(sp4)`: horizon top / bottom depth names (used to init SPC)
+ `hzidname(sp4)`: horizon ID name (typically automatically built at init time)
+ `hzdesgnname(sp4)`: horizon designation name (if set)
+ `hztexclname(sp4)`: horizon texture class name (if set)

* Methods that return a vector of values.

+ `profile_id(sp4)`: profile IDs, in order
+ `hzID(sp4)`: horizon IDs, in order
+ `hzDesgn(sp4)`: horizon designations, in order

* Other methods.

+ `depth_units(sp4)`: defaults to 'cm' at SPC creation
+ `metadata(sp4)`: returns `list` object with base + optional (user-defined) metadata elements
* Methods that return site/horizon attribute column names.

+ `names(sp4)`: site + horizon names concatenated into a single vector
+ `horizonNames(sp4)`: horizon names
+ `siteNames(sp4)`: site names

* Profile and horizon totals.

+ `length(sp4)`: number of profiles in collection
+ `nrow(sp4)`: number of horizons in collection

* Other methods.

+ `depth_units(sp4)`: defaults to 'cm' at SPC creation
+ `metadata(sp4)`: returns `list` object with base + optional (user-defined) metadata elements

# Horizon and Site Data

Expand All @@ -156,10 +156,10 @@ Both site and horizon data are stored as `data.frame` within the SoilProfileColl

Columns from site or horizon tables can be accessed with the `$` syntax notation, similar to the `data.frame`. New data can be assigned to either table in the same manner, as long as the length of the new data is:

1. same length as the number of profiles in the collection (target is the site table)
2. same length as the number of horizons in the collection (target is the horizon table)
3. length 1; and selecting the target table requires `site(object)$new_column <- new_value` for new site data and `horizons(object)$new_column <- new value` for horizon
1. same length as the number of profiles in the collection (target is the site table)
2. same length as the number of horizons in the collection (target is the horizon table)
3. length 1; and selecting the target table requires `site(object)$new_column <- new_value` for new site data and `horizons(object)$new_column <- new value` for horizon

Assignment of new data to existing or new attributes can proceed as follows.

```{r hz_and_site_data}
Expand Down Expand Up @@ -355,13 +355,13 @@ z <- rebuildSPC(sp4)

`checkHzDepthLogic()` has the ability to perform logical tests on whole profiles or individual horizons. Four different tests are performed related to four common errors in horizon depths:

- bottom depth shallower than top depth
- bottom depth shallower than top depth

- equal top and bottom depth
- equal top and bottom depth

- missing (`NA`) top or bottom depth
- missing (`NA`) top or bottom depth

- gap or overlap between adjacent horizons
- gap or overlap between adjacent horizons

```{r}
checkHzDepthLogic(sp4)
Expand Down Expand Up @@ -445,7 +445,7 @@ sp4[, , .LAST]
`SoilProfileCollection` objects are combined by passing a list of objects to the `combine()` function.

Ideally all objects share the same internal structure, profile ID, horizon ID, depth units, and other parameters of a `SoilProfileCollection`. Manually subset the example data into 3 pieces, compile into a list, and then `combine` back together.

```{r concatenation, eval=FALSE}
# subset data into chunks
s1 <- sp4[1:2, ]
Expand Down Expand Up @@ -636,12 +636,12 @@ explainPlotSPC(sp4, name = 'name', n = length(sp4) + 2)
### Small SoilProfileCollections

Making quality figures with fewer than 5 soil profiles usually requires more customization of the basic call to `plotSPC`. In general, the following are a good starting point:
* shrink margins and disable clipping with `par`
* adjust output graphic device (e.g. `png()`) dimensions and resolution
* increase font size with `cex.names`
* adjust sketch width with `width`, typically within 0.15-0.35
* move depth axis to the left using negative `line` values, e.g. (`depth.axis = list(line = -2)`)

* shrink margins and disable clipping with `par`
* adjust output graphic device (e.g. `png()`) dimensions and resolution
* increase font size with `cex.names`
* adjust sketch width with `width`, typically within 0.15-0.35
* move depth axis to the left using negative `line` values, e.g. (`depth.axis = list(line = -2)`)

Get some example data from the Official Series Descriptions:
```{r, fig.width=5, fig.height=6}
Expand Down Expand Up @@ -1087,9 +1087,9 @@ The `slab()` function is the simplest way to implement a change of depth support

The depth structure ("slabs") over which summaries are computed is defined with the `slab.structure` argument using:

* a single integer (e.g. `10`): data are aggregated over a regular sequence of 10-unit thickness slabs
* a vector of 2 integers (e.g. `c(50, 60)`): data are aggregated over depths spanning 50--60 units
* a vector of 3 or more integers (e.g. `c(0, 5, 10, 50, 100)`): data are aggregated over the depths spanning 0--5, 5--10, 10--50, 50--100 units
* a single integer (e.g. `10`): data are aggregated over a regular sequence of 10-unit thickness slabs
* a vector of 2 integers (e.g. `c(50, 60)`): data are aggregated over depths spanning 50--60 units
* a vector of 3 or more integers (e.g. `c(0, 5, 10, 50, 100)`): data are aggregated over the depths spanning 0--5, 5--10, 10--50, 50--100 units

```{r slab, fig.height=4, fig.width=8}
# aggregate a couple of the horizon-level attributes,
Expand Down Expand Up @@ -1226,7 +1226,7 @@ d.gsm.pedons <- data.table::dcast(
data.table(d.gsm),
formula = id + top + bottom ~ variable,
value.var = 'value'
)
)
# init SPC
depths(d.gsm.pedons) <- id ~ top + bottom
Expand Down Expand Up @@ -1279,17 +1279,9 @@ Calculation of between-profile dissimilarity is performed using `NCSP()` (Numeri

See the [function manual page](http://ncss-tech.github.io/aqp/reference/NCSP.html) and [this paper](http://dx.doi.org/10.1016/j.cageo.2012.10.020) for details.

```{r setup2, echo=FALSE, results='hide', warning=FALSE}
# handle sharpshootR dependency of last chunk
knitr::opts_chunk$set(
eval = isTRUE(R.version$major >= 4 &&
try(requireNamespace("sharpshootR", quietly = TRUE), silent = TRUE))
)
```

```{r fig.height=6, fig.width=10}
library(cluster)
library(sharpshootR)
# start fresh
data(sp4)
Expand All @@ -1311,25 +1303,29 @@ d.diana <- diana(d)
# this function is from the sharpshootR package
# requires some manual adjustments
par(mar = c(0, 0, 4, 0))
plotProfileDendrogram(
sp4,
d.diana,
scaling.factor = 0.9,
y.offset = 5,
cex.names = 0.7,
width = 0.3,
color = 'ex_Ca_to_Mg',
name.style = 'center-center',
hz.depths = TRUE,
depth.axis = FALSE
)
if(requireNamespace('sharpshootR')) {
sharpshootR::plotProfileDendrogram(
sp4,
d.diana,
scaling.factor = 0.9,
y.offset = 5,
cex.names = 0.7,
width = 0.3,
color = 'ex_Ca_to_Mg',
name.style = 'center-center',
hz.depths = TRUE,
depth.axis = FALSE
)
}
```

Some additional examples can be found in:

* [Pair-Wise Distances by Generalized Horizon Labels](http://ncss-tech.github.io/AQP/aqp/genhz-distance-eval.html)
* [Competing Soil Series](http://ncss-tech.github.io/AQP/soilDB/competing-series.html)
* [Soil Profile Distances](http://ncss-tech.github.io/AQP/aqp/aqp-profile-dissimilarity.html)
* [Pair-Wise Distances by Generalized Horizon Labels](http://ncss-tech.github.io/AQP/aqp/genhz-distance-eval.html)
* [Competing Soil Series](http://ncss-tech.github.io/AQP/soilDB/competing-series.html)
* [Soil Profile Distances](http://ncss-tech.github.io/AQP/aqp/aqp-profile-dissimilarity.html)

----------------------------
This document is based on `aqp` version `r utils::packageDescription("aqp", field="Version")`.
This document is based on `aqp` version `r utils::packageDescription("aqp", field = "Version")`.

0 comments on commit 5c83e0b

Please sign in to comment.