Do newer Teslas Have longer Ranges?

Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see https://quarto.org.

Running Code

When you click the Render button a document will be generated that includes both content and the output of embedded code. You can embed code like this:

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.0     ✔ 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.1     
── 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(dplyr)
list <- read_csv("EVRanges.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.
#list is the name of the dataset

For this project, I’m primarily finding out if newer Teslas usually have higher ranges. And if there is any correlation or reason behind the range being high ow low . Newer cars on paper should outperform older cars, so we’ll try to see if that is the case. The main variables here are Model, Model Year, and Range

I’m gonna start of by loading the dataset then declaring my libraries. Then I’ll filter my dataset to strictly Tesla cars, and count the models that are available in the dataset.

filteredList <- list |>
  filter(
    `Electric Range` > 0,
    !is.na(`Model Year`),
    !is.na(Model)
  )
tesla <- filteredList |>
  filter(
    Make =="TESLA",
  )

tesla |>
  count(`Model`)
# A tibble: 5 × 2
  Model        n
  <chr>    <int>
1 MODEL 3  13306
2 MODEL S   5483
3 MODEL X   3183
4 MODEL Y   2226
5 ROADSTER    40

Below are the year of the models

tesla |>
  count(`Model Year`)
# A tibble: 12 × 2
   `Model Year`     n
          <dbl> <int>
 1         2008    16
 2         2010    17
 3         2011     7
 4         2012   112
 5         2013   607
 6         2014   536
 7         2015   910
 8         2016  1470
 9         2017  1572
10         2018  7683
11         2019  4473
12         2020  6835

Now that we have our Tesla models, here is a bar chart to show which model is popular. We have a table, and we’re going to visualize what we got.

ggplot(tesla, aes(x = Model, fill = Model)) +
  geom_bar() +
  geom_text(
    stat = "count",
    aes(label = after_stat(count)),
    vjust = -0.5
  ) + 
  scale_fill_manual(
    values = c(
      "MODEL 3" = "green",  
      "MODEL S" = "yellow",     
      "MODEL X" = "red",    
      "MODEL Y" = "blue",   
      "ROADSTER" ="purple"
    )
  )

This line lists the all the cars,based on their model and year

teslaSummary <- tesla |>
  group_by(Model, `Model Year`) |>
  summarise(
    vehicles = n(),
    medianRange = median(`Electric Range`),
    meanRange = mean(`Electric Range`),
    .groups = "drop"
  ) |>
  arrange(desc(medianRange))

print(teslaSummary, n = Inf)
# A tibble: 22 × 5
   Model    `Model Year` vehicles medianRange meanRange
   <chr>           <dbl>    <int>       <dbl>     <dbl>
 1 MODEL S          2020      398         330      331.
 2 MODEL 3          2020     3513         308      299.
 3 MODEL X          2020      698         293      292.
 4 MODEL Y          2020     2226         291      291 
 5 MODEL X          2019      410         289      289 
 6 MODEL S          2019      270         270      270 
 7 MODEL S          2012      112         265      265 
 8 MODEL S          2018      895         249      249 
 9 ROADSTER         2010       17         245      245 
10 ROADSTER         2011        7         245      245 
11 MODEL X          2018      861         238      238 
12 MODEL 3          2017       73         220      220 
13 MODEL 3          2019     3793         220      220 
14 ROADSTER         2008       16         220      220 
15 MODEL 3          2018     5927         215      215 
16 MODEL S          2016      881         210      210 
17 MODEL S          2017      874         210      210 
18 MODEL S          2013      607         208      208 
19 MODEL S          2014      536         208      208 
20 MODEL S          2015      910         208      208 
21 MODEL X          2016      589         200      200 
22 MODEL X          2017      625         200      200 

The code below shows the models of cars placed based on their make year and ranges. we can observe roadsters are in 200 to 250 range, 2012 - 2015 model S hover on the low 200 end and younger models tend to be on the higher end of range. Model 3 and Model X are s also similar to how model S performs.

ggplot(
  tesla,
  aes(
    x = `Model Year`,
    y = `Electric Range`,
    color = Model
  )
) + geom_point(alpha = 0.2) + 
  scale_color_manual(
    values = c(
      "MODEL 3" = "green",  
      "MODEL S" = "brown",      
      "MODEL X" = "red",    
      "MODEL Y" = "blue",   
      "ROADSTER" ="purple"
    )
  )

Here is where we find try and create a model to predict the range of Teslas based on the year they were built. Again, the key reason we’re picking year is because battery life tends to slow down over time, tanking the vehicles battery capacity. Through our regression model, we have found that the range improves by 14.508 miles. The intercept provides the value -29037, which is the range predicted for the year 0. This obviously doesn’t make sense, its just a baseline to see how the model works. To actually find the predicted range of the year model of the car we would use this formula.

Equation

Range = -29037.73 + 14.508(model year)

the p value is less than 2x10^-16, which shows strong evidence of association. What that means in simpler terms, is that though it appears on paper that for every year model there is a better range, it isn’t the actual reason that the age of the car plays a role in longer ranges. These cars could be reflecting the range they had in the dataset, upon registration or production.

Adjusted R^2 is 0.4312,showing the model accounts for 43.12% of the difference in electric range

The residual standard error is about 29.76 miles describing errors around the regression line.

teslaRegression <- lm(
  `Electric Range` ~ `Model Year`,
  data = tesla
)

summary(teslaRegression)

Call:
lm(formula = `Electric Range` ~ `Model Year`, data = tesla)

Residuals:
    Min      1Q  Median      3Q     Max 
-33.248 -23.741  -1.756  23.244 126.336 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -29037.730    215.978  -134.4   <2e-16 ***
`Model Year`     14.508      0.107   135.6   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 29.76 on 24236 degrees of freedom
Multiple R-squared:  0.4313,    Adjusted R-squared:  0.4312 
F-statistic: 1.838e+04 on 1 and 24236 DF,  p-value: < 2.2e-16
a <- coef(teslaRegression)

cat(
  "Predicted range (miles) =",
  round(a[1], 2),
  "+ (", round(a[2],2), " x model year)"
)
Predicted range (miles) = -29037.73 + ( 14.51  x model year)
ggplot(tesla, aes(x = `Model Year`, y = `Electric Range`)) + 
  geom_point(alpha = 0.1, color = "blue") +
  geom_smooth(method = "lm", se = TRUE, color = "orange")
`geom_smooth()` using formula = 'y ~ x'

par(mfrow = c(1,1))
par(mar = c(4,4,2,1))
plot(teslaRegression, which = 1)

plot(teslaRegression, which =2)

plot(teslaRegression, which =3)

plot(teslaRegression, which =5)

Residual vs Fitted the line goes downward the sharply upwards. this suggests the relationship between the make year of the car and the ranges relationship aren’t as tight.

Q-Q Residual shows a flat beginning, and a diagonal that has a gap towards the higher end. This suggests residuals are not normally distributed

Scale Location The downward slope and the slight rise shows residual variance isn’t constant.

Residual v Leverage most points are scattered around the left, which means they have low leverage, and the higher values on the right have high leverage.

To begin with this dataset, I loaded tidyverse and dplyr libraries, and loaded my dataset. I then cleaned it to work with only Tesla cars. I then sorted the variables important for my work, year model, model and range. I made graphs showing the amount of cars that we’re working with, what year they were manufactured, and tried to show before the regression model if younger cars had more range than older ones.

We then moved to the regression model, where we have found that the range improves by 14.508 miles for every newer model every year. The intercept provides the value -29037, which is the range predicted for the year 0, which is our baseline to predict the ranges of the Teslas. and that equation is:Range = -29037.73 + 14.508(model year). The p-value (2x10^-16) shows there is a strong case of association, which means the model year of the car isn’t the reason the ranges are higher, and that there could be a confounding variable or other factor that our model appears this way.

Conclusion

In conclusion, though we have found out that that newer Tesla cars usually have more electrical range than older models, it isn’t because they are newer, rather it was just an association. The ranges in the vehicle vary from car to car and I believe were not at maximum capacity, which would make it hard to judge, just by looking at a data-set that just lists registered vehicles in a certain area.

Limitations and Future Notes

The limitation to this study mainly stemmed from the type of data set. The dataset’s purpose is to showcase and keep record of vehicles registered in a certain area of the US, and is hard to evaluate car performances. The ranges listed could not reflect the cars maximum capacity, rather could be the range available at the time of registration of the car. In the future, I would look for a dataset that its purpose was to specifically test the ranges of the cars, and not just to keep records. Though the ranges were listed, they vary and that messes with the model and how the data would’ve turned out.

Reference materials https://www.youtube.com/watch?v=Rdq2oEWg3KU https://www.modernstatisticswithr.com/regression.html https://intro2r.com/mult_graphs.html