Here I go through the process of cleaning the 2025 Google Form entries.
library(tidyverse)
library(readr)
library(styler)
health_assess_2025 <- read_csv("data/july_16_2025_Butternut Health Assessment Form (Responses).csv")
# health_assess_2025 <- health_assess_2025 %>% slice(109)
# health_assess_2025$`Any additional notes?`
health_assess_2025 <- health_assess_2025 %>% select(
-`Number of the 1st photo taken`,
-`Number of the last photo taken`,
-`Producing seed?`,
-`Roughly how many seeds are on the tree?`,
-`How many seed are in each bunch (average estimate)?`,
-`What is the crown class of this individual?`,
# Collections
-`What did you collect?`,
-`If VOUCHERS were collected, how many?`,
-`If LEAVES were collected, how many?`,
-`If CUTTINGS were collected, how many?`,
-`If SEEDS were collected, how many?`,
-`If other collections were made, please describe them here including the number collected.`,
-`How deep are the furrows in the bark?`,
-`What shade (from light/white to dark) is the tree bark?`,
# Environment
-`Riparian or upland?`,
-`Associated tree species within 20 meters.`,
-`What competition is potentially threatening this tree?`,
-`If you answered "Other" above, please explain.`,
-`Does this seedling show signs of damage from any of the following?`,
-`Does this tree show any signs of any of the following?`,
#Accessory Information
-Camera,
-Notes1,
-Notes2,
-Notes3,
-Notes4,
-Notes5,
-Notes6,
-Notes7,
#Editing
-`Edited after field collection? (Y/N)`,
-`If edited, what date:`,
-`If edited, what:`,
)
#colnames(health_assess_2025)
Note that this section will not work if the question wording has been changed since July 16th, 2025
# Plant Height (ft)
health_assess_2025 <- health_assess_2025 %>% rename(plant_height_ft = `Plant Height (in FEET)`)
# DBH
health_assess_2025 <- health_assess_2025 %>% rename(dbh_cm = `DBH (in CENTIMETERS)`)
# has_canker
health_assess_2025 <- health_assess_2025 %>% rename(has_canker = `Visible cankers?`)
# has_callous
health_assess_2025 <- health_assess_2025 %>% rename(has_callous = `If large cankers are present, do you see evidence of callousing, whether currently being calloused over or having previously been calloused over?
If there are no large cankers present, enter "NA." If there are large cankers present but it is not clear whether to not they are healing over, enter "Maybe."`)
# seedling_y_n
health_assess_2025 <- health_assess_2025 %>% rename(seedling_y_n = `Is this individual a seedling?`)
# % live canopy
health_assess_2025 <- health_assess_2025 %>% rename(percent_live_canopy = `Percent live canopy (estimate, being sure to only include live branches in assessment)
Note: This is a measure of crown density. In order to estimate this, first envision the amount of canopy there would be if the tree were fully healthy. Butternuts do not typically have a tightly formed canopy even when healthy so be sure to evaluate based on branch presence and location. Then estimate what percent of the envisioned canopy is actually present. This will be your estimate of percent live canopy.`)
# base_epicormics
health_assess_2025 <- health_assess_2025 %>% rename(base_epicormics = `Number of epicormic branches / sprouts from the base`)
# trunk_epicormics
health_assess_2025 <- health_assess_2025 %>% rename(trunk_epicormics = `Number of epicormic branches / sprouts from the trunk`)
# girdled_canker_circum_2025
health_assess_2025 <- health_assess_2025 %>% rename(girdled_canker_circum = `At the part of the trunk that appears most girdled by canker, what portion of the circumference of the trunk is girdled?`)
# trunk_canker_area
health_assess_2025 <- health_assess_2025 %>% rename(trunk_canker_area = `How much area of the trunk below first main branch is infected by canker, measured as a percentage of total trunk with cankers visible (including cankering visible underneath uplifted bark)?`)
# base_canker_area
health_assess_2025 <- health_assess_2025 %>% rename(base_canker_area = `How much area of the base/ root flare is infected by canker, e.g. as a percentage of root flare (up to 10 cm above soil) with cankers visible (including underneath bark)?`)
# densio_north
health_assess_2025 <- health_assess_2025 %>% rename(densio_north = North)
# densio_south
health_assess_2025 <- health_assess_2025 %>% rename(densio_south = South)
# densio_east
health_assess_2025 <- health_assess_2025 %>% rename(densio_east = East)
# densio_west
health_assess_2025 <- health_assess_2025 %>% rename(densio_west = West)
# purdue_severity_canker
health_assess_2025 <- health_assess_2025 %>% rename(purdue_severity_canker = `Assess severity of infection. Focus on the bottom 10 feet of the tree when assessing the number and size of cankers, noting that cankers can be hard to see on old trees with thick bark. CANKERS:`)
# purdue_severity_canopy
health_assess_2025 <- health_assess_2025 %>% rename(purdue_severity_canopy = `Assess severity of infection. CANOPY:`)
# shape_terminal_bud
health_assess_2025 <- health_assess_2025 %>% rename(shape_terminal_bud = `Shape of terminal bud`)
# shape_leaf_scar
health_assess_2025 <- health_assess_2025 %>% rename(shape_leaf_scar = `Shape of leaf scar`)
# shape_lenticels
health_assess_2025 <- health_assess_2025 %>% rename(shape_lenticels = `Shape / length of lenticels`)
# shape_hairs
health_assess_2025 <- health_assess_2025 %>% rename(shape_hairs = `Hairs on the end of the twigs`)
#colnames(health_assess_2025)
Thoughts * do all the canker areas correlate with each other * does one of the canker areas correlate more with percent live canopy loss? * I would hypothesize that girdled circumference area correlates more with
****THIS SHOULD PROBABLY BE OFF OF PLANT NUMBERS INSTEAD****
# Testing columns (#15, 16, 34, 52, 71)
## 15, 16, 71 all explicitly state testing
## 34 is a BLACK WALNUT
## 52 has unspecific GPS points making me think it is also a testing from when we make it numerical only
health_assess_2025 <- health_assess_2025 %>% slice(c(-15, -16, -34, -52, -71))
# Remove 'Suger River' site from analysis
health_assess_2025 <- filter(
health_assess_2025,
# Notice that its selecting sites which are NOT sugar river
!str_equal(
`Site Number or Initial: JC-W-_______`,
"Sugar river",
ignore_case = TRUE
)
)
health_assess_2025$percent_live_canopy <- parse_number(health_assess_2025$percent_live_canopy)
Run this to view the side by side cleaned numerical canopy values (after removing the %s)
# test_canopy <- health_assess_2025 %>% select(percent_live_canopy) %>% mutate(clean_percent_live_canopy = parse_number(health_assess_2025$percent_live_canopy))
# view(test_canopy)
health_assess_2025$base_canker_area <- parse_number(health_assess_2025$base_canker_area)
# Right now, "Less than 10, but more than 0" just reads in as 10
health_assess_2025$trunk_canker_area <- parse_number(health_assess_2025$trunk_canker_area)
# Right now, "Less than 10, but more than 0" just reads in as 10
health_assess_2025$girdled_canker_circum <- parse_number(health_assess_2025$girdled_canker_circum)
Run this to view the side by side cleaned numerical canker areas
# base_canker_test <- health_assess_2025 %>% select(base_canker_area) %>% mutate(cleaned_base_canker = parse_number(health_assess_2025$base_canker_area))
# view(base_canker_test)
#
# # Right now, "Less than 10, but more than 0" just reads in as 10
# trunk_canker_test <- health_assess_2025 %>% select(trunk_canker_area) %>% mutate(cleaned_trunk_canker = parse_number(health_assess_2025$trunk_canker_area))
# view(trunk_canker_test)
#
# # Right now, "Less than 10, but more than 0" just reads in as 10
# girdled_canker_test <- health_assess_2025 %>% select(girdled_canker_circum_2025) %>% mutate(cleaned_girdled_canker = parse_number(health_assess_2025$girdled_canker_circum_2025))
# view(girdled_canker_test)
health_assess_2025 <- health_assess_2025 %>% mutate(base_canker_area = if_else(has_canker == "No", 0, base_canker_area))
health_assess_2025 <- health_assess_2025 %>% mutate(trunk_canker_area = if_else(has_canker == "No", 0, trunk_canker_area))
health_assess_2025$girdled_canker_circum_2025
## Warning: Unknown or uninitialised column: `girdled_canker_circum_2025`.
## NULL
health_assess_2025 <- health_assess_2025 %>% mutate(girdled_canker_circum = if_else(has_canker == "No", 0, girdled_canker_circum))
Run this to view the side by side added 0s for NO
# base_canker_adding_0s_test <- health_assess_2025 %>% select(has_canker, base_canker_area) %>% mutate(cleaned_base_canker = if_else(has_canker == "Yes", base_canker_area, 0))
# view(base_canker_adding_0s_test)
#
# trunk_canker_adding_0s_test <- health_assess_2025 %>% select(has_canker, trunk_canker_area) %>% mutate(cleaned_trunk_canker = if_else(has_canker == "Yes", trunk_canker_area, 0))
# view(trunk_canker_adding_0s_test)
#
# girdled_circum_adding_0s_test <- health_assess_2025 %>% select(has_canker, girdled_canker_circum_2025) %>% mutate(cleaned_girdled_circum = if_else(has_canker == "Yes", girdled_canker_circum_2025, 0))
# view(girdled_circum_adding_0s_test)
health_assess_2025 <- health_assess_2025 %>% mutate(
# Clean up the text for consistency (e.g., remove extra spaces, make lowercase)
height_str = str_to_lower(str_trim(dbh_cm)),
# Extract the first decimal number, this will always be the cm
# Note that broadly "\\d+\\.?\\d*" selection nomenclature simily breaks down to: get the "Digits, maybe a dot, maybe more digits"
# Where the "\\d+" gets all the first whole digits,
# then the "\\.?" will check whether there is a literal decimal point,
# if there is then "\\d*" gets all remaining digits
dbh_cm = as.numeric(str_extract(height_str, "\\d+\\.?\\d*")),
) %>% select(-height_str) # Only keep the new dbh value
Run this to test side-by-side ‘cm’ removal
# test_dbh <- health_assess_2025 %>% select(dbh_cm) %>% mutate(
# # Clean up the text for consistency (e.g., remove extra spaces, make lowercase)
# height_str = str_to_lower(str_trim(dbh_cm)),
#
# # Extract the first decimal number, this will always be the cm
# # Note that broadly "\\d+\\.?\\d*" selection nomenclature simily breaks down to: get the "Digits, maybe a dot, maybe more digits"
# # Where the "\\d+" gets all the first whole digits,
# # then the "\\.?" will check whether there is a literal decimal point,
# # if there is then "\\d*" gets all remaining digits
# dbh_cm_new = as.numeric(str_extract(height_str, "\\d+\\.?\\d*")),
#
# ) %>% select(-height_str) # Only keep the new dbh value
# view(test_dbh)
These are related because I have to verify DBH by having an accurate height
Many of the height entries were first inputted as “1 foot 3 inches”, explicitly writing out the components. Instead, we want just a pure feet measurement in that column. So, I will extract the feet/foot numbers and inches and then convert those accordingly.
health_assess_2025 <- health_assess_2025 %>% mutate(
# Big picture height cleaning:
# * Assume in feet if no units are written into the box
# * If units are written in the box: extract them and re-calculate the heigh
# ------------------ Process:
# Clean up the text for consistency (e.g., remove extra spaces, make lowercase)
height_str = str_to_lower(str_trim(plant_height_ft)),
# Extract the first decimal number, this will always be the feet
# Note that broadly "\\d+\\.?\\d*" selection nomenclature simily breaks down to: get the "Digits, maybe a dot, maybe more digits"
# Where the "\\d+" gets all the first whole digits,
# then the "\\.?" will check whether there is a literal decimal point,
# if there is then "\\d*" gets all remaining digits
feet_str = str_extract(height_str, "\\d+\\.?\\d*\\s*(ft)"),
feet = as.numeric(str_extract(feet_str, "\\d+\\.?\\d*")),
# Get the string of inches which will be based on either the presence of "inches" or "in",
# e.g., "7 inches" or "7in"
inches_str = str_extract(height_str, "\\d+\\.?\\d*\\s*(inches|in)"),
# Extract the decimal from the isolated inches string, like the feet
inches = as.numeric(str_extract(inches_str, "\\d+\\.?\\d*")),
# Convert using the numerical values
# Where 'coalesce' will use a 0 if feet/inches is an NA value
calculated_from_text_feet = (coalesce(feet, 0)) + (coalesce(inches, 0) / 12.0),
# Seeing if the entry has additional text in it like "ft" or "inches"
contains_text = str_detect(height_str, "ft") |
str_detect(height_str, "inches") | str_detect(height_str, "in"),
# Assume the plant_height_ft is the string as a number if the entry doesn't have text.
plant_height_ft = if_else(
!contains_text,
as.numeric(height_str),
calculated_from_text_feet
)
) %>% select(
-height_str,
-feet_str,
-feet,
-inches_str,
-inches,
-calculated_from_text_feet,
-contains_text
)
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `plant_height_ft = if_else(!contains_text,
## as.numeric(height_str), calculated_from_text_feet)`.
## Caused by warning in `if_else()`:
## ! NAs introduced by coercion
Run this to see the full break down off the calculation and extraction
# test_height_cleaning <- health_assess_2025 %>% select(plant_height_ft) %>% mutate(
# # Big picture height cleaning:
# # * Assume in feet if no units are written into the box
# # * If units are written in the box: extract them and re-calculate the heigh
#
# # ------------------ Process:
# # Clean up the text for consistency (e.g., remove extra spaces, make lowercase)
# height_str = str_to_lower(str_trim(plant_height_ft)),
#
# # Extract the first decimal number, this will always be the feet
# # Note that broadly "\\d+\\.?\\d*" selection nomenclature simily breaks down to: get the "Digits, maybe a dot, maybe more digits"
# # Where the "\\d+" gets all the first whole digits,
# # then the "\\.?" will check whether there is a literal decimal point,
# # if there is then "\\d*" gets all remaining digits
# feet_str = str_extract(height_str, "\\d+\\.?\\d*\\s*(ft)"),
# feet = as.numeric(str_extract(feet_str, "\\d+\\.?\\d*")),
#
# # Get the string of inches which will be based on either the presence of "inches" or "in",
# # e.g., "7 inches" or "7in"
# inches_str = str_extract(height_str, "\\d+\\.?\\d*\\s*(inches|in)"),
# # Extract the decimal from the isolated inches string, like the feet
# inches = as.numeric(str_extract(inches_str, "\\d+\\.?\\d*")),
#
# # Convert using the numerical values
# # Where 'coalesce' will use a 0 if feet/inches is an NA value
# calculated_from_text_feet = (coalesce(feet, 0)) + (coalesce(inches, 0) / 12.0),
#
# # Seeing if the entry has additional text in it like "ft" or "inches"
# contains_text = str_detect(height_str, "ft") | str_detect(height_str, "inches") | str_detect(height_str, "in"),
#
# # Assume the plant_height_ft is the string as a number if the entry doesn't have text.
# plant_height_ft_cleaned = if_else(!contains_text, as.numeric(height_str), calculated_from_text_feet)
#
# ) %>% select(plant_height_ft, plant_height_ft_cleaned)
#
# view(test_height_cleaning)
For the first case of translating height entries from text to numbers there were explicit units like “1 foot 3 inches.” However, others lacked explicit units and were listed as “67.”
In our case, it would be easy to have accidently inputted inches because we were using a ruler for the seedlings. So, I went through and verified that the unitless entries were in fact in feet, and not inches, by accident.
To do this, I viewed the new calculated heights alongside, dbh, densiometer and addditional notes:
# Viewing subset of health_assess_2025 data
view_height <- health_assess_2025 %>% select(`Plant Number (e.g. 4th tree assessed will be 4)`, dbh_cm, plant_height_ft, densio_north, `Any additional notes?`)
# Ordering with highest height at the top
view_height <- view_height[order(view_height$plant_height_ft, decreasing = T), ]
library(knitr)
kable(slice(view_height, 1:20), , caption = "Comparison of heights to verify unitless entries were in feet")
| Plant Number (e.g. 4th tree assessed will be 4) | dbh_cm | plant_height_ft | densio_north | Any additional notes? |
|---|---|---|---|---|
| 24 | 39.5 | 69.00 | NA | Bad visibility of the canopy |
| 25 | 49.5 | 66.28 | NA | NA |
| 16 | 48.5 | 65.00 | NA | fairly vigorous overall; has grapevine; some canopy dieback but stem looks healthy, most cankers are in canopy. in the SW there is an ash right next to it potentially shading it in that direction. |
| 27 | 53.2 | 62.34 | NA | NA |
| SH29 | NA | 62.00 | 66 open | Some black streaks from leaves rubbing on cage, some terminal die back on both of 2 terminal branches that it is recovering from |
| 21 | 20.5 | 62.00 | NA | NA |
| 23 | 37.0 | 61.00 | NA | Vine growing up the tree. Tree is wrapped by them. |
| 18 | 36.5 | 59.71 | NA | NA |
| 26 | 76.5 | 53.00 | NA | nice shade tree, open grown, short open grown |
| 017 | 46.0 | 50.20 | NA | several dead butternut nearby, one right behind it to the west and one to the south |
| 191 | 17.0 | 50.00 | NA | NA |
| 19 | 40.1 | 48.50 | NA | NA |
| 20 | 43.2 | 45.60 | NA | NA |
| SH12 | 30.5 | 45.00 | NA | Sean roughly estimated to be 50 years old. We would have given it a 4 based on canopy but it does not have epicormics. |
| 211 | 19.0 | 45.00 | NA | Dead; Dale estimated that the main trunk died 10 years ago. |
| *Epicormic may be graft-able. | ||||
| 22 | 31.2 | 41.99 | NA | many small healed cankers ~ several dozen, on edge of field by seedlings, 2 dead butternuts to the west |
| 27 | 28.0 | 41.00 | NA | Some sites FGCA visits, tree species are part of the competition. |
| 1 | 34.5 | 40.00 | NA | Too tall to characterize hybrid characters |
| 2 | 32.0 | 40.00 | NA | DEAD tree. Canopy class is based on structure, not live canopy. Callous is also based on whether cankers look like they have ever been calloused. |
| SH3 | 23.0 | 40.00 | NA | We did this assessment based on dead adult tree. Epicormic health characterization will be entered as its own form. |
Notice that the plant with the apparent greatest height (SH29), also has a densiometer measure. We only took densiometer measures for seedlings. This leads me to believe that SH29’s height was actually written inches, and thus was not 62 feet tall. I then confirmed that SH29 was a seedling with the photos.
Thus, I seperately overrided SH29’s height to be re-evaluated as inches:
# Identified mistake with SH29's height.
# Based on photo evidence, the input of 62 feet into the datasheet must have been a mistake and treating the 62 as inches makes sense for that individual.
health_assess_2025 <- health_assess_2025 %>% mutate(plant_height_ft = recode(health_assess_2025$plant_height_ft, `62` = (62.0 / 12)))
# In the future, if I need to recode a lot of values I found this useful tidbit:
# df <- mutate(df, height = case_when(
# height < 2.5 ~ height * 100,
# height < 100 ~ height + 100
# )
# test_adults_have_dbh <- health_assess_2025 %>% select(`Plant Number (e.g. 4th tree assessed will be 4)`, dbh_cm, plant_height_ft, seedling_y_n) %>% mutate(
# has_dbh = (!is.na(dbh_cm)),
# )
#
# view(test_adults_have_dbh)
# test_adults <- health_assess_2025 %>% select(`Plant Number (e.g. 4th tree assessed will be 4)`, densio_north, seedling_y_n) %>% mutate(
# is_seedling_with_densio = ((!is.na(densio_north)) & (seedling_y_n == "Yes"))
# )
#
# view(test_adults)
This was Emma and I’s agreed upon definition as of July 17th, 2025
Removes additional text description
health_assess_2025 <- health_assess_2025 %>% mutate(
purdue_severity_canker = recode(
health_assess_2025$purdue_severity_canker,
"1. Fewer than 3 active cankers that are all smaller than 2-3 inches in length or diameter OR fewer than 3 inactive cankers." = "1",
"2. More than 3 active cankers, OR 2-5 shallow (with no dead tissue) healed over with cracks less than 7 inches long." = "2",
"3. More than 5 active OR inactive cankers cracked through the bark to the tissue below which have healed over, but you still see the level of damage." = "3",
"4. Cankers occur all over the 10-foot area, with deep cracks and both active and inactive cankers." = "4",
"5. Tree almost dead, mostly inactive cankers with deep cracks to dead tissue." = "5"
)
)
# North
test_densio_cleaning <- health_assess_2025 %>%
select(densio_north) %>%
mutate(densio_north_cleaned = parse_number(health_assess_2025$densio_north))
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `densio_north_cleaned =
## parse_number(health_assess_2025$densio_north)`.
## Caused by warning:
## ! 7 parsing failures.
## row col expected actual
## 3 -- a number W - 32. E - 76. S - 10. N - 32. 39% empty or 61% canopy cover.
## 4 -- a number S - 1. E - 56. N - 53. W - 54. 43% open or 57% canopy cover.
## 6 -- a number W - 33. E - 12. N - 68. S - 2. 30% open, 70% canopy cover
## 8 -- a number E - 8. S - 5. W - 10. N - 95 30.7% filled, 69.3% canopy cover
## 9 -- a number E - 7. S - 6. W - 1. N - 5. 19.76% open, 80.24% canopy cover
## ... ... ........ ...............................................................
## See problems(...) for more details.
# Ordering with highest height at the top
test_densio_cleaning <- test_densio_cleaning[order(test_densio_cleaning$densio_north_cleaned, decreasing = T), ]
# # East
# test_densio_cleaning <- health_assess_2025 %>%
# select(densio_east) %>%
# mutate(densio_east_cleaned = parse_number(health_assess_2025$densio_east))
#
# # South
# test_densio_cleaning <- health_assess_2025 %>%
# select(densio_south) %>%
# mutate(densio_south_cleaned = parse_number(health_assess_2025$densio_south))
#
# # West
# test_densio_cleaning <- health_assess_2025 %>%
# select(densio_west) %>%
# mutate(densio_west_cleaned = parse_number(health_assess_2025$densio_west))
library(knitr)
kable(slice(test_densio_cleaning, 1:50), , caption = "Comparison of cleaned densiometer readings to originals")
| densio_north | densio_north_cleaned |
|---|---|
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 96 | 96 |
| 95 | 95 |
| 95 | 95 |
| 94 | 94 |
| 93 | 93 |
| 92 | 92 |
| 91 | 91 |
| 89 | 89 |
| 88 | 88 |
| 87 | 87 |
| 86 | 86 |
| 85 | 85 |
| 83 | 83 |
| 83 | 83 |
| 82 open | 82 |
| 80 open | 80 |
| 80 | 80 |
| 78 open | 78 |
| 77 open | 77 |
| 72 | 72 |
| 66 open | 66 |
| 64 | 64 |
| 62 | 62 |
| 61 | 61 |
| 60 | 60 |
| 60 open | 60 |
| 53 | 53 |
| 50 open | 50 |
| 49 | 49 |
| 49 | 49 |
| 48 | 48 |
| 45 | 45 |
| 40 | 40 |
| 37 | 37 |
| 36 | 36 |
| 32 | 32 |
| 23 | 23 |
#densio
health_assess_2025$densio_east <- parse_number(health_assess_2025$densio_east)
health_assess_2025$densio_north <- parse_number(health_assess_2025$densio_north)
## Warning: 7 parsing failures.
## row col expected actual
## 3 -- a number W - 32. E - 76. S - 10. N - 32. 39% empty or 61% canopy cover.
## 4 -- a number S - 1. E - 56. N - 53. W - 54. 43% open or 57% canopy cover.
## 6 -- a number W - 33. E - 12. N - 68. S - 2. 30% open, 70% canopy cover
## 8 -- a number E - 8. S - 5. W - 10. N - 95 30.7% filled, 69.3% canopy cover
## 9 -- a number E - 7. S - 6. W - 1. N - 5. 19.76% open, 80.24% canopy cover
## ... ... ........ ...............................................................
## See problems(...) for more details.
health_assess_2025$densio_south <- parse_number(health_assess_2025$densio_south)
health_assess_2025$densio_west <- parse_number(health_assess_2025$densio_west)
## Warning: 1 parsing failure.
## row col expected actual
## 22 -- a number Densiometer measures not relevant because seedling was overtaken by honeysuckle. Honeysuckle was cut away before assessing. ng
library(knitr)
kable(slice(health_assess_2025, 1:20), caption = "Cleaned and processed 2025 health assessment data")
| Timestamp | Email Address | Date | Site Number or Initial: JC-W-_______ | Plant Number (e.g. 4th tree assessed will be 4) | GPS location NORTH | GPS Location WEST | Slope (degree) | Aspect (N, NE, E, etc) | plant_height_ft | dbh_cm | percent_live_canopy | base_epicormics | trunk_epicormics | has_canker | has_callous | trunk_canker_area | girdled_canker_circum | base_canker_area | purdue_severity_canker | purdue_severity_canopy | shape_terminal_bud | shape_leaf_scar | shape_lenticels | shape_hairs | densio_north | densio_east | densio_south | densio_west | Any additional notes? | seedling_y_n | Plant Initials (for example, SH or EL) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 6/5/2025 10:07:29 | eleavens@mortonarb.org | 6/5/2025 | SH | 70 | 41.892576 | -88.226243 | 0 | NA | 6.500000 | 1.20 | 100 | 0 | 0 | Yes | No | 10 | 50 | 30 | 3 | 1. No apparent crown dieback. | 0 | 0 | 0 | 0 | NA | NA | NA | NA | No samples were collected. Crown class is NA. Terminal bud was NA. Appears to have walnut mite damage - or something like that - on about one quarter of the leaves. Surrounded by bramble. Within 10 meters of the ditch at the north edge of the site. Also within 10 meters of the power lines. Now needs a cage. | NA | NA |
| 6/5/2025 10:33:48 | eleavens@mortonarb.org | 6/5/2025 | SH | 67 | 41.892507 | -88.226261 | 0 | NA | 6.000000 | 1.20 | 100 | 1 - dead | 0 | Yes | Yes | 10 | 40 | 30 | 1 | 1. No apparent crown dieback. | 0 | 0 | 1 | 0 | NA | NA | NA | NA | It is kind of bulky - thick twigs and big bud scars. Nothing collected. Na for crown class. NA for bark phenotype. Additional sapling/ possible epicormic coming up near the base of the tree. One dead one appears to be epicormic and was entered as such. The one that may be a seedling was not entered as an epicormic because it was not clear if it was a seedling or epicormic. Canopy cover is NA. Surrounded by brambles. Within 10 meters of ditch and also power lines. | NA | NA |
| 6/5/2025 11:21:22 | eleavens@mortonarb.org | 6/5/2025 | SH | 71 | 41.892598 | -88.226597 | 30 | N | 3.375000 | NA | 100 | 0 | 0 | Yes | Yes | 10 | 10 | 10 | 1 | 1. No apparent crown dieback. | 0 | 0 | 1 | 0 | NA | NA | NA | NA | NA for DBH, too small. Very small canker cracks. 2 resprouts from 1 cm base that was once mowed. NA for terminal bud. Blistery lenticels. | NA | NA |
| 6/5/2025 11:47:58 | eleavens@mortonarb.org | 6/5/2025 | SH | 72 | 41.892562 | -88.22709 | 0 | NA | 6.000000 | 1.00 | 100 | 0 | 0 | Yes | Yes | 5 | 40 | 10 | 1 | 1. No apparent crown dieback. | 0 | 0 | 1 | 0 | NA | NA | NA | NA | within 10 meters of ditch and power lines. will need caging. mite damage. vine was wrapping around it which was removed. leaf scars a little bit hulky. NA for bark phenotype, 1.5 for overall canker severity. | NA | NA |
| 6/5/2025 13:28:31 | eleavens@mortonarb.org | 6/5/2025 | SH | 18 | 41.892325 | -88.228259 | 0 | NA | 35.000000 | 37.30 | 90 | 0 | 0 | Yes | Yes | 30 | 40 | 40 | 4 | 2. Some but limited crown dieback. | 0 | 1 | 0 | 0 | NA | NA | NA | NA | We’re not entirely sure that the major trunk damage is canker damage. It could be some kind of mechanical - or lightning - damage. Come back to check on the seeds. Is right next to a recently mowed area. Didn’t collect anything. No terminal bud. NA for canopy cover. | NA | NA |
| 6/5/2025 14:00:52 | eleavens@mortonarb.org | 6/5/2025 | SH | 17 | 41.892486 | -88.228256 | 0 | NA | 1.500000 | NA | 100 | 1 very small but dead | 0 | Yes | No | 5 | 10 | 0 | 1 | 1. No apparent crown dieback. | 0 | 0 | 0 | 0 | NA | NA | NA | NA | 1 totally dead twig that looks like it was probably an epicormic. Mite damage. NA for DBH. NA for crown class. NA for terminal bud, bark phenotype, and canker callous. | NA | NA |
| 6/5/2025 14:34:52 | eleavens@mortonarb.org | 6/5/2025 | SH | 69 | 41.892567 | -88.227675 | 0 | NA | 11.000000 | 4.00 | 100 | 0 | 0 | Yes | Yes | 25 | 30 | 60 | 2 | 1. No apparent crown dieback. | 0 | 0 | 2 | 0 | NA | NA | NA | NA | NA for bark phenotype, terminal bud, and densiometer | NA | NA |
| 6/5/2025 14:54:16 | eleavens@mortonarb.org | 6/5/2025 | SH | 44 | 41.892517 | -88.227645 | 0 | NA | 4.000000 | NA | 100 | 0 | 0 | No | NA | 0 | 0 | 0 | NA | NA | 0 | 0 | 1 | 0 | NA | NA | NA | NA | NA on bark phenotype, terminal bud, crown class, blistery lenticels, mite damage. This is 2 stems coming up where it looks to have been previously mowed. | NA | NA |
| 6/6/2025 9:37:32 | eleavens@mortonarb.org | 6/6/2025 | SH | 43 | 41.892816 | -88.227357 | 0 | NA | 2.500000 | NA | 100 | 0 | 0 | Yes | No | 20 | 20 | 0 | 1 | 1. No apparent crown dieback. | 0 | 0 | 0 | 0 | NA | NA | NA | NA | Buckthorn, honeysuckle, sumac, bur oak, and unknown. Has been mowed in the past. NA for DBH, bark phenotype, or crown class. No terminal bud. NA for canker callous. | NA | NA |
| 6/6/2025 10:28:15 | eleavens@mortonarb.org | 6/6/2025 | SH | 48 | 41.89219 | -88.227309 | 0 | NA | 16.000000 | 6.00 | 100 | 0 | 0 | Yes | Yes | 30 | 50 | 70 | 3 | 1. No apparent crown dieback. | 0 | 1 | 0 | 0 | NA | NA | NA | NA | Major damage to one side of the trunk, unsure if from canker, deer rub, or other. Nearby tree(not butternut) has similar damage. Had smaller but significant second trunk that is dead now. NA to terminal bud and densiometer. | NA | NA |
| 6/6/2025 10:48:21 | eleavens@mortonarb.org | 6/6/2025 | SH | 45 | 41.892277 | -88.22726 | 0 | NA | 6.000000 | 1.50 | 100 | 0 | 0 | Yes | Yes | 20 | 50 | 100 | 3 | 1. No apparent crown dieback. | 0 | 0 | 0 | 0 | NA | NA | NA | NA | There is 1 dead possible epicormic coming from the base. Cut stump about an inch in diameter, NA for terminal bud and densiometer. | NA | NA |
| 6/6/2025 11:02:25 | eleavens@mortonarb.org | 6/6/2025 | SH46 | 46 | 41.892266 | -88.22705 | 0 | NA | 9.500000 | 2.50 | 100 | 0 | 0 | Yes | Yes | 20 | 40 | 0 | 2 | 1. No apparent crown dieback. | 0 | 0 | 0 | 0 | NA | NA | NA | NA | NA for bark phenotype and densiometer. | NA | NA |
| 6/6/2025 11:24:42 | eleavens@mortonarb.org | 6/6/2025 | SH | 47 | 41.892363 | -88.22715 | 0 | NA | 4.500000 | NA | 100 | 0 | 0 | Yes | No | 5 | 5 | 0 | 1 | 1. No apparent crown dieback. | 0 | 0 | 1 | 0 | NA | NA | NA | NA | Dead branch coming up from the trunk about 18 inches off the ground. Kind of a hulky tree. NA for bark phenotype, crown class, and canker calloused. | NA | NA |
| 6/6/2025 11:41:35 | eleavens@mortonarb.org | 6/6/2025 | SH | 74 | 41.892328 | -88.227094 | 0 | NA | 6.500000 | 1.50 | 100 | 0 | 0 | Yes | Yes | 15 | 40 | 30 | 2 | 1. No apparent crown dieback. | 0 | 0 | 1 | 0 | NA | NA | NA | NA | 1 dead branch coming up from the base. Lenticels are blistery and a little bigger than usual. NA for bark phenotype, terminal bud, and densiometer. | NA | NA |
| 6/12/2025 9:27:26 | eleavens@mortonarb.org | 6/12/2025 | SH | 37 | 41.892676 | -88.224128 | 0 | 0 | 7.500000 | 3.00 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | No | NA |
| 6/12/2025 9:30:48 | eleavens@mortonarb.org | 6/12/2025 | WCP | SH37 | Na | Na | NA | NA | 7.500000 | 3.00 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | No | NA |
| 6/12/2025 9:46:40 | eleavens@mortonarb.org | 6/12/2025 | WCP | SH37 | Na | Na | 0 | 0 | 7.500000 | 3.00 | 90 | 0 | 0 | Yes | No | 5 | 20 | 30 | 1.5 | 2. Some but limited crown dieback. | NA | 0 | 0 | 0 | NA | NA | NA | NA | Surrounded by some thorny species | No | NA |
| 6/12/2025 10:00:13 | eleavens@mortonarb.org | 6/12/2025 | WCP | SH75 | 41.892603 | -88.224133 | 0 | NA | 2.750000 | NA | 100 | 0 | 0 | Yes | Maybe | 5 | 50 | 40 | 2 | 1. No apparent crown dieback. | NA | 0 | 0 | 0 | 64 | 48 | 16 | 63 | NA | Yes | NA |
| 6/12/2025 10:20:26 | eleavens@mortonarb.org | 6/12/2025 | WCP | SH28 | 41.892572 | -88.224932 | 0 | NA | 7.000000 | 2.75 | 40 | 0 | 0 | Yes | No | 25 | 65 | 80 | 4 | 2.5 | NA | 0 | 1 | 0 | NA | NA | NA | NA | Also shrubs nearby as competition | No | NA |
| 6/12/2025 10:34:42 | eleavens@mortonarb.org | 6/12/2025 | WCP | SH34 | 41.892565 | -88.225166 | 0 | NA | 2.708333 | NA | 100 | 0 | 0 | Yes | NA | 15 | 40 | 0 | 1 | 1. No apparent crown dieback. | NA | 0 | 0 | 0 | 5 | 6 | 12 | 10 | Some black streaks on the petioles which might be canker | Yes | NA |