library(knitr) knitr::opts_chunk$set(message = F, warning = F)
# Sets up output folding hooks = knitr::knit_hooks$get() hook_foldable = function(type) { force(type) function(x, options) { res = hooks[[type]](x, options) if (isFALSE(options[[paste0("fold.", type)]])) return(res) paste0( "<details><summary>", type, "</summary>\n\n", res, "\n\n</details>" ) } } knitr::knit_hooks$set( output = hook_foldable("output"), plot = hook_foldable("plot") )
data.table::setDTthreads(2)
The R package, FIESTA (Forest Inventory ESTimation and Analysis) is a research estimation tool for analysts that work with sample-based inventory data like that from the U.S. Department of Agriculture, Forest Service, Forest Inventory and Analysis (FIA) Program to accommodate: unique population boundaries, different evaluation time periods, customized stratification schemes, non-standard variance equations, integration of multi-scale remotely-sensed data and other auxiliary information, and interaction with other modeling and estimation tools from CRAN R's library of packages. FIESTA contains a collection of functions that can access FIA databases, summarize and compile plot and spatial data, and generate estimates with associated sampling errors.
Functions are organized by type or objective and are named with a corresponding prefix:
Core Functions
Estimation Modules
Analysis Tools
FIESTA's dat tools assist with customizing variables as well as summarizing and visualizing FIA data. The datLUTclass and datLUTnm functions help with merging look-up tables to support new variables, standard FIA code names or unique names, or groupings of discrete or continuous data values. The datSum* functions provide tools for aggregating FIA data for estimation, mapping, or exploratory data analyses.
FIESTA's tree estimates require tree data summarized to the condition (base unit) domain level and extrapolated to an acre to account for trees sampled from different plot sizes. An adjustment factor is applied to adjust for nonsampled plots across different strata (adj='samp') within the area of interest for GB estimates or within each plot (adj='plot') for MA and SA estimates.
The objective of this tutorial is to demonstrate the use of FIESTA's dat tools for customizing, summarizing, and visualizing FIA data. The examples use data from two inventory years of field measurements in the state of Wyoming, from FIADB_1.7.2.00, last updated June 20, 2018, downloaded on June 25, 2018 and stored as internal data objects in FIESTA.
FUNCTION | DESCRIPTION -------------- | --------------------------------------------------------------- datFilter() | Subsets a data table by specified filter(s). datFreq() | Generates frequency table. datPivot() | Generates pivot table. datBarplot() | Generates bar plot. datBarplotStacked() | Generates stacked bar plot. datPiechart() | Generates pie chart. datLUTclass() | Merge look-up table for classifying continuous data (e.g., DIA). datLUTnm() | Merge look-up table to append names or categories. datSumCond() | Aggregates numeric condition data to plot level. datSumTree() | Aggregates numeric tree data to the plot or condition-level. datSumTreeDom() | Aggregates numeric tree data by tree domain to plot or condition level.
We just load the FIESTA
library to get started with the examples.
# Load library library(FIESTA)
The following examples use FIA data from Wyoming for inventory years 2011-2013.
datFilter()
The datFilter
function subsets a data table by specified filter(s) or logical statement and returns a list of the filtered data table and the filter.
View Example
WYconddat.nfs <- datFilter( x = WYcond, xfilter = "ADFORCD > 0" ) names(WYconddat.nfs) WYcond.nfs <- WYconddat.nfs$xf dim(WYcond) dim(WYcond.nfs)
View Example
WYtreedat.dead <- datFilter( x = WYtree, xfilter = "STATUSCD == 2 & STANDING_DEAD_CD == 1 & SPCD == 746" ) names(WYtreedat.dead) WYtree.deadasp <- WYtreedat.dead$xf dim(WYtree.deadasp) dim(WYtree)
View Example
WYtreedat.dead2 <- datFilter( x = WYtree, xfilter = "STATUSCD == 2 & STANDING_DEAD_CD == 1 & SPCD == 746", othertabnms = c("WYplt", "WYcond") ) names(WYtreedat.dead2) WYtree.deadasp2 <- WYtreedat.dead2$xf head(WYtree.deadasp2) dim(WYtree.deadasp2) WYtree.deadasptabs <- WYtreedat.dead2$cliptabs names(WYtree.deadasptabs) WYplt.deadasp <- WYtree.deadasptabs$clip_WYplt WYcond.deadasp <- WYtree.deadasptabs$clip_WYcond dim(WYplt.deadasp) dim(WYcond.deadasp)
datFreq()
The datFreq
function generates a frequency table from a data frame, including number of records by a specified variable or variables in the data frame with optional totals and/or subtotals.
View Example
## Get number of plots by county datFreq( x = WYplt, xvar="COUNTYCD" ) ## Get number of plots by county and plot status datFreq( x = WYplt, xvar=c("COUNTYCD", "PLOT_STATUS_CD") ) ## Get number of plots by county and plot status with subtotals datFreq( x = WYplt, xvar = c("COUNTYCD", "PLOT_STATUS_CD"), subtotal = TRUE ) ## Get number of plots by county and plot status with subtotals datFreq( x = WYplt, xvar = c("COUNTYCD", "PLOT_STATUS_CD"), subtotal = TRUE, subtotalcol = "COUNTYCD" )
datPivot()
The datPivot
function generates a pivot table.
View Example
## Get summed condition proportions by forest type class and stand size class datPivot( x = WYcond, pvar = "CONDPROP_UNADJ", xvar = "FORTYPCD", yvar = "STDSZCD" ) ## Get average height by species group code and status code datPivot( x = WYtree, pvar = "HT", xvar = "SPGRPCD", yvar = "TREECLCD", pfun = mean )
datLUTclass()
The datLUTclass
function merges a look-up table to define categories of continuous data in x
(e.g., DIACL
). Adds a variable to x
, setting the variable to VARCLNM
where: xvar >= MIN
and xvar < MAX
.
FIESTA
with 2-inch Diameter ClassesView Example
FIESTAutils::ref_diacl2in WYtreelut <- datLUTclass( x = WYtree, xvar = "DIA", LUT = FIESTAutils::ref_diacl2in, LUTclassnm = "DIACL2IN" ) names(WYtreelut) WYtree2 <- WYtreelut$xLUT head(WYtree2) dim(WYtree) dim(WYtree2)
View Example
diacl25 <- data.frame( MIN = c(5,25), MAX = c(25, 100), DIACL25 = c("5.0-24.9", "25.0+" ) ) diacl25 WYtreelut2 <- datLUTclass( x = WYtree, xvar = "DIA", LUT = diacl25, LUTclassnm = "DIACL25" ) names(WYtreelut2) WYtree2 <- WYtreelut2$xLUT head(WYtree2) dim(WYtree) dim(WYtree2)
LIVE_CANOPY_CVR_PCT
variable from WYcond
TableView Example
cutbreaks <- c(0,25,50,100) WYcondlut <- datLUTclass( x = WYcond, xvar = "LIVE_CANOPY_CVR_PCT", cutbreaks = cutbreaks ) names(WYcondlut) head(WYcondlut$xLUT) WYcondlut$LUT
datLUTnm()
The datLUTnm
function merges a look-up table to append new variables, names, or categories to x
.
View Example
First, we can look at a reference table stored in FIESTA
with code descriptions of common FIA attributes.
head(FIESTAutils::ref_codes) unique(FIESTAutils::ref_codes$VARIABLE)
Next, we set the code descriptions for FIA disturbance variable.
ref_dstrbcd <- FIESTAutils::ref_codes[FIESTAutils::ref_codes$VARIABLE == "DSTRBCD",] head(ref_dstrbcd)
Next, we can append forest type names using the reference table above.
WYcondlut <- datLUTnm( x = WYcond, xvar = "DSTRBCD1", LUT = ref_dstrbcd, LUTvar = "VALUE", LUTnewvar = "MEANING", LUTnewvarnm = "DSTRB1NM" ) names(WYcondlut) WYcond2 <- WYcondlut$xLUT head(WYcond2[WYcond2$DSTRBCD1 > 0, ])
Now, we can append forest type names using datLUTnm
. If the xvar
is in the stored reference table, the name and values will automatically be appended.
WYcondlut2 <- datLUTnm( x = WYcond, xvar = "DSTRBCD1", FIAname = TRUE ) names(WYcondlut2) WYcond3 <- WYcondlut2$xLUT head(WYcond3[WYcond3$DSTRBCD1 > 0, ])
datSumCond()
The datSumCond
functions aggregates the CONDPROP_UNADJ
variable or other continuous condition variables to plot level with option to apply condition filters. If condition variable is not CONDPROP_UNADJ
the variable is multiplied by CONDPROP_UNADJ
for a weighted sum.
The function returns a list of the following:
condsum
- plot-level table with aggregated condition attribute.
cfilter
- condition filter
View Example
First, we aggregate LIVE_CANOPY_CVR_PCT
to plot, weighted by CONDPROP_UNADJ
.
condsumdat <- datSumCond( cond = WYcond, csumvar = "LIVE_CANOPY_CVR_PCT" ) names(condsumdat) condsum <- condsumdat$condsum head(condsum)
Next, we check results.
condsum[condsum$PLT_CN == 40405596010690,] WYcond[WYcond$PLT_CN == 40405596010690,]
Next, we can append results to plot table.
condsum <- datSumCond( cond = WYcond, plt = WYplt, csumvar = "LIVE_CANOPY_CVR_PCT" )$condsum head(condsum)
We can also add a filter.
condsum <- datSumCond( cond = WYcond, plt = WYplt, csumvar = "LIVE_CANOPY_CVR_PCT", cfilter = "STDSZCD == 1" )$condsum head(condsum) ## Check results condsum[condsum$CN == 40405596010690,] WYcond[WYcond$PLT_CN == 40405596010690,]
Next, we look at summed nonforest condition proportions by plot.
condnf <- datSumCond( cond = WYcond, plt = WYplt, csumvar = "CONDPROP_UNADJ", csumvarnm = "cond_nf", cfilter = "COND_STATUS_CD %in% c(2,3)" )$condsum condnf[condnf$CN == 40404737010690,] WYcond[WYcond$PLT_CN == 40404737010690,]
Finally, we can look at summed reserved condition proportions by plot.
condres <- datSumCond( cond = WYcond, plt = WYplt, csumvar = "CONDPROP_UNADJ", csumvarnm = "cond_reserved", cfilter = "RESERVCD == 1" )$condsum WYcond[WYcond$PLT_CN == 46792188020004,]
datSumTree()
The datSumTree
function aggregates tree-level data to plot or condition, including options for filtering tree data or extrapolating to plot acre by multiplying by trees per acre (TPA*
).
Returns a list of the following:
treedat - plot or condition-level table with aggregated tree attribute(s).
sumvars - Name(s) of the output aggregated tree attributes.
TPA=FALSE
)View Example
treesumdat1 <- datSumTree( tree = WYtree, plt = WYplt, tsumvarlst = c("BA", "VOLCFNET"), tfilter = "STATUSCD == 1", bycond = FALSE, datSum_opts = list(TPA = FALSE, tround = 2) ) names(treesumdat1) treesum1 <- treesumdat1$treedat head(treesum1) treesumdat1$sumvars
TPA=TRUE
)View Example
treesumdat2 <- datSumTree( tree = WYtree, plt = WYplt, tsumvarlst = c("BA", "VOLCFNET"), tfilter = "STATUSCD == 1", bycond = FALSE, datSum_opts = list(TPA = TRUE, tround = 2) ) names(treesumdat2) treesum2 <- treesumdat2$treedat head(treesum2)
View Check
checkvars <- c("PLT_CN", "CONDID", "SUBP", "TREE", "STATUSCD", "SPCD", "DIA", "HT", "BA", "VOLCFNET", "TPA_UNADJ") testplt <- WYtree[WYtree$PLT_CN == 40404758010690, checkvars] testplt sum(testplt[testplt$STATUSCD == 1, "BA"], na.rm=TRUE) sum(testplt[testplt$STATUSCD == 1, "BA"] * testplt[testplt$STATUSCD == 1, "TPA_UNADJ"], na.rm=TRUE) treesum1[treesum1$CN == 40404758010690,] treesum2[treesum2$CN == 40404758010690,]
View Example
treesumdat3 <- datSumTree( tree = WYtree, plt = WYplt, tderive = list(MEAN_DIA = 'AVG(DIA)', MEAN_HT = 'AVG(HT)'), tfilter = "STATUSCD == 1", bycond = FALSE, datSum_opts = list(TPA = FALSE, tround = 2) ) names(treesumdat3) treesum3 <- treesumdat3$treedat head(treesum3) ## Test DIA and HT results for 1 plot testplt mean(testplt[testplt$STATUSCD == 1, "DIA"], na.rm=TRUE) mean(testplt[testplt$STATUSCD == 1, "HT"], na.rm=TRUE) treesum3[treesum3$PLT_CN == 40404758010690,]
TPA=TRUE
)View Example
treesumdat4a <- datSumTree( tree = WYtree, plt = WYplt, tsumvarlst = "TPA_UNADJ", tfilter = "STATUSCD == 1", bycond = FALSE, datSum_opts = list(TPA = TRUE, tround = 2) ) names(treesumdat4a) treesum4a <- treesumdat4a$treedat head(treesum4a)
View Example
Note: Must include condition table for condition proportion variables
treesumdat4b <- datSumTree( tree = WYtree, plt = WYplt, cond = WYcond, tderive = list(MEAN_DIA = 'AVG(DIA)'), tsumvarlst = "VOLCFNET", tfilter = "STATUSCD == 1", bycond = FALSE, getadjplot = TRUE ) names(treesumdat4b) treesum4b <- treesumdat4b$treedat head(treesum4b)
COND_STATUS_CD = 5
and CONDPROP_UNADJ = 0.25
)View Example
treesumdat4c <- datSumTree( tree = WYtree, plt = WYplt, cond = WYcond, tsumvarlst = "VOLCFNET", tfilter = "STATUSCD == 1", bycond = FALSE, getadjplot = FALSE ) treesum4c <- treesumdat4c$treedat cn <- 40407815010690 WYcond[WYcond$PLT_CN == cn, ] treesum4b[treesum4b$CN == cn, ] treesum4c[treesum4c$CN == cn, ]
TPA=TRUE
)View Example
treesumdat5a <- datSumTree( tree = WYtree, plt = WYplt, seed = WYseed, tsumvarlst = "TPA_UNADJ", seedlings = "Y", tfilter = "STATUSCD == 1", bycond = FALSE, datSum_opts = list(TPA = TRUE, tround = 2) ) names(treesumdat5a) treesum5a <- treesumdat5a$treedat head(treesum5a) treesum5a[treesum5a$CN %in% cn,] WYseed[WYseed$PLT_CN == cn,]
TPA=TRUE
) - AdjustedView Example
treesumdat5b <- datSumTree( tree = WYtree, plt = WYplt, cond = WYcond, seed = WYseed, tsumvarlst = "TPA_UNADJ", seedlings = "Y", tfilter = "STATUSCD == 1", bycond = FALSE, getadjplot =TRUE, datSum_opts = list(TPA = TRUE, tround = 2) ) names(treesumdat5b) treesum5b <- treesumdat5b$treedat head(treesum5b) treesum5a[treesum5a$CN %in% cn,] treesum5b[treesum5b$CN %in% cn,] WYcond[WYcond$PLT_CN %in% cn,]
datSumTreeDom()
The datSumTreeDom
function aggregates tree-level data to plot or condition, including options for filtering tree data or extrapolating to plot acre by multiplying by TPA
.
It returns a list of the following:
tdomdat
- plot or condition-level table with aggregated tree domain attributes.
tdomsum
- the tdom look-up table with data aggregated by species.
tsumvar
- name of aggregated output variable.
tdomlst
- list of the aggregated data in tdomdat.
tdomdat.pres
- if presence=TRUE, plot or condition-level table with aggregated
domain attributes represented as presence/absence (1/0).
tdomdat.prop
- if presence=TRUE, plot or condition-level table with aggregated
domain attributes represented as proportion of total by plot.
tdomdat.pres
- if presence=TRUE, plot or condition-level table with aggregated
domain attributes represented as percent cover, multiplying cover attribute
by tdom proportion by plot.
View Example
treedomBA <- datSumTreeDom( tree = WYtree, cond = WYcond, plt = WYplt, bycond = FALSE, tsumvar = "BA", tdomtot = TRUE, tdomtotnm = "BA_LIVE", tdomprefix = "BA_LIVE", tfilter = "STATUSCD==1", datSum_opts = list(TPA = TRUE, tround = 2) ) names(treedomBA) tdomdat <- treedomBA$tdomdat tdomvarlut <- treedomBA$tdomvarlut tdomlst <- treedomBA$tdomlst tdomtotnm <- treedomBA$tdomtotnm head(tdomdat) tdomvarlut tdomlst tdomtotnm dim(WYplt) dim(tdomdat)
View Example
treedomCNT <- datSumTreeDom( tree = WYtree, cond = WYcond, plt = WYplt, bycond = FALSE, tsumvar = "TPA_UNADJ", tdomtot = TRUE, tdomprefix = "CNT", tfilter = "STATUSCD==1", datSum_opts = list(TPA = TRUE, tround = 0) ) names(treedomCNT) tdomdat.tree <- treedomCNT$tdomdat tdomvarlut <- treedomCNT$tdomvarlut tdomlst <- treedomCNT$tdomlst tdomtotnm <- treedomCNT$tdomtotnm head(tdomdat.tree)
View Example
treedomCNTs <- datSumTreeDom( cond = WYcond, plt = WYplt, seed = WYseed, bycond = FALSE, tsumvar = "TPA_UNADJ", tdomtot = TRUE, tdomprefix = "CNT", datSum_opts = list(TPA = TRUE, tround = 0) ) names(treedomCNTs) tdomdat.seed <- treedomCNTs$tdomdat tdomvarlut <- treedomCNTs$tdomvarlut tdomlst <- treedomCNTs$tdomlst tdomtotnm <- treedomCNTs$tdomtotnm head(tdomdat.seed)
View Example
treedomCNTs <- datSumTreeDom( tree = WYtree, cond = WYcond, plt = WYplt, seed = WYseed, bycond =FALSE, tsumvar = "TPA_UNADJ", tdomtot = TRUE, tdomprefix = "CNT", tfilter = "STATUSCD==1", seedlings = "Y", datSum_opts = list(TPA = TRUE, tround = 0) ) names(treedomCNTs) tdomdat.treeseed <- treedomCNTs$tdomdat tdomvarlut <- treedomCNTs$tdomvarlut tdomlst <- treedomCNTs$tdomlst tdomtotnm <- treedomCNTs$tdomtotnm head(tdomdat.treeseed) cn <- 40404730010690 tdomdat.tree[tdomdat.tree$CN == cn,] tdomdat.seed[tdomdat.seed$CN == cn,] tdomdat.treeseed[tdomdat.treeseed$CN == cn,]
View Example
treedomCNTs <- datSumTreeDom( tree = WYtree, cond = WYcond, plt = WYplt, seed = WYseed, bycond = FALSE, tsumvar = "PLT_CN", tdomtot = TRUE, tdomprefix = "CNT", savedata = FALSE, tfilter = "STATUSCD==1", seedlings = "Y", presence = TRUE, datSum_opts = list(TPA = TRUE) ) names(treedomCNTs) tdomdat.pres <- treedomCNTs$tdomdat.pres head(tdomdat.pres)
View Example
treedomCNTs <- datSumTreeDom(tree = WYtree, cond = WYcond, plt = WYplt, seed = WYseed, bycond = FALSE, tsumvar = "TPA_UNADJ", tdomtot = TRUE, tdomprefix = "CNT", savedata = FALSE, tfilter = "STATUSCD==1", seedlings = "Y", proportion = TRUE, datSum_opts = list(tround = 0)) names(treedomCNTs) tdomdat.pres <- treedomCNTs$tdomdat.pres tdomdat.prop <- treedomCNTs$tdomdat.prop head(tdomdat.pres)
View Example
treedomCNTs <- datSumTreeDom( tree = WYtree, cond = WYcond, plt = WYplt, seed = WYseed, bycond = FALSE, tsumvar = "PLT_CN", tdomtot = TRUE, tdomprefix = "CNT", tfilter = "STATUSCD==1", seedlings = "Y", presence = TRUE, proportion = TRUE, tdombarplot = TRUE, datSum_opts = list(TPA = TRUE, tround = 0) ) names(treedomCNTs) tdomdat.pres <- treedomCNTs$tdomdat.pres tdomdat.prop <- treedomCNTs$tdomdat.prop cn=40404742010690 tdomdat.tree[tdomdat.tree$CN == cn,] tdomdat.seed[tdomdat.seed$CN == cn,] tdomdat.treeseed[tdomdat.treeseed$CN == cn,] tdomdat.pres[tdomdat.pres$CN == cn,] tdomdat.prop[tdomdat.prop$CN == cn,]
View Example
treedomCNTs <- datSumTreeDom( tree = WYtree, cond = WYcond, plt = WYplt, seed = WYseed, bycond = FALSE, tsumvar = "PLT_CN", tdomtot = TRUE, tdomprefix = "CNT", tfilter = "STATUSCD==1", seedlings = "Y", presence = TRUE, proportion = TRUE, tdombarplot = TRUE, datSum_opts = list(TPA = TRUE, tround = 0) ) names(treedomCNTs) tdomdat.pres <- treedomCNTs$tdomdat.pres tdomdat.prop <- treedomCNTs$tdomdat.prop head(tdomdat.pres)
SPCD=113
) Trees >= 1.0 DIAView Example
treedomBA <- datSumTreeDom( tree = WYtree, cond = WYcond, plt = WYplt, bycond = FALSE, tsumvar = "BA", tdomprefix = "BA", tdomvarlst = 113, tfilter = "STATUSCD==1", datSum_opts = list(tround = 2) ) names(treedomBA) ba.limber <- treedomBA$tdomdat head(ba.limber)
View Example
## Total basal area per acre by species and diameter class DIALUT <- FIESTAutils::ref_diacl2in[FIESTAutils::ref_diacl2in$MIN <= 37, ] names(DIALUT)[names(DIALUT) == "MEANING"] <- "DIACL2IN" ## Append diameter classes to tree table datlut <- datLUTclass( x = WYtree, xvar = "DIA", LUT = DIALUT, LUTclassnm = "DIACL2IN" ) WYtree2 <- datlut$xLUT ## Species and diameter class treedomDIACNTs <- datSumTreeDom( tree = WYtree2, cond = WYcond, plt = WYplt, bycond = FALSE, tsumvar = "PLT_CN", tdomtot = TRUE, tdomprefix = "CNT", tfilter = "STATUSCD==1 & DIA > 30", presence = TRUE, proportion = TRUE, tdomvar2 = "DIACL2IN", tdombarplot = TRUE, datSum_opts = list(TPA = TRUE, tround = 2) ) names(treedomDIACNTs) tdomdat.pres <- treedomDIACNTs$tdomdat.pres tdomdat.prop <- treedomDIACNTs$tdomdat.prop head(tdomdat.pres)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.