Home

Column

Outbreak Tracker 📍

Column

Placeholder

placeholder text

Placeholder

placeholder text


Predict

Row

Placeholder 1

Placeholder 2

Placeholder 3

Row

Placeholder 4

Placeholder 5


Data

Column

Data Dictionary

Column

Data Explorer


Project Checklist

Column

REQUIREMENTS


⚠️ [10] Include 6-10 display items.

  1. ✅ Map/Tracker
  2. ✅ [05] At least 1 display item should showcase the data.
  3. 🚧 [05] At least 1 display item should showcase model results.
  4. 🚧 [05] At least 1 display item should showcase the predictors used in each model.
  5. 🚧 idea
  6. 🚧 idea

⚠️ [20] Apply at least 2 different types of statistic modeling approaches.

  1. 🚧 model
  2. 🚧 model

⚠️ [05] Model specification should be done in the tidymodels framework.

  • 🚧

⚠️ [05] Feature engineer the data as applicable using step_x functions.

  • 🚧

⚠️ [05] Use a recipe.

  • 🚧

⚠️ [05] Use a tidymodels workflow.

  • 🚧

⚠️ [10] Provide an evaluation of your models.

  • 🚧

Nice to Haves


⚠️ Data Tab

  • 🚧 look into making the data dictionary slide in and out so that its not always present and the user can click on it when they want it and hide it when they dont.

Column

DONE

✅[05] Publish the app to Rpubs and send Dr. York the link as a direct message in Slack.

✅[10] Aesthetics (i.e., start with a good theme).

✅[05] Embed the code within the app.

✅[05] The app should be a designed and rendered as a flexdashboard.

---
title: "Jeffrey Pine Beetle Outbreak"
output: 
  flexdashboard::flex_dashboard:
    favicon: "img/pine_beetle.png"
    logo: "img/pine_beetle.png"
    social: "menu"
    source_code: "embed"
    theme:
      version: 4
      bg: "#0A1628"
      fg: "#E1F1FF" 
      primary: "#364055"
      base_font:
        google: "EB Garamond"
      code_font:
        google: "JetBrains Mono"
---

```{r setup, include=FALSE}

# =========================================================
# LOAD LIBRARIES
# =========================================================
library(conflicted)
library(DT)
library(flexdashboard)
library(labelled)
library(plotly)
library(tidymodels)
library(tidyverse)

# =========================================================
# COLOR PALETTE
# =========================================================
nav_color <- "#364055"
font_color <- "#E1F1FF" 
accent_color <- "#D9A21B"
background_color <- "#0A1628"

# =========================================================
# LOAD DATA
# =========================================================
pine_tbl <- readr::read_csv(
  file      = "data/Data_1993.csv",
  col_types = "ifddiidfdddddddddddddfffff"
) |>
  labelled::set_variable_labels(
    # =====================================================
    # Tree Characteristics 
    # =====================================================
    TreeNum = "Unique tree identifier",
    Response = "1 = infested, 0 = not infested",
    Easting = "Horizontal (east-west) position",
    Northing = "Vertical (north-south) position",
    TreeDiam = "Tree diameter/size",
    Infest_Serv1 = "Infestation severity",
    Infest_Serv2 = "Infestation severity",
    DeadDist = "Minimum linear distance to nearest brood",
    
    # =====================================================
    # Neighborhood Characteristics 
    # =====================================================
    SDI_20th = "Stand Density Index @ 1/20th-acre",
    BA_20th = "Basal Area at 1/20th-acre",
    `Neigh_SDI_1/4th` = "Stand Density Index at .25acre",
    `Neigh_1/4th` = "Basal area within .25acre",
    `Neigh_1/2th` = "Basal area within .50 acre",
    Neigh_1 = "Basal area within 1 acre",
    Neigh_1.5 = "Basal area within 1.5 acres",
    
    # =====================================================
    # Basal Area (Infested Trees)
    # =====================================================
    BA_Inf_20th = "Infested BA within 1/20th acre",
    `BA_Infest_1/4th` = "Infested BA within 1/4 acre",
    `BA_Infest_1/2th` = "Infested BA within 1/2 acre",
    BA_Infest_1 = "Infested BA within 1 acre",
    BA_Infest_1.5 = "Infested BA within 1.5 acres",
    
    # =====================================================
    # Indicators (Boolean variables)
    # =====================================================
    Ind_DeadDist = "Nearest brood tree within 50m",
    IND_BA_Infest_20th = "Infested tree in neighborhood",
    `IND_BA_Infest_1/4th` = "Infested tree within .25acre",
    `IND_BA_Infest_1/2th` = "Infested tree within .50acre",
    IND_BA_Infest_1 = "Infested tree within 1acre",
    IND_BA_Infest_1.5 = "Infested tree within 1.5acres"
)
```

# Home {data-orientation="columns"}

## Column

### Outbreak Tracker 📍

```{r outbreak_tracker}

# ========================================================
# FILTER & TIDY: Prepare the dataset for plotting.
# - Keep only columns needed for the spatial scatter.
# - Round nearest-brood distance to one decimal place.
# ========================================================
outbreak_map_df <- pine_tbl |>
  select(
    TreeNum,  # tree id
    TreeDiam, # tree diameter 
    DeadDist, # distance to nearest brood tree 
    Easting,  # UTM easting coordinate
    Northing, # UTM northing coordinate 
    Response  # infested (1) vs. not infested (0)
  ) |>
  mutate(
    DeadDist = round(DeadDist, 1) # for tooltip display
  )

# ========================================================
# HELPER FUNCTION: Build hover-text for tooltip popup.
# - Tree number
# - Tree diameter
# - Distance to nearest brood tree
# - UTM coordinates
# ========================================================
build_tooltip_text <- function(.df) {
  glue::glue_data(.df,
    "<b>Tree #{TreeNum}</b><br>",
    "Diameter: {TreeDiam}cm<br>",
    "Nearest Brood: {DeadDist}m<br>",
    "Easting: {Easting}<br>",
    "Northing: {Northing}<br>"
  )
}

# ========================================================
# PLOT: Spatial Scatter
# - color splits data by Response and handles the legend
# ========================================================
outbreak_map <- outbreak_map_df |>
  plot_ly(
    x         = ~Easting,
    y         = ~Northing,
    type      = "scatter",
    mode      = "markers",
    color     = ~Response,
    colors    = c("#006600", "#A52A2A"),
    hoverinfo = "text",
    text      = ~build_tooltip_text(outbreak_map_df),
    showlegend  = FALSE,
    marker    = list(
      size        = ~TreeDiam,
      sizemode    = "diameter",
      sizemin     = 1,
      sizeref     = 2.5,
      showlegend  = FALSE
    )
  ) |>
  plotly::layout(
    xaxis = list(
      title      = "UTM Easting",
      color      = font_color,
      tickformat = "d"
    ),
    yaxis = list(
      title      = "UTM Northing",
      color      = font_color,
      tickformat = "d"
    ),
    hovermode     = "closest",
    dragmode      = "pan",
    showlegend  = FALSE,
    paper_bgcolor = background_color,
    plot_bgcolor  = background_color
  )

outbreak_map
```

## Column

### Placeholder

placeholder text

```{r }
# placeholder
```

### Placeholder

placeholder text

```{r }
# placeholder 
```

------------------------------------------------------------------------

# Predict

## Row

### Placeholder 1

```{r}
```

### Placeholder 2

```{r}

```

### Placeholder 3

```{r}

```

## Row

### Placeholder 4

```{r}

```

### Placeholder 5

```{r}

```

------------------------------------------------------------------------

# Data {data-orientation="columns"}

## Column {data-width="200"}

### Data Dictionary

```{r data_dictionary}
# create data dictionary 
dict_tbl <- pine_tbl |> 
  labelled::generate_dictionary() |> 
  dplyr::select(variable, label) |> 
  dplyr::arrange(variable)      # sort alphabetically by variable name

# render data dictionary
DT::datatable(
  data = dict_tbl,
  colnames = NULL,              # hide column names
  rownames = FALSE,             # hide row names
  options = list(
    dom = 'ft',                 # only show filter and table 
    pageLength = nrow(dict_tbl) # table length determined by number of rows
  )
)
```

## Column

### Data Explorer

```{r data_explorer}
# round all double except coordinates
dbl_cols <- pine_tbl |> 
  select(where(is.double)) |> 
  select(-Easting, -Northing) |> 
  names()

# render data explorer
DT::datatable(
  data = pine_tbl,
  rownames = FALSE,
  options = list(
    dom = 'tlp',
    pageLength = 20
  )
) |> 
  formatRound(columns = dbl_cols, digits = 1)
```

------------------------------------------------------------------------

# Project Checklist {data-orientation="columns"}

## Column

### REQUIREMENTS

------------------------------------------------------------------------

⚠️ [10] Include 6-10 display items.

1.  ✅ Map/Tracker
2.  ✅ [05] At least 1 display item should showcase the data.
3.  🚧 [05] At least 1 display item should showcase model results.
4.  🚧 [05] At least 1 display item should showcase the predictors used in each model.
5.  🚧 idea
6.  🚧 idea

------------------------------------------------------------------------

⚠️ [20] Apply at least 2 different types of statistic modeling approaches.

1.  🚧 model
2.  🚧 model

------------------------------------------------------------------------

⚠️ [05] Model specification should be done in the tidymodels framework.

-   🚧

⚠️ [05] Feature engineer the data as applicable using `step_x` functions.

-   🚧

⚠️ [05] Use a recipe.

-   🚧

⚠️ [05] Use a tidymodels workflow.

-   🚧

⚠️ [10] Provide an evaluation of your models.

-   🚧

------------------------------------------------------------------------

Nice to Haves

------------------------------------------------------------------------

⚠️ Data Tab

-   🚧 look into making the data dictionary slide in and out so that its not always present and the user can click on it when they want it and hide it when they dont.

## Column

### DONE

✅[05] Publish the app to Rpubs and send Dr. York the link as a direct message in Slack.

✅[10] Aesthetics (i.e., start with a good theme).

✅[05] Embed the code within the app.

✅[05] The app should be a designed and rendered as a flexdashboard.