Comparing Electric Driving Ranges of Battery Electric and Plug-in Hybrid Electric Vehicles

Introduction

I am finding how does the electric driving range of battery electric vehicles (BEVs) compare to plug-in hybrid electric vehicles (PHEVs). BEVs can only run on electricity, however PHEVs have a small battery and a gas engine, that gives hint about BEVs having a longer electric range

I used my data-set from Electric Vehicle Population Data from the Washington State Department of Licensing (data.wa.gov). It has 299705 observations and 16 variables where I only used “electric_vehicle_type” that the vehicle type, and “electric_range” that shows miles the vehicle can travel on electric power.

Additionally, there was several 0 values which was not recorded, so I removed those to run the code smoothly.

Data Analysis

My first step, I loaded necessary libraries, read the data, and explored it. I preferred to change the upper-cased variable to lower-case, and replacing the space to “_”. I used different functions like “select()”, to keep only required columns, and “filter()”, to remove the 0 value or not recorded. Using “group_by()” and “summarise()”, I calculated the mean value for each variable (BEV and PHEV). Lastly, I made a bar graph which I find easy to compare the two groups.

Loading libraries and data-set

library(tidyverse)
## Warning: package 'tidyr' was built under R version 4.6.1
## Warning: package 'readr' was built under R version 4.6.1
## Warning: package 'dplyr' was built under R version 4.6.1
## Warning: package 'lubridate' was built under R version 4.6.1
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(dplyr)
library(readr)
mydataset <- read_csv("export.csv")
## Rows: 299705 Columns: 16
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (10): VIN (1-10), County, City, State, Make, Model, Electric Vehicle Typ...
## dbl  (6): Postal Code, Model Year, Electric Range, Legislative District, DOL...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
summary(mydataset)
##      VIN (1-10)           County              City              State       
##  Length   :299705   Length   :299705   Length   :299705   Length   :299705  
##  N.unique : 18376   N.unique :   255   N.unique :   941   N.unique :    50  
##  N.blank  :     0   N.blank  :     0   N.blank  :     0   N.blank  :     0  
##  Min.nchar:    10   Min.nchar:     3   Min.nchar:     3   Min.nchar:     2  
##  Max.nchar:    10   Max.nchar:    20   Max.nchar:    24   Max.nchar:     2  
##                     NAs      :    11   NAs      :    11                     
##                                                                             
##   Postal Code      Model Year          Make              Model       
##  Min.   : 1030   Min.   :1999   Length   :299705   Length   :299705  
##  1st Qu.:98052   1st Qu.:2021   N.unique :    51   N.unique :   202  
##  Median :98134   Median :2023   N.blank  :     0   N.blank  :     0  
##  Mean   :98176   Mean   :2022   Min.nchar:     3   Min.nchar:     2  
##  3rd Qu.:98391   3rd Qu.:2024   Max.nchar:    22   Max.nchar:    24  
##  Max.   :99801   Max.   :2027                                        
##  NAs    :11                                                          
##  Electric Vehicle Type Clean Alternative Fuel Vehicle (CAFV) Eligibility
##  Length   :299705      Length   :299705                                 
##  N.unique :     2      N.unique :     3                                 
##  N.blank  :     0      N.blank  :     0                                 
##  Min.nchar:    30      Min.nchar:    37                                 
##  Max.nchar:    38      Max.nchar:    60                                 
##                                                                         
##                                                                         
##  Electric Range   Legislative District DOL Vehicle ID       Vehicle Location 
##  Min.   :  0.00   Min.   : 1.00        Min.   :     4469   Length   :299705  
##  1st Qu.:  0.00   1st Qu.:17.00        1st Qu.:228301678   N.unique :  1199  
##  Median :  0.00   Median :32.00        Median :267927096   N.blank  :     0  
##  Mean   : 36.66   Mean   :28.75        Mean   :250992430   Min.nchar:    23  
##  3rd Qu.: 32.00   3rd Qu.:42.00        3rd Qu.:284535905   Max.nchar:    27  
##  Max.   :337.00   Max.   :49.00        Max.   :479114996   NAs      :    20  
##  NAs    :26       NAs    :790                                                
##   Electric Utility    2020 GEOID       
##  Length   :299705   Min.   :1.001e+09  
##  N.unique :    77   1st Qu.:5.303e+10  
##  N.blank  :     0   Median :5.303e+10  
##  Min.nchar:    10   Mean   :5.297e+10  
##  Max.nchar:   112   3rd Qu.:5.305e+10  
##  NAs      :    11   Max.   :6.601e+10  
##                     NAs    :11

Changing uppercase to lowercase and space to “_”

names(mydataset) <- tolower(names(mydataset))
names(mydataset) <- gsub(" ","_", names(mydataset))

Finding average data

range <- mydataset |>
  select(electric_vehicle_type, electric_range) |>
   filter(electric_range > 0) |>
  group_by(electric_vehicle_type) |>
  summarise(number_of_vehicle = n(),
            average_range = mean(electric_range, na.rm = TRUE)
            )
range
## # A tibble: 2 × 3
##   electric_vehicle_type                  number_of_vehicle average_range
##   <chr>                                              <int>         <dbl>
## 1 Battery Electric Vehicle (BEV)                     45492         201. 
## 2 Plug-in Hybrid Electric Vehicle (PHEV)             57952          32.2
ggplot(range, aes(x = electric_vehicle_type, y = average_range, fill =  electric_vehicle_type)) +
         geom_col(show.legend = TRUE) +
  labs(title = "Electric Range by Vehicle Type",
       x = "Type of Vehicle",
       y = "Electric Ranges (miles)") +
# Tilting the text to make it clear
       theme(axis.text.x = element_text(angle = 10, hjust = .5))

Conclusion

This analysis gives the result that Battery Electric Vehicle have a longer electric driving range than Plug-in Hybrid Electric Vehicles. BEVs has averaged about 200.5 miles on electric power, where PHEVs averaged only about 32.3 miles. BEVs is better for long distance on electricity.

Cons is that most of the BEVs had a range of 0 and were removed. In future research, I could find the model and its year, to find the missing information.