Skip to content

Commit 75fb8e1

Browse files
committed
add predict_crwidth()
1 parent 8b8c9bb commit 75fb8e1

5 files changed

Lines changed: 125 additions & 20 deletions

File tree

R/data.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#'
1313
#' where `CW` is the predicted tree crown diameter in feet, `DIA` is FIA stem
1414
#' diameter in inches, and `b0`, `b1`, `b2` are the regression coefficients.
15-
#' The quadratic term `b2` was not included in the regression models for some
15+
#' The quadratic term `b2` is not included in the regression models for some
1616
#' species, and has been assigned `0` in that case for purposes of this lookup
1717
#' table.
1818
#'

R/predict_crwidth.R

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
1-
#' @noRd
1+
#' Compute predicted tree crown width using species-specific equations
2+
#'
3+
#' `predict_crwidth()` computes tree crown width using species-specific
4+
#' regression equations from the literature.
5+
#'
6+
#' @details
7+
#' Crown width is predicted from tree diameter using coefficients provided in
8+
#' the lookup table [cw_coef] (see `?cw_coef` for detailed documentation and
9+
#' references). The method also incorporates adjustment factors used to derive
10+
#' crown width estimates for FIA "saplings", i.e., trees less than 5.0 in.
11+
#' (12.7 cm) diameter but greater than or equal to 1.0 in. (2.54 cm) diameter.
12+
#' Details are described in the documentation for the lookup table
13+
#' [cw_sapling_adj].
14+
#'
15+
#' Large diameter trees in the temperate rain forests of the Pacific Northwest
16+
#' region can far exceed the range of diameters in the broadly applicable
17+
#' datasets that have been used to develop crown width prediction equations. To
18+
#' avoid extrapolation beyond the range of the model fitting data in those
19+
#' cases, `predict_crwidth()` makes use of the "old growth" equation presented
20+
#' by Gill et al. (2000) to estimate crown width for nine tree species when
21+
#' their diameter is greater than 50 in. (127 cm).
22+
#'
23+
#' @param tree_list A data frame containing tree records. Must have columns
24+
#' `SPCD` (FIA integer species code), `STATUSCD` (FIA integer tree status code,
25+
#' 1 = live) and `DIA` (FIA tree diameter in inches).
26+
#' @param digits Optional integer indicating the number of digits to keep in the
27+
#' return values (defaults to `1`).
28+
#' @return
29+
#' A numeric vector of length `nrow(tree_list)` with predicted crown width in
30+
#' feet for live trees. `NA` is returned for trees with `STATUSCD != 1`.
31+
#'
32+
#' @references
33+
#' Gill, S.J., G.S. Biging, E.C. Murphy. 2000. Modeling conifer tree crown
34+
#' radius and estimating canopy cover. _Forest Ecology and Management_, 126(3):
35+
#' 405-416.
36+
#'
37+
#' @examples
38+
#' predict_crwidth(plantation)
239
#' @export
3-
predict_crwidth <- function(tree_list) {
40+
predict_crwidth <- function(tree_list, digits = 1) {
441
if (missing(tree_list) || is.null(tree_list))
542
stop("'tree_list' is required", call. = FALSE)
643

@@ -26,12 +63,15 @@ predict_crwidth <- function(tree_list) {
2663
if (any(is.na(tree_list$DIA)))
2764
stop("'tree_list$DIA' cannot have missing values", call. = FALSE)
2865

29-
# default regression coefficients if species-specific ones are missing
30-
# SPCD == 807, blue oak
31-
b_default <- cw_coef[cw_coef$SPCD == 807, c("b0", "b1", "b2")]
66+
if (is.null(digits))
67+
digits <- 2
3268

3369
cw <- rep_len(NA_real_, nrow(tree_list))
3470

71+
# define a default equation to use in case a species-specific one is missing
72+
# SPCD == 807, blue oak
73+
b_default <- cw_coef[cw_coef$SPCD == 807, c("b0", "b1", "b2")]
74+
3575
# special case for large trees of certain species in the PNW region:
3676
# use the "old growth" equation from Gill et al. (2000)
3777
old_growth_trees <- tree_list$DIA > 50 & tree_list$STATUSCD == 1 &
@@ -47,24 +87,39 @@ predict_crwidth <- function(tree_list) {
4787
if (nrow(b) == 0)
4888
b <- b_default
4989

50-
this_subset <- tree_list$SPCD == spcd & tree_list$STATUSCD == 1 &
51-
is.na(cw)
90+
this_subset <-
91+
tree_list$SPCD == spcd & tree_list$STATUSCD == 1 & is.na(cw)
5292

53-
if (length(this_subset) > 0) {
54-
cw[this_subset] <- b$b0[1] +
55-
b$b1[1] * pmax(5, tree_list$DIA[this_subset]) +
56-
b$b2[1] * pmax(5, tree_list$DIA[this_subset])^2
57-
}
93+
cw[this_subset] <-
94+
b$b0 + b$b1 * pmax(5, tree_list$DIA[this_subset]) +
95+
b$b2 * pmax(5, tree_list$DIA[this_subset])^2
5896
}
5997

6098
# apply sapling crown width adjustment factors
6199
saplings <- tree_list$DIA < 5 & tree_list$STATUSCD == 1
62100
sapling_spp <- unique(tree_list$SPCD[saplings])
63-
# species-specific adjustment factors if any
64-
spp_adj <- intersect(sapling_spp, cw_sapling_adj$SPCD)
65-
# TODO:
66-
# ...
67-
101+
# species-specific adjustment factors if any (based on Bragg 2001)
102+
spcd_adj <- intersect(sapling_spp, cw_sapling_adj$SPCD)
103+
for (spcd in spcd_adj) {
104+
rowid <- which(cw_sapling_adj$SPCD == spcd)
105+
# adjustment factors at 1, 2, 3, 4, 5 inches DIA:
106+
adj_factors <- c(as.numeric(cw_sapling_adj[rowid, 2:5]), 1)
107+
this_subset <- saplings & tree_list$SPCD == spcd
108+
# interpolated adjustment factors for the actual sapling diameters:
109+
n <- trunc(tree_list$DIA[this_subset])
110+
cw_adj <- (tree_list$DIA[this_subset] - n) *
111+
(adj_factors[n + 1] - adj_factors[n]) + adj_factors[n]
112+
cw[this_subset] <- cw[this_subset] * cw_adj
113+
}
114+
# otherwise use avarage adjustment factors based on Bragg (2001) data
115+
# average adjustment factors at 1, 2, 3, 4, 5 inches DIA:
116+
adj_factors <- c(0.509, 0.644, 0.767, 0.885, 1.0)
117+
this_subset <- saplings & !(tree_list$SPCD %in% cw_sapling_adj$SPCD)
118+
# interpolated adjustment factors for the actual sapling diameters:
119+
n <- trunc(tree_list$DIA[this_subset])
120+
cw_adj <- (tree_list$DIA[this_subset] - n) *
121+
(adj_factors[n + 1] - adj_factors[n]) + adj_factors[n]
122+
cw[this_subset] <- cw[this_subset] * cw_adj
68123

69-
return(cw)
124+
round(cw, digits = digits)
70125
}

_pkgdown.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ reference:
2121
- title: Functions
2222
- contents:
2323
- overlay_crowns
24+
- predict_crwidth
2425
- spatstat_helpers

man/cw_coef.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/predict_crwidth.Rd

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)