munsell2rgb()
now safely selects the closest Munsell value and chroma to those available in the package LUTsoilTextureColorPal()
for suggesting a color palette suitable for soil texture class@sp
slot of the SoilProfileCollection
object, and dependency on sp package, has been removed.
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 structureestimatePSCS()
gains argument "lieutex"
for in lieu textures which are used in the new routine for identification of the particle size control section of organic soilscollapseHz()
combines and aggregates data for adjacent horizons matching a pattern or sharing a common IDmutate_profile_raw()
for building sets of dynamic mutate expressions. Also mutate_profile()
gains col_names argument for dynamic naming of columns.addVolumeFraction()
now more robust to very thin horizons x low volume fractions; also skips horizons without sufficient or relevant valuesplotSPC()
now adjusted as function of number of profiles and device widthplotSPC()
saved to last_spc_plot
in aqp.env
simulateColor()
gains new method mvnorm
for simulating plausible colors
profileInformationIndex()
, dice()
, slab()
, spc2mpspline()
, fillHzGaps()
, and flagOverlappingHz()
huePositionCircle()
thicknessOf()
used for calculating thickness of horizons within each profile of a SoilProfileCollection
based on horizon-level logical expressions encoded in a function. Default behavior uses pattern matching on the horizon designation name.evalMissingData()
col2Munsell()
generalizes and replaces rgb2munsell()
(thanks Shawn Salley for the suggestion)
rgb2munsell()
will be deprecated in aqp 2.1warpHorizons()
for warping horizon thickness (inflate/deflate) (thanks Shawn Salley for idea / inspiration)plotColorMixture()
when final mixed color does not exist in spectral librarygroupedProfilePlot()
profileInformationIndex()
(vignette pending)flagOverlappingHz()
for identifying horizons with perfect overlapfillHzGaps()
, dice()
, slab()
, and several other functions now safely handle horizons with perfect overlap (#296)This is a major update to aqp that may create some issues for code depending on specific inputs/outputs in aqp < 1.42, particularly those relying on slice()
, slab()
, and profile_compare()
. slice()
and profile_compare()
are now deprecated, but will continue to work for the rest of calendar year 2023. There are no plans to maintain these functions beyond aqp 2.0. The new version of slab()
is a drop-in replacement for the previous version of the function.
Notable changes include:
slice()
in favor of the new, faster, more robust implementation in dice()
slab()
, with new arguments, faster back-end, and weighted aggregation implemented (finally)profile_compare()
in favor of the NCSP()
--a complete overhaul based on Maynard et al., 2020
compareSites()
perturb()
and estimatePSCS()
are now vectorized, and optimized for larger collectionsmixMunsell()
now uses mixingMethod = 'exact'
by default for the simulation of subtractive mixturesgower
package moved to SUGGESTSplotColorMixture()
now using grid graphics functions to determine color swatch geometry and setting overlap detection thresholdPMS2Munsell()
and support datacoordinates()<-
and proj4string()<-
in favor of initSpatial()<-
rruff.sample
example XRD patternsget.ml.hz()
no longer uses the name
argumentMajor changes to plotSPC()
:
max.depth
or max(x)
. This means that sketches generated with aqp 2.x will generally have less white space at the bottom of the figure. Make more room for additional annotation or visual effect by setting the desired depth range with the max.depth
argument.electroStatics_1D()
for fixing horizon depth label overlap, solutions are deterministic and almost always betterdepth.axis
, logical or listplot.depth.axis
: set via depth.axis = TRUE
, depth.axis = FALSE
, or customize depth.axis = list(...)
cex.depth.axis
: set via depth.axis = list(cex = 1)
axis.line.offset
: set via depth.axis = list(line = -2)
New features:
wilson2022
quickSPC()
and list / character templatesplotSPC()
via options(.aqp.plotSPC.args = list(...))
fragmentSieve()
and fragmentClasses()
as.data.frame(<SPC>)
as shorthand for as(<SPC>, 'data.frame')
plotSPC()
now marks truncated profiles with a ragged bottomfixOverlap()
now has two label-placement solvers, based on 1) electrostatics and 2) simulated annealingplotSPC()
Incremental changes, should have no effect on previous code:
plotSPC()
when fixLabelCollisions = TRUE
, adjustments suggested to fixOverlap()
are now scaled correctlyexplainPlotSPC()
reports label adjustment index when label collision repair is enabledexplainPlotSPC()
soilColorSignature()
gains arguments and perceptual color distances (dE00) via farver packageas(<SPC>, "data.frame")
: Replace plyr::join()
with merge()
correctAWC()
: NA handling - return NA when frags are NAmutate_profile()
: Faster (data.table-based) evaluation of profile-level expressions (#255)profileApply
: Add support for custom lapply()
-like function (APPLY.FUN
) for processing chunks (#256).interpretHorizonColor()
outputs to last_spc_plot
in aqp.env
for use in custom legend()
(#254)simplify
argument to SoilTextureLevels()
and ssc_to_texcl()
to optionally convert to an ordered factor with maximum of 12 levels (rather than 21). This smaller list of classes excludes sand grain size variants such as fine sand, loamy coarse sand, and very fine sandy loam.getArgillicBounds()
, getCambicBounds()
, mollic.thickness.requirement()
, getSurfaceHorizonDepth()
and related functions have been optimized and now work on SoilProfileCollection objects with length > 1reduceSPC()
function for selecting a subset of minimal plus additional specified columns from a SoilProfileCollection.NHZ
for use with SoilProfileCollection
[
method
object[,,.NHZ]
returns a vector with the number of horizons in each profileplotSPC()
gains new arguments for controlling horizon depth labelsplotSPC()
gains horizon depth annotation collision fixes (https://github.com/ncss-tech/aqp/issues/240)plotSPC()
minor bugfix for cases when n != length(x)
plotSPC()
important change! y.offset
is now automatically re-ordered by plot.order
base::aggregate
(thanks AGB)depthOf()
and related functions: better handling of NA
results from FUN
panel.depth_function()
that affected plotting of grouped data, created by slab()
plotSPC()
now uses variable (vertical) text alignment for horizon depth labelsprofileInformationIndex()
estimateSoilDepth()
now requires a valid horizon designation (no longer attempts a guess)group_by()
, summarize()
, mutate()
f.noise()
and resample.twotheta()
: use {powdR} package insteadtexture_to_texmod()
and fragvol_to_texmod()
c/o @smroeckerslice()
implemented as dice()
colorChart()
can now show neutral hues in a skinny panelcolorContrast()
, parseMunsell()
, and huePosition()
to work properly with neutral hueshuePosition()
gains new arguments and functionality: origin
and direction
huePositionCircle()
for helping visualize differences in Munsell hue on the unit circleplotSPC
defaults change:
width = 0.25
: slightly wider profile sketchesname = hzdesgnname(x)
: use metadata if present, no longer guessing. This may cause your figures to "lose" previously guessed horizon names, specify with name = 'column name'
or set metadata with hzdesgnname(x) <- 'hzname'
checkHzDepthLogic()
when byhz = TRUE
simulateColor()
for simulation of reasonable colorscolorChart()
for graphical depiction of Munsell chip frequency by groupunique
method for SoilProfileCollection
objects now returns a SoilProfileCollection
by default
SPC = FALSE
for previous behavior (https://github.com/ncss-tech/aqp/issues/159)aggregateColor()
now uses mixMunsell
for the estimation of soil color mixturesplotColorMixture()
will respect "names" attribute of colors-to-mix, without erroneous alpha-sortingparseMunsell()
now more robust and faster, c/o P. RoudiermixMunsell
:
exact
for direct conversion of mixture spectra to sRGB or closest Munsell chip (via spec2Munsell()
)PMS2Munsell()
for converting PMS codes -> closest Munsell chip (https://github.com/ncss-tech/aqp/issues/124)glom()
z1
and z2
arguments vectorized to allow for profile-specific intervals
z1
and z2
support non-standard evaluation based on column names in siteNames(p)
, and also can take character vector (length 1) with column names in siteNames(p)
depthOf()
, minDepthOf()
, maxDepthOf()
, getSurfaceHorizonDepth()
, getMineralSoilSurfaceDepth()
, getPlowLayerDepth()
can now be applied to multiple profiles.
SoilProfileCollection
has more than one profile then result is a data.frame
containing profile ID, top or bottom depths, horizon designation and patternSoilProfileCollection
methods that conflict with {dplyr} 1.0+ have been deprecated:
filter
, mutate
, group_by
, summarize
subset
, "mutate" -> transform
, "combine" -> c
*SPC
syntax: filterSPC
, mutateSPC
, groupSPC
, summarizeSPC
dplyr::combine
(deprecated in {dplyr} 0.7) still conflictsaqp::union()
, previously deprecated, has been removed from namespace
c()
or combine()
for SoilProfileCollection
inputcombine()
or pbindlist()
for list
inputplotSPC()
gains vectorized y.offset
support (demonstrated in: http://ncss-tech.github.io/AQP/aqp/genhz-distance-eval.html)plotSPC()
gains argument shrink.thin
for shrinking horizon designation labels when horizons are thinalignTransect()
for simplifying relative positioning of profile sketchesplotMultipleSPC()
gains ability to automatically merge thematic legendscoordinates<-
will check formula terms (unique coordinates) in the @horizons
slot, if needed.spec2Munsell()
for converting reflectance spectra into sRGB coordinates or closest Munsell chipmixMunsell
:
mixingMethod
argument for selecting several mixing strategiespanel.depth_function
when plotting grouped step-functions[,j]
-index extraction using {data.table}.LAST
, .FIRST
and .HZID
SoilProfileCollection "k-keywords"perturb()
is the new generalized replacement for sim()
and permute_profile()
checkHzDepthLogic()
now has a byhz
argument for checking logic by horizon rather than profilefillHzGaps
now has to_top
and to_bottom
arguments for filling above shallowest top / deepest bottom by profilefixOverlap()
more flexible and will usually settle on a solution in fewer iterations:
overlapMetrics()
instead of findOverlap()
for part of objective functionT0
and k
argumentsalignTransect
helper function for computing relative positions and ordering vector supplied to plotSPC
plotSPC()
automatically converts logical
data supplied to color
argument into factor
glom()
is now vectorized over profilesestimateAWC
introduced for testing lookup table estimation of available water capacity (AWC) of fine-earth fractioncorrectAWC
introduced for testing corrections of AWC estimates for rock fragment and saltsfillHzGaps
: new function for fixing horizon depth topological errors and padding top/bottom of profiles with placeholder (empty) horizonsmixMunsell
now relies on suggested package {gower} for 5-10x speed bumpplotColorQuantiles()
, now using {lattice} graphicsequivalent_munsell
and method equivalentMunsellChips
for "equivalent" Munsell chips lookup list based on all pairwise dE00 contrasts for integer "chips" in {aqp} munsell
data setcrit.clay.argillic
rounded to whole numbers per NSSH Part 614, subpart B, sections 614.13 and 614.14mutate_profile
uses data.table::rbindlist(fill=TRUE)
to combine site- and horizon-level transformationshzTopographyCodeToOffset
, hzTopographyCodeToLineType
, hzDistinctnessCodeToOffset
)L1_profiles
computes multivariate (L1) medians, compare to marginal medians via slab
plotSPC
updates:
hz.boundary.lty
is a horizon-level attribute that contains line type codeshz.topography.offset
a horizon-level attribute that contains representative offsets that encode horizon boundary topographyplotSPC
now encodes hz.topography.offset
using a vertical "bump" (chevron)addBracket
can now accept multiple bracket annotations per profilepms.munsell.lut
for converting Pantone spot color codes to (closest) Munsell chipduplicate
will makes copies of profiles within a SoilProfileCollection
us.state.soils
: 50 state soils + PR and VI soilsmixMunsell
plotColorMixture
for visualization of spectra / mixturetextureTriangleSummary
:
soiltexture
package for visualization (plotrix
implementation dropped)sim = TRUE
argument, see bootstrapSoilTexture
for a better approachbootstrapSoilTexture
for simulating realistic sand/silt/clay compositionscombine
replaces/expands aqp::union
due to conflicts with base::union
split
receives some upgrades to the S4 definition to increase parity with split.default
filter
is now an alias for new method subset
, which mirrors base::subset
estimateSoilDepth
loses top
and bottom
arguments, these are automatically extractedmunsell2SPC
, spc2mpspline
returnData
argument to contrastChart
glom(..., invert=TRUE)
, glomApply
, and better testsglomApply
: aqp::trunc
for cases when top and bottom depth interval is the same for all profiles in a SoilProfileCollectionNULL
through $<-
and horizons<-
or site<-
(https://github.com/ncss-tech/aqp/issues/163)data.table
with character vector (not formula) interfacespc_in_sync
(https://github.com/ncss-tech/aqp/pull/152)[
subset method and optional use of data.table
(https://github.com/ncss-tech/aqp/pull/155)depths<-
has been optimized and minimally validates input datahzID
) is now a character
data typeaqp::union
uses depths<-
internally; explicitly enforcing profile ID + top depth order in horizon data is safer but results in different ordering if union
-ing IDs that "intermingle" (need to be re-sorted).permute_profile
; similar to sim
but for boundaries. The interface to this function is likely to change/be expanded.segment
c/o @smroeckerplotSPC
plot
generic to show aqp::plot
in ?plot
tbl_df
and data.table
to SoilProfileCollectionaqp_df_class
to determine class name in use in a SoilProfileCollection objectplotSPC
upgrades (https://github.com/ncss-tech/aqp/pull/146)mollic.thickness.requirement
, hasDarkColors
estimateSoilDepth
-like methods for depth to multiple features via pattern matching: depthOf
, minDepthOf
, maxDepthOf
ssc_to_texcl
, texcl_to_ssc
, texmod_to_fragvoltot
, texture_to_taxpartsize
)[i,]
[,j]
subset methods for data.frame-based slots (https://github.com/ncss-tech/aqp/issues/135)mutate
, mutate_profile
(https://github.com/ncss-tech/aqp/issues/118)getSurfaceHorizonDepth
with buried horizons / non-contiguous instances of matching horizons (https://github.com/ncss-tech/aqp/issues/132)plotSPC
with small number of profiles ((https://github.com/ncss-tech/aqp/issues/128)[
j-index subset ((https://github.com/ncss-tech/aqp/issues/125)slab.structure[2] > max(x)
[[
subsetting method; an "ambivalent" accessor for site- or horizon-level propertiesgrepSPC
, filter
, subApply
for use in %>%
-lineshzDesgn()
, get horizon designations from a SPChzdesgnname()
/hzdesgnname()<-
and hztexclname()
/hztexclname()<-
get/set column containing horizon designations and texture classesglom()
profileApply()
enhancement for large SoilProfileCollection
objects (https://github.com/ncss-tech/aqp/issues/112)
profileApply()
frameify
argument for data.frame
output (https://github.com/ncss-tech/aqp/issues/111)checkHzDepthLogic()
replaces test_hz_logic()
rgb2munsell()
and colorQuantiles()
now uses the CIE2000 distance metric for color comparisoncolorQuantiles
until farver
2.0.2 is available on CRANSoilProfileCollection
object gains new slot: @restrictions
, fix old objects with rebuildSPC()
evalMissingData()
gets new argument for relative vs. absolute evaluation of missing data
horizonColorIndices()
, harden.rubification()
, harden.melanization()
, thompson.bell.darkness()
and associated functions in soilColorIndices.Rrowley2019
Hmisc
(hdquantile
), loading aqp
is now much faster
slab()
now uses stats::quantile()
as the default slab functionslab()
can be activated via argument: slab.fun = aqp:::.slab.fun.numeric.HD
generalize.hz()
gets a \dots argument for passing additional arguments to grep()
, e.g. perl=TRUE
addVolumeFraction()
can now accept a vector of colors, as many as number of horizonsjacobs2000
, pending documentationaggregateColor()
faster and more accurate, using delta-E00 for quantized colors c/o {farver} (see https://github.com/ncss-tech/aqp/issues/98)contrastChart()
and soilPalette()
plotSPC()
gains a new argument for relative positioning: relative.pos
fixOverlap()
, see manual page for examplesexplainPlotSPC()
, addDiagnosticBracket()
, and addVolumeFraction()
updated accordinglyplotSPC()
will now attempt to create multi-row legends when using a factor > n.legend levelsplotSPC()
will now generate > 10 colors for legends associated with a factor (https://github.com/ncss-tech/aqp/issues/9)munsell2rgb()
will now return CIE LAB coordinates if requested (https://github.com/ncss-tech/aqp/issues/69)aggregateColor()
gets a new feature, similar colors can be grouped via cluster::pam()previewColors()
, colorQuantiles()
, plotColorQuantiles()
horizonDepths()<-
, edit top/bottom names after SPC initprofile_id()<-
, edit profile IDs after init; be careful!hzID()
and hzID()<-
, get/set unique horizon IDshzidname()
and hzidname()<-
, get/set column containing unique horizon IDsrbind.SoilProfileCollection()
has been deprecated in favor of union()
, gains new functionality: https://github.com/ncss-tech/aqp/issues/71horizonNames()<-
explainPlotSPC
from SPC tutorial to aqp::explainPlotSPC()
plotSPC()
is a little better at estimating "extra" vertical / horizontal space, still needs work (https://github.com/ncss-tech/aqp/issues/62)plotSPC()
gets a new argument, n.legend
: approximate number of classesaggregateColor()
for cases when horizon depths are missing or top/bottom logic flippedaddVolumeFraction()
when fragment volume > 100%addDiagnosticBracket()
allowing for specification of column containing diagnostic feature kind
addBracket()
now requires a data.frame with plotting details, see manual pageshannonEntropy()
, confusionIndex()
, and brierScore()
get.ml.hz()
for horizon names that start with number or punctuationget.ml.hz()
now uses internal aqp functions for Shannon entropy and Brier scoresmissingDataGrid()
relaxing slice()
with strict=FALSE
munsell
look-up tableplotSPC()
now able to deal with missing horizon data (thanks Stephen R.)
rgb2munsell()
now uses CIELAB colorspace for lookup, results are more accurate as compared to using sRGB colorspacetexture.triangle.low.rv.high()
renamed to textureTriangleSummary()
. The old name still works, but a message is issued
textureTriangleSummary()
texture.names
: for toggling texture class namestextureTriangleSummary(..., sim=TRUE)
, previous simulated compositional data was not correct because the stats::var() was being used vs. compositions::var.acomp(). the variance / covariance values were 2-5x too small.tauW()
, added by D.G. Rossiter: see manual page for referencesrbind
-ingsoil_minerals
with some common soil mineral colors source: http://www.nrcs.usda.gov/wps/portal/nrcs/detail/soils/edu/?cid=nrcs142p2_054286
getClosestMunsellChip()
sp6
) based on http://www.sciencedirect.com/science/article/pii/S0016706111001972munsell2rgb()
can now accommodate neutral hues (N), and values of "2.5", see manual page for detailssoilColorSignature()
, see manual page
parseMunsell()
for converting strings of '10YR 2/2' into R colors or RGB triplets
munsell2rgb
on parsed strings of full Munsell notationprofile_compare()
, getting ready for a complete overhaul to this function
evalMissingData()
, see manual pagegenhzTableToAdjMat
, hzTransitionProbabilities
rbind.SoilProfileCollection()
related to object re-ordering
+ in aqp < 1.9.3: there was a chance than profile_id(x)
and site(x)[[idname(x)]])
would not match
+ bugs like this will no longer be a possibility after aqp 2.0, new SPC object structure plannedgroupedProfilePlot()
gains some new arguments and better documentation (see manual page)
plot.SoilProfileCollection
gains argument: default.color
(see manual page)munsell2rgb()
guessGenHzLevels()
aggregateColor()
and associated helper function sharpshootR::aggregateColorPlot()
R CMD check --as-cran
happyprofileApply()
manual pagedigest::digest
is now imported by defaultSoilProfileCollection
objectsx.idx.offset
: allows for plotting of multiple SPC objects within the same figure, see examplesplot.depth.axis
: enable / disable depth axis, useful for multi-collection plotsprofileGroupLabels
: simple annotation for groups of profiles within a profile sketch, see manual page for examplesplotMultipleSPC
: plot several SPC objects on the same axis, see manual page for examplesaddBrackets()
, panel.depth_function()
, and plotSPC()
addBrackets()
allow for annotation of bracketsspatial_subset()
: this functionality can be accomplished outside of AQP and removes dependency on rgeos packageattr(x, 'original.levels')
.label
, used to set site-level attribute containing profile labelsaqp.env
texture.triangle.low.rv.high()
plots texture data with low-high range defined by quantilesslab()
and profileApply()
via 'parallel' packageplotSPC()
gets a density
argument for shaded coloring of horizonsslab()
re-written from scratch, resulting in reduced memory footprint and quicker running time
! older code based on slab() is likely to now broken- sorry, it won't happen again
+ the new code is much slimmer and based on aggregate() rather than ddply
+ function arguments have changed so be sure to check the manual page
+ user-supplied functions are now much simpler to write and rely on vectors rather than data.frames (= faster)
+ the next major release will contain additional examples of how to use the new featuressim()
for simulation based on a template soil profile, proper documentation pending...subsetProfiles()
for simpler subsetting of SoilProfileCollection
objects via site or horizon-level attributes
get.ml.hz()
now returns a 'confidence' for each horizon (as a percent)site(SCP) <- d
now tries to merge data from SPC@site with 'd' via left join
+ this means that all new SPC objects will have a single column of @site data, containing profile IDs
strict
argument to many functions, to gracefully account for bad horizon data
SoilProfileCollection
+ this supersedes the (now removed) S3 SoilProfileList
classes
+ basic accessors/setters are in place, subject to change
SoilProfileCollection
class
new functions for getting data out of PedonPC (MS Access) databases [windows only for now] + get_site_data_from_pedon_db() : site and pedon aggregate data + get_hz_data_from_pedon_db() : horizon level data + get_colors_from_pedon_db() : formats and mixes multiple colors / horizon
mapunit_geom_by_ll_bbox()
: get map unit geometry by bounding boxMUKEYS_by_ll_bbox()
: get map unit keys by bounding boxSDA_query()
: retrieve soil tabular data via query written in SQLplotSPC
profile_compare()
now calculates slice-wise dissimilarity matrices in 1/3 the time (thanks llply!)