1 Introduction

This document demonstrates how to use the soilDB package to download KSSL data from SoilWeb. These data are from the September 2018 snapshot, and will be updated as future snapshots are released. Comparisons are made via graphical summaries of key soil properties with depth, using data structures and functions from the aqp package.

1.1 Installation

With a recent version of R (>= 3.5), it is possible to get all of the packages that this tutorial depends on via:

# stable packages from CRAN
install.packages('aqp', dep = TRUE)
install.packages('soilDB', dep = TRUE)
install.packages('Gmedian', dep = TRUE)
install.packages('tactile', dep = TRUE)
install.packages('maps', dep = TRUE)

2 Quick Example

KSSL and NASIS data are from the September 2018 snapshot. Details pending.

library(aqp)
library(soilDB)

# get lab and morphologic data
# simplify colors to 1 color (moist and dry) per horizon via mixing
# see ?mix_and_clean_colors for details.
s <- fetchKSSL(series = 'auburn', returnMorphologicData = TRUE, simplifyColors = TRUE)

# extract pedons into SoilProfileCollection
pedons <- s$SPC

The result is a list, check it out.

str(s, 2)
## List of 2
##  $ SPC  :Formal class 'SoilProfileCollection' [package "aqp"] with 9 slots
##  $ morph:List of 6
##   ..$ phcolor       :'data.frame':   105 obs. of  7 variables:
##   ..$ phfrags       :'data.frame':   27 obs. of  10 variables:
##   ..$ phpores       :'data.frame':   71 obs. of  5 variables:
##   ..$ phstructure   :'data.frame':   40 obs. of  7 variables:
##   ..$ pediagfeatures:'data.frame':   24 obs. of  5 variables:
##   ..$ rmf           : logi [1, 1] FALSE
# check out the "raw" morphologic data:
lapply(s$morph, head)
## $phcolor
##    phiid labsampnum colorpct colorhue colorvalue colorchroma colormoistst
## 1 820051   05N02182       NA     10YR          4           4          Dry
## 2 820051   05N02182       NA     10YR          3           3        Moist
## 3 820052   05N02183       NA    7.5YR          3           3        Moist
## 4 820052   05N02183       NA    7.5YR          4           6          Dry
## 5 820053   05N02184       NA      5YR          3           3        Moist
## 6 820053   05N02184       NA      5YR          4           4          Dry
## 
## $phfrags
##    phiid labsampnum fragvol                   fragkind fragsize_l fragsize_r fragsize_h fragshp
## 1 820051   05N02182      14 Metamorphic rock fragments          2          5         76      NA
## 2 820052   05N02183      10 Metamorphic rock fragments          2         20         76      NA
## 3 820053   05N02184      18 Metamorphic rock fragments          2          5         76      NA
## 4 570101   83P04043       5                       <NA>          2         NA         75      NA
## 5 570102   83P04044       5                       <NA>         75         NA        250      NA
## 6 570102   83P04044      10                       <NA>          2         NA         75      NA
##    fraground  fraghard
## 1 Subrounded Indurated
## 2 Subrounded Indurated
## 3 Subangular Indurated
## 4       <NA>      <NA>
## 5       <NA>      <NA>
## 6       <NA>      <NA>
## 
## $phpores
##    phiid labsampnum poreqty           poresize           poreshp
## 1 820051   05N02182       5               Fine      Interstitial
## 2 820051   05N02182       7             Medium           Tubular
## 3 820052   05N02183       5          Very fine Dendritic tubular
## 4 820052   05N02183       6             Medium           Tubular
## 5 820053   05N02184       5          Very fine Dendritic tubular
## 6 519185   40A23590      21 Very fine and fine              <NA>
## 
## $phstructure
##    phiid labsampnum structgrade structsize        structtype structid structpartsto
## 1 820051   05N02182    Moderate       Fine          Granular       NA            NA
## 2 820052   05N02183    Moderate     Medium Subangular blocky       NA            NA
## 3 820053   05N02184    Moderate     Medium Subangular blocky       NA            NA
## 4 519185   40A23590        <NA>       <NA>           Massive       NA            NA
## 5 518423   40A23592        <NA>       <NA>           Massive       NA            NA
## 6 518425   40A23594        <NA>       <NA>           Massive       NA            NA
## 
## $pediagfeatures
##   pedon_key  peiid featdept featdepb        featkind
## 1     11634 122235        0        5 Ochric epipedon
## 2     11634 122235        5       43  Cambic horizon
## 3     11634 122235       43        0  Lithic contact
## 4     32586 158467        0       18 Ochric epipedon
## 5     32586 158467       10       33  Cambic horizon
## 6     32586 158467       33       41  Lithic contact
## 
## $rmf
##       [,1]
## [1,] FALSE

Graphically check the results with soil profile sketches. The Auburn soil is typically shallow to bedrock, limit sketches to 60cm.

par(mar = c(1,0,0,2))
plotSPC(pedons, color = 'moist_soil_color', print.id = FALSE, name = 'hzn_desgn', width = 0.3, name.style = 'center-center', max.depth = 60)

Simplification of fragment data is still a manual process.

# simplify fragment data
s.frags <- simplifyFragmentData(s$morph$phfrags, id.var = 'labsampnum')

# merge fragment data into SPC via "left" join
horizons(pedons) <- s.frags

# check
par(mar = c(0, 0, 3, 2))
plotSPC(pedons, color = 'total_frags_pct', print.id = FALSE, name = 'hzn_desgn', width = 0.3, max.depth = 60)
addVolumeFraction(pedons, 'total_frags_pct', pch = 1, cex.min = 0.25, cex.max = 0.5)

2.1 Fragment Volume >= 100%

There are cases where errors in the source data (NASIS Pedon Horizon Fragments table) suggest coarse fragment volume > 100%. As of soilDB 2.0.2 and aqp 1.15.4, the simplifyFragmentData() function will report such errors and the addVolumeFraction() function will fail gracefully by truncating fragment volume at 100%.

Give it a try with an example (thanks to Brian Gardner for finding it).

# get lab and morphologic data
s <- fetchKSSL(series = 'kettenbach', returnMorphologicData = TRUE)

# extract pedons into SoilProfileCollection
pedons <- s$SPC

# simplify fragment data
s.frags <- simplifyFragmentData(s$morph$phfrags, id.var = 'labsampnum')

# merge fragment data into SPC via left join
horizons(pedons) <- s.frags

# flag horizons with >= 100% total fragment volume
pedons$fragment_errors <- factor(pedons$total_frags_pct >= 100)

# label pedons with user pedon ID
# label horizons with total fragment %
par(mar = c(0, 0, 3, 5))
plotSPC(pedons, color = 'fragment_errors', name = 'total_frags_pct', label = 'pedon_id', cex.name = 0.85)
addVolumeFraction(pedons, colname = 'total_frags_pct', pch = 1, cex.min = 0.25, cex.max = 0.5)
## Warning: 160 is >= 100, likely a data error
## Warning: 180 is >= 100, likely a data error