|
| 1 | +#' @noRd |
| 2 | +#' @export |
| 3 | +predict_crwidth <- function(tree_list) { |
| 4 | + if (missing(tree_list) || is.null(tree_list)) |
| 5 | + stop("'tree_list' is required", call. = FALSE) |
| 6 | + |
| 7 | + if (!is.data.frame(tree_list)) |
| 8 | + stop("'tree_list' must be a data frame", call. = FALSE) |
| 9 | + |
| 10 | + required_cols <- c("SPCD", "STATUSCD", "DIA") |
| 11 | + if (!all(required_cols %in% colnames(tree_list))) |
| 12 | + stop("'tree_list' is missing required columns", call. = FALSE) |
| 13 | + |
| 14 | + if (!is.numeric(tree_list$SPCD)) |
| 15 | + stop("'tree_list$SPCD' must be numeric or integer", call. = FALSE) |
| 16 | + if (any(is.na(tree_list$SPCD))) |
| 17 | + stop("'tree_list$SPCD' cannot have missing values", call. = FALSE) |
| 18 | + |
| 19 | + if (!is.numeric(tree_list$STATUSCD)) |
| 20 | + stop("'tree_list$STATUSCD' must be numeric or integer", call. = FALSE) |
| 21 | + if (any(is.na(tree_list$STATUSCD))) |
| 22 | + stop("'tree_list$STATUSCD' cannot have missing values", call. = FALSE) |
| 23 | + |
| 24 | + if (!is.numeric(tree_list$DIA)) |
| 25 | + stop("'tree_list$DIA' must be numeric", call. = FALSE) |
| 26 | + if (any(is.na(tree_list$DIA))) |
| 27 | + stop("'tree_list$DIA' cannot have missing values", call. = FALSE) |
| 28 | + |
| 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")] |
| 32 | + |
| 33 | + cw <- rep_len(NA_real_, nrow(tree_list)) |
| 34 | + |
| 35 | + # special case for large trees of certain species in the PNW region: |
| 36 | + # use the "old growth" equation from Gill et al. (2000) |
| 37 | + old_growth_trees <- tree_list$DIA > 50 & tree_list$STATUSCD == 1 & |
| 38 | + tree_list$SPCD %in% c(11, 98, 108, 119, 122, 202, 242, 263, 264) |
| 39 | + |
| 40 | + cw[old_growth_trees] <- 16.449 + 0.4067 * tree_list$DIA[old_growth_trees] |
| 41 | + |
| 42 | + # apply species-specific equations |
| 43 | + # NB: crwidth of trees with DIA < 5 in. (i.e. "saplings") is predicted for |
| 44 | + # DIA = 5 and then sapling crwidth adjustment factors are applied afterward |
| 45 | + for (spcd in unique(tree_list$SPCD)) { |
| 46 | + b <- cw_coef[cw_coef$SPCD == spcd, c("b0", "b1", "b2")] |
| 47 | + if (nrow(b) == 0) |
| 48 | + b <- b_default |
| 49 | + |
| 50 | + this_subset <- tree_list$SPCD == spcd & tree_list$STATUSCD == 1 & |
| 51 | + is.na(cw) |
| 52 | + |
| 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 | + } |
| 58 | + } |
| 59 | + |
| 60 | + # apply sapling crown width adjustment factors |
| 61 | + saplings <- tree_list$DIA < 5 & tree_list$STATUSCD == 1 |
| 62 | + 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 | + |
| 68 | + |
| 69 | + return(cw) |
| 70 | +} |
0 commit comments