Geographical EV

{r setup, include=FALSE} library(shiny) library(dplyr) library(ggplot2) library(sf) library(leaflet) library(tigris) library(tidyr) library(lubridate) library(scales) library(viridis) library(readr) library(plotly) library(tidyverse) knitr::opts_chunk$set(echo = TRUE)

{r load-ev-data, echo = FALSE} #Read CSV File ev_data <- read.csv("Electric_Vehicle_Population_Size_History_by_County.csv", stringsAsFactors = FALSE) %>% mutate(Date = mdy(Date))

{r summarize-county, include=FALSE} #Summarize Latest-Month EVs by County county_ev <- ev_data %>% filter(State == "WA", Date == max(Date, na.rm=TRUE)) %>% group_by(County) %>% summarise(ev_count = sum(`Electric.Vehicle..EV..Total`, na.rm=TRUE), total_vehicles = sum(Total.Vehicles, na.rm=TRUE), .groups = "drop") %>% mutate(ev_share = ev_count / total_vehicles)

```{r loadandmerge, include=FALSE} # Load and merge WA county polygons

options(tigris_use_cache = TRUE) wa_sf <- st_as_sf(counties(state = “WA”, cb = TRUE)) wa_sf <- wa_sf %>% st_transform(crs = 4326) wa_ev <- wa_sf %>% left_join(county_ev, by = c(“NAME” = “County”)) %>% replace_na(list(ev_count = 0, ev_share = 0))


```{r prep-top-bottom, include=FALSE}
# top 5 by absolute EV count
top5_count <- county_ev %>% 
  slice_max(ev_count, n = 5)

# bottom 5 by absolute EV count—but only among those > 0
bot5_count <- county_ev %>%
  filter(ev_count > 0) %>%      # drop the zero‐EV rows
  slice_min(ev_count, n = 5)

Top & Bottom 5 by EV Count

{r bar-ev-count, echo=FALSE} # combine top5 & bottom5 into one df df_count <- bind_rows( top5_count %>% mutate(Group = "Top 5"), bot5_count %>% mutate(Group = "Bottom 5") ) ggplot(df_count, aes( x = reorder(County, ev_count), y = ev_count, fill = Group )) + geom_col() + coord_flip() + scale_fill_manual( values = c("Top 5" = "turquoise", "Bottom 5" = "goldenrod") ) + labs( title = "Top & Bottom 5 Counties by EV Count", x = NULL, y = "EV Count", fill = NULL ) + theme_minimal()

Washington State EV Map

```{r map-ev-share, echo=FALSE} # color palette for EV share pal <- colorNumeric( palette = “YlGnBu”, domain = wa_ev\(ev_share, na.color = "transparent" ) leaflet(wa_ev, options = leafletOptions(zoomControl = TRUE)) %>% addProviderTiles(providers\)CartoDB.Positron) %>% addPolygons( fillColor = ~pal(ev_share), color = “#444444”, weight = 1, fillOpacity = 0.8, label = ~paste0( NAME, “:”, scales::percent(ev_share, accuracy = 0.1), ” (“, ev_count,” EVs)” ), labelOptions = labelOptions( direction = “auto”, style = list(“font-weight” = “normal”, padding = “3px 8px”) ) ) %>% addLegend( pal = pal, values = ~ev_share, position = “bottomright”, title = “EVs / Total Vehicles”, labFormat = labelFormat( transform = function(x) x * 100, suffix = “%” ) )

Interactive Electric Vehicle Explorer (Chart 4)

``{r app, echo=FALSE} ui <- fluidPage( fluidRow( column(4, textInput("make_filter", "Filter by Make (optional):", ""), sliderInput("year_range", "Select Model Year Range:", min = min(ev_data$Model Year, na.rm = TRUE), max = max(ev_data$Model Year, na.rm = TRUE), value = c(min(ev_data$Model Year, na.rm = TRUE), max(ev_data$Model Year`, na.rm = TRUE)), step = 1, sep = “” ) ), column(8, dataTableOutput(“ev_table”), plotlyOutput(“ev_plot”) ) ) )

server <- function(input, output) { filtered_data <- reactive({ ev_data %>% filter( Model Year >= input\(year_range[1], `Model Year` <= input\)year_range[2], grepl(input$make_filter, Make, ignore.case = TRUE) ) })

output$ev_table <- renderDataTable({ filtered_data() %>% select(Model Year, Make, Vehicle Model Description, Alternative Fuel Type) })

output$ev_plot <- renderPlotly({ plot_data <- filtered_data() %>% count(Alternative Fuel Type) %>% arrange(desc(n))

p <- ggplot(plot_data, aes(x = reorder(`Alternative Fuel Type`, n), y = n, fill = `Alternative Fuel Type`)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  labs(
    title = "Count of Vehicles by Alternative Fuel Type",
    x = "Alternative Fuel Type",
    y = "Number of Vehicles"
  ) +
  theme_minimal() +
  theme(legend.position = "none")

ggplotly(p)

}) }


```{r chart2, include=FALSE}
# Load and prepare data
ev_data <- tryCatch(
  {
    read_csv("WA_Tax_Exemptions_-_Potential_Eligibility_by_Make_Model_Excluding_Vehicle_Price_Criteria.csv")
  },
  error = function(e) {
    stop("Error loading CSV file. Please ensure the file is in the working directory.")
  }
)

# Clean and process data
ev_data$Year <- as.numeric(ev_data$`Model Year`)

yearly_ev_data <- ev_data %>%
  filter(!is.na(Year)) %>%
  group_by(Year) %>%
  summarise(Total_EV_Count = n()) %>%
  arrange(Year)

min_year <- min(yearly_ev_data$Year)
max_year <- max(yearly_ev_data$Year)

# UI
ui <- fluidPage(
  titlePanel("EV Adoption Trends in Washington State"),

  sidebarLayout(
    sidebarPanel(
      sliderInput("year_range", "Select Year Range:",
                  min = min_year, max = max_year,
                  value = c(min_year, max_year), step = 1, animate = TRUE)
    ),

    mainPanel(
      plotlyOutput("ev_line_plot")
    )
  )
)

# Server
server <- function(input, output) {

  filtered_data <- reactive({
    yearly_ev_data %>%
      filter(Year >= input$year_range[1], Year <= input$year_range[2])
  })

  output$ev_line_plot <- renderPlotly({
    data <- filtered_data()

    plot_ly(data, x = ~Year, y = ~Total_EV_Count, type = 'scatter', mode = 'lines+markers',
            line = list(color = 'blue')) %>%
      layout(title = "Electric Vehicle Adoption Over Years",
             xaxis = list(title = "Year"),
             yaxis = list(title = "Total EV Count"))
  })
}

{r} ev_data <- read_csv("Electric_Vehicle_Population_Data.csv") glimpse(ev_data)

```{r Top 10 Most Common EV Models} top_models <- ev_data %>% mutate(Make_Model = paste(Make, Model)) %>% count(Make_Model, sort = TRUE) %>% slice_max(n, n = 10)

ggplot(top_models, aes(x = reorder(Make_Model, n), y = n)) + geom_bar(stat = “identity”, fill = “pink”) + coord_flip() + labs(title = “Top 10 Most Common EV Models in WA”, x = “Make & Model”, y = “Number of Vehicles”) + theme_minimal()


```{r Distribution of EV Types}
ev_type_counts <- ev_data %>%
  count(`Electric Vehicle Type`)

ggplot(ev_type_counts, aes(x = `Electric Vehicle Type`, y = n, fill = `Electric Vehicle Type`)) +
  geom_bar(stat = "identity") +
  labs(title = "EV Type Distribution: BEV vs PHEV",
       x = "EV Type",
       y = "Number of Vehicles") +
  scale_fill_manual(values = c("navy", "lavender")) +
  theme_minimal()

``{r Distribution by Model Year} year_dist <- ev_data %>% count(Model Year) %>% filter(!is.na(Model Year`))

ggplot(year_dist, aes(x = Model Year, y = n)) + geom_bar(stat = “identity”, fill = “brown”) + labs(title = “Distribution of EVs by Model Year”, x = “Model Year”, y = “Number of Vehicles”) + theme_minimal() ``` shinyApp(ui, server)