require(dplyr)
## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
require(triangle)
## Loading required package: triangle
require(ggplot2)
## Loading required package: ggplot2
require(stats)
iterations <- 1200
months <- 60
set.seed(321)
# for (i in 1:months) <--- I'm not sure the loop changes anything in the next four lines?
# I even tried adding brackets {} and it didn't do anything different
ice_car_growth_rate <- 1.005^(1:months) #0.5% per month
ice_truck_growth_rate <- 1.003^(1:months) # 0.3% per month
bev_car_growth_rate <- 1.02^(1:months) # 2% per month
bev_truck_growth_rate <- 1.015^(1:months) # 1.5% per month
# Initial number of vehicles (estimates for the start of the simulation)
initial_ice_cars <- 546000
initial_ice_trucks <- 234000
initial_bev_cars <- 14000
initial_bev_trucks <- 6000
# Set initial values
ice_cars_vector <- initial_ice_cars*ice_car_growth_rate
ice_trucks_vector <- initial_ice_trucks*ice_truck_growth_rate
bev_cars_vector <- initial_bev_cars*bev_car_growth_rate
bev_trucks_vector <- initial_bev_trucks*bev_truck_growth_rate
# Monthly Miles
set.seed(1)
miles <- rtriangle(iterations*months, 4785, 18858, 13476)/12
# Average battery size in kWh for BEVs
set.seed(2)
bev_battery_size_kwh <- rtriangle(iterations*months, 40, 118, 82)
#Average battery size in kwh for BEV trucks
set.seed(3)
bev_truck_battery_size_kwh <- rtriangle(iterations*months, 92, 212, 135)
# CO2 emission factors for ICE cars (sedans + small crossover SUVs)
set.seed(4)
truck_co2_per_10k_miles <- rnorm(iterations*months, mean = (4.2 + 5.8) / 2, sd = (5.8 - 4.2) / 4)
# CO2 emission factors for ICE trucks (Full sized pickups and larger SUVs)
set.seed(5)
car_co2_per_10k_miles <- rnorm(iterations*months, mean = (2.8 + 5.5) / 2, sd = (5.5 - 2.8) / 4) # Normal distribution between 2.8 and 5.5 tons
# CO2 emissions per kWh for battery production using triangular distribution
set.seed(6) # Set seed for reproducibility
bev_battery_co2_per_kwh <- rtriangle(iterations*months, 0.05, 0.2, 0.14) # tons of CO2 per kWh
# CO2 for battery production
bev_battery_co2 <- bev_battery_co2_per_kwh * bev_battery_size_kwh # Total CO2 for battery production
bev_truck_battery_co2 <- bev_battery_co2_per_kwh * bev_truck_battery_size_kwh #Total CO2 for battery production (trucks)
# Energy consumption values
set.seed(10) #SET SEEDS FOR ALL DIST
ice_car_consumption <- rtriangle(iterations*months, 3e6, 5e6, 4e6) / 3600000 * miles
set.seed(11)
ice_truck_consumption <- rtriangle(iterations*months, 6e6, 8e6, 7e6) / 3600000 * miles
set.seed(12)
# OLD: bev_car_consumption <- runif(iterations*months, 720000, 1260000) / 3600000 * miles
bev_car_consumption <- rnorm(iterations * months, mean = 990000, sd = 156174) / 3600000 * miles
set.seed(13)
bev_truck_consumption <- rnorm(iterations*months, 1800000, 120000) / 3600000 * miles
set.seed(14)
bev_car_grid_demand <- 1/rtriangle(iterations*months, 0.6, 0.89, 0.8)
set.seed(15)
bev_truck_grid_demand <- 1/rtriangle(iterations*months, 0.6, 0.89, 0.8)
bev_car_energy <- bev_car_consumption * (bev_car_grid_demand)
bev_truck_energy <- bev_truck_consumption * bev_truck_grid_demand
# CO2 emissions based on miles drive
ice_car_co2 <- (miles / 10000) * car_co2_per_10k_miles
ice_truck_co2 <- (miles / 10000) * truck_co2_per_10k_miles
#Grid CO2 production as a grid emission factor
grid_emissions_factor <- 0.000233 # Tons of CO₂ per kWh
# Calculate incremental vehicle populations
bev_cars_increment <- c(bev_cars_vector[1], diff(bev_cars_vector)) # Growth in BEV cars each month
bev_trucks_increment <- c(bev_trucks_vector[1], diff(bev_trucks_vector)) # Growth in BEV trucks each month
# Matrix for monthly BEV battery production emissions
bev_car_battery_production_matrix <- matrix(
bev_battery_co2_per_kwh * bev_battery_size_kwh, # CO2 per vehicle
nrow = months,
ncol = iterations
) * bev_cars_increment # Scale by incremental population growth
bev_truck_battery_production_matrix <- matrix(
bev_battery_co2_per_kwh * bev_truck_battery_size_kwh, # CO2 per vehicle
nrow = months,
ncol = iterations
) * bev_trucks_increment # Scale by incremental population growth
# Cumulative battery emissions for BEVs
bev_car_cumulative_battery_co2 <- apply(bev_car_battery_production_matrix, 2, cumsum)
bev_truck_cumulative_battery_co2 <- apply(bev_truck_battery_production_matrix, 2, cumsum)
# Grid-Based CO2 (unchanged from your existing logic)
bev_car_grid_co2 <- matrix(bev_car_energy * bev_cars_vector * grid_emissions_factor, nrow = months, ncol = iterations)
bev_truck_grid_co2 <- matrix(bev_truck_energy * bev_trucks_vector * grid_emissions_factor, nrow = months, ncol = iterations)
# Combine battery production and grid-based emissions
bev_car_co2_matrix <- bev_car_cumulative_battery_co2 + apply(bev_car_grid_co2, 2, cumsum)
bev_truck_co2_matrix <- bev_truck_cumulative_battery_co2 + apply(bev_truck_grid_co2, 2, cumsum)
#Cumulative Miles
mat_miles <- matrix(miles, nrow = months)
cumulative_miles <- apply(mat_miles, 2, cumsum) # Cumulative miles for each iteration
cumulative_miles_mean <- rowMeans(cumulative_miles)
ice_car_energy_matrix=matrix(ice_car_consumption * ice_cars_vector, nrow=months)
ice_truck_energy_matrix=matrix(ice_truck_consumption * ice_trucks_vector, nrow=months)
bev_car_energy_matrix=matrix(bev_car_energy * bev_cars_vector, nrow=months)
bev_truck_energy_matrix=matrix(bev_truck_energy * bev_trucks_vector, nrow=months)
ice_car_co2_matrix=matrix(ice_car_co2 * ice_cars_vector, nrow=months)
ice_truck_co2_matrix=matrix(ice_truck_co2 * ice_trucks_vector, nrow=months)
bev_car_co2_matrix=matrix(cumsum(bev_car_co2_matrix), nrow=months)
bev_truck_co2_matrix=matrix(cumsum(bev_truck_co2_matrix), nrow=months)
# Calculate mean, standard error, and 95% confidence intervals
myf <- function(x) {
means = rowMeans(x) # Row means
se = apply(x, 1, sd) / sqrt(iterations) # Row standard error
lower = means - qt(0.975, iterations - 1) * se # Lower bound
upper = means + qt(0.975, iterations - 1) * se # Upper bound
mymat = cbind(lower, means, upper) # Combine into matrix
return(mymat)
}
# ICE Car Energy Scatter
ice_energy_means=myf(ice_car_energy_matrix)
plot(ice_energy_means)
#Start Making Visual Plots #ICE truck Energy Scatter
ice_truck_energy_means=myf(ice_truck_energy_matrix)
plot(ice_truck_energy_means)
#BEV Car Energy Scatter
bev_car_energy_means=myf(bev_car_energy_matrix)
plot(bev_car_energy_means)
#BEV Truck Energy Scatter
bev_truck_energy_means=myf(bev_truck_energy_matrix)
plot(bev_truck_energy_means)
#ICE CO2 Scatter
ice_car_co2_means=myf(ice_car_co2_matrix)
plot(ice_car_co2_means)
ice_truck_co2_means=myf(ice_truck_co2_matrix)
plot(ice_truck_co2_means)
#BEV Car CO2 Scatter
bev_car_co2_means=myf(bev_car_co2_matrix)
plot(bev_car_co2_means)
bev_truck_co2_means=myf(bev_truck_co2_matrix)
plot(bev_truck_co2_means)
#Run CI function, create dataframe, and plot BEV energy over miles
# Apply the `myf` function to the BEV car energy matrix
bev_car_energy_ci <- myf(bev_car_energy_matrix)
# Create a data frame for plotting
bev_energy_plot_data <- data.frame(
Miles = cumulative_miles_mean, # Use cumulative miles mean or other suitable x-axis values
Mean = bev_car_energy_ci[, "means"],
Lower_CI = bev_car_energy_ci[, "lower"],
Upper_CI = bev_car_energy_ci[, "upper"]
)
# Plot using ggplot2
library(ggplot2)
ggplot(bev_energy_plot_data, aes(x = Miles)) +
geom_line(aes(y = Mean), color = "green") + # Mean line
geom_ribbon(aes(ymin = Lower_CI, ymax = Upper_CI), fill = "green", alpha = 0.2) + # Confidence intervals
labs(
title = "BEV Car Energy Consumption with Confidence Intervals",
x = "Cumulative Miles Driven",
y = "Energy Consumption (kWh)"
) +
theme_minimal()
# Combine ICE cars and trucks energy matrices
ice_total_energy_matrix <- ice_car_energy_matrix + ice_truck_energy_matrix
# Apply the `myf` function to the combined ICE energy matrix
ice_energy_ci <- myf(ice_total_energy_matrix)
# Create a data frame for plotting
ice_energy_plot_data <- data.frame(
Miles = cumulative_miles_mean, # Use cumulative miles mean for x-axis
Mean = ice_energy_ci[, "means"],
Lower_CI = ice_energy_ci[, "lower"],
Upper_CI = ice_energy_ci[, "upper"]
)
# Plot using ggplot2
library(ggplot2)
ggplot(ice_energy_plot_data, aes(x = Miles)) +
geom_line(aes(y = Mean), color = "blue") + # Mean line for ICE vehicles
geom_ribbon(aes(ymin = Lower_CI, ymax = Upper_CI), fill = "blue", alpha = 0.2) + # Confidence intervals
labs(
title = "ICE Vehicle Energy Consumption with Confidence Intervals",
x = "Cumulative Miles Driven",
y = "Energy Consumption (kWh)"
) +
theme_minimal()
# Combine BEV cars and trucks CO2 matrices
bev_total_co2_matrix <- bev_car_co2_matrix + bev_truck_co2_matrix
# Apply the `myf` function to the combined BEV CO2 matrix
bev_total_co2_ci <- myf(bev_total_co2_matrix)
# Create a data frame for plotting
bev_total_co2_plot_data <- data.frame(
Miles = cumulative_miles_mean, # Use cumulative miles mean for x-axis
Mean = bev_total_co2_ci[, "means"], # Mean of total BEV CO2
Lower_CI = bev_total_co2_ci[, "lower"], # Lower confidence interval
Upper_CI = bev_total_co2_ci[, "upper"] # Upper confidence interval
)
# Plot BEV CO2 emissions with confidence intervals over cumulative miles
ggplot(bev_total_co2_plot_data, aes(x = Miles)) +
geom_line(aes(y = Mean), color = "red", size = 1) + # Mean line for BEV CO2 emissions
geom_ribbon(aes(ymin = Lower_CI, ymax = Upper_CI), fill = "red", alpha = 0.2) + # Confidence intervals
labs(
title = "Total BEV CO2 Emissions with Confidence Intervals",
x = "Cumulative Miles Driven",
y = "CO2 Emissions (Tons)"
) +
theme_minimal() +
scale_x_continuous(limits = c(0, 60000)) + # Set x-axis range to 0 - 60000 miles
scale_y_continuous(limits = c(1.7e+10, 2.5e+10),
name = "CO2 Emissions (Tons)"
)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_line()`).
# Combine ICE cars and trucks CO2 matrices
ice_total_co2_matrix <- ice_car_co2_matrix + ice_truck_co2_matrix
# Apply the `myf` function to the combined ICE CO2 matrix
ice_co2_ci <- myf(ice_total_co2_matrix)
# Create a data frame for plotting
ice_co2_plot_data <- data.frame(
Miles = cumulative_miles_mean, # Use cumulative miles mean for x-axis
Mean = ice_co2_ci[, "means"],
Lower_CI = ice_co2_ci[, "lower"],
Upper_CI = ice_co2_ci[, "upper"]
)
# Plot using ggplot2
library(ggplot2)
ggplot(ice_co2_plot_data, aes(x = Miles)) +
geom_line(aes(y = Mean), color = "blue") + # Mean line for ICE CO2 emissions
geom_ribbon(aes(ymin = Lower_CI, ymax = Upper_CI), fill = "blue", alpha = 0.2) + # Confidence intervals
labs(
title = "ICE CO2 Emissions with Confidence Intervals",
x = "Cumulative Miles Driven",
y = "CO2 Emissions (Tons)"
) +
theme_minimal() +
scale_x_continuous(limits = c(0, max(cumulative_miles_mean))) # Ensure x-axis shows the full range
# Combine BEV and ICE total CO2 data into a data frame
co2_comparison_data <- data.frame(
Miles = cumulative_miles_mean, # Shared x-axis for cumulative miles
BEV_CO2_Mean = bev_total_co2_ci[, "means"], # BEV CO2 means
BEV_CO2_Lower_CI = bev_total_co2_ci[, "lower"],
BEV_CO2_Upper_CI = bev_total_co2_ci[, "upper"],
ICE_CO2_Mean = ice_co2_ci[, "means"], # ICE CO2 means
ICE_CO2_Lower_CI = ice_co2_ci[, "lower"],
ICE_CO2_Upper_CI = ice_co2_ci[, "upper"]
)
# Plot BEV and ICE total CO2 on the same chart
ggplot(co2_comparison_data, aes(x = Miles)) +
# BEV CO2 line and ribbon
geom_line(aes(y = BEV_CO2_Mean, color = "BEV"), size = 1) +
geom_ribbon(aes(ymin = BEV_CO2_Lower_CI, ymax = BEV_CO2_Upper_CI, fill = "BEV"), alpha = 0.2) +
# ICE CO2 line and ribbon
geom_line(aes(y = ICE_CO2_Mean, color = "ICE"), size = 1) +
geom_ribbon(aes(ymin = ICE_CO2_Lower_CI, ymax = ICE_CO2_Upper_CI, fill = "ICE"), alpha = 0.2) +
# Labels and legend
labs(
title = "Total CO2 Emissions: BEV vs ICE",
x = "Miles Driven",
y = "CO2 Emissions (Tons)",
color = "Vehicle Type",
fill = "Vehicle Type"
) +
scale_color_manual(values = c("BEV" = "green", "ICE" = "blue")) +
scale_fill_manual(values = c("BEV" = "green", "ICE" = "blue")) +
theme_minimal()
# Combine BEV and ICE total CO2 data into a data frame
co2_comparison_data <- data.frame(
Miles = cumulative_miles_mean, # Shared x-axis for cumulative miles
BEV_CO2_Mean = bev_total_co2_ci[, "means"], # BEV CO2 means
BEV_CO2_Lower_CI = bev_total_co2_ci[, "lower"],
BEV_CO2_Upper_CI = bev_total_co2_ci[, "upper"],
ICE_CO2_Mean = ice_co2_ci[, "means"], # ICE CO2 means
ICE_CO2_Lower_CI = ice_co2_ci[, "lower"],
ICE_CO2_Upper_CI = ice_co2_ci[, "upper"]
)
# Plot BEV and ICE total CO2 on the same chart with log scale
ggplot(co2_comparison_data, aes(x = Miles)) +
# BEV CO2 line and ribbon
geom_line(aes(y = BEV_CO2_Mean, color = "BEV"), size = 1) +
geom_ribbon(aes(ymin = BEV_CO2_Lower_CI, ymax = BEV_CO2_Upper_CI, fill = "BEV"), alpha = 0.2) +
# ICE CO2 line and ribbon
geom_line(aes(y = ICE_CO2_Mean, color = "ICE"), size = 1) +
geom_ribbon(aes(ymin = ICE_CO2_Lower_CI, ymax = ICE_CO2_Upper_CI, fill = "ICE"), alpha = 0.2) +
# Labels and legend
labs(
title = "Total CO2 Emissions (Log Scale): BEV vs ICE",
x = "Miles Driven",
y = "CO2 Emissions (Tons, Log Scale)",
color = "Vehicle Type",
fill = "Vehicle Type"
) +
scale_y_log10() + # Apply log scale to y-axis
scale_color_manual(values = c("BEV" = "green", "ICE" = "blue")) +
scale_fill_manual(values = c("BEV" = "green", "ICE" = "blue")) +
theme_minimal()
# Combine BEV and ICE total CO2 data into a data frame
energy_comparison_data <- data.frame(
Miles = cumulative_miles_mean, # Shared x-axis for cumulative miles
BEV_energy_Mean = bev_car_energy_ci[, "means"], # BEV CO2 means
BEV_energy_Lower_CI = bev_car_energy_ci[, "lower"],
BEV_energy_Upper_CI = bev_car_energy_ci[, "upper"],
ICE_energy_Mean = ice_energy_ci[, "means"], # ICE CO2 means
ICE_energy_Lower_CI = ice_energy_ci[, "lower"],
ICE_energy_Upper_CI = ice_energy_ci[, "upper"]
)
# Plot BEV and ICE total CO2 on the same chart with log scale
ggplot(energy_comparison_data, aes(x = Miles)) +
# BEV CO2 line and ribbon
geom_line(aes(y = BEV_energy_Mean, color = "BEV"), size = 1) +
geom_ribbon(aes(ymin = BEV_energy_Lower_CI, ymax = BEV_energy_Upper_CI, fill = "BEV"), alpha = 0.2) +
# ICE CO2 line and ribbon
geom_line(aes(y = ICE_energy_Mean, color = "ICE"), size = 1) +
geom_ribbon(aes(ymin = ICE_energy_Lower_CI, ymax = ICE_energy_Upper_CI, fill = "ICE"), alpha = 0.2) +
# Labels and legend
labs(
title = "Total Energy Consumption (Log Scale): BEV vs ICE",
x = "Miles Driven",
y = "CO2 Emissions (Tons, Log Scale)",
color = "Vehicle Type",
fill = "Vehicle Type"
) +
scale_y_log10() + # Apply log scale to y-axis
scale_color_manual(values = c("BEV" = "red", "ICE" = "purple")) +
scale_fill_manual(values = c("BEV" = "red", "ICE" = "purple")) +
theme_minimal()
# Create a histogram of monthly miles
hist(miles,
main = "Histogram of Monthly Miles Driven",
xlab = "Miles Driven (Monthly)",
col = "skyblue",
breaks = 30, # Number of bins
border = "white")
# Create side-by-side histograms
par(mfrow = c(1, 2)) # Set up a 1x2 plotting layout
# Histogram for BEV battery size
hist(bev_battery_size_kwh,
main = "Histogram of BEV Battery Sizes",
xlab = "Battery Size (kWh)",
col = "lightgreen",
breaks = 30, # Number of bins
border = "white")
# Histogram for BEV Truck battery size
hist(bev_truck_battery_size_kwh,
main = "Histogram of BEV Truck Battery Sizes",
xlab = "Battery Size (kWh)",
col = "lightblue",
breaks = 30, # Number of bins
border = "white")
# Reset plotting layout to default
par(mfrow = c(1, 1))
# Create side-by-side histograms
par(mfrow = c(1, 2)) # Set up a 1x2 plotting layout
# Histogram for Truck CO2 emissions per 10k miles
hist(truck_co2_per_10k_miles,
main = "ICE Truck CO2 Emissions (per 10k miles)",
xlab = "CO2 Emissions (Tons)",
col = "lightblue",
breaks = 30, # Number of bins
border = "white")
# Histogram for Car CO2 emissions per 10k miles
hist(car_co2_per_10k_miles,
main = "ICE Car CO2 Emissions (per 10k miles)",
xlab = "CO2 Emissions (Tons)",
col = "lightgreen",
breaks = 30, # Number of bins
border = "white")
# Reset plotting layout to default
par(mfrow = c(1, 1))
# Histogram for BEV battery CO2 emissions per kWh
hist(bev_battery_co2_per_kwh,
main = "BEV Battery CO2 Emissions per kWh",
xlab = "CO2 Emissions (Tons per kWh)",
col = "purple",
breaks = 30, # Number of bins
border = "black")
# First pair: ICE car and truck consumption
par(mfrow = c(1, 2)) # Arrange plots side by side
hist(ice_car_consumption,
main = "ICE Car Consumption",
xlab = "Consumption (kWh)",
col = "skyblue",
breaks = 30,
border = "white")
hist(ice_truck_consumption,
main = "ICE Truck Consumption",
xlab = "Consumption (kWh)",
col = "skyblue",
breaks = 30,
border = "white")
# Second pair: BEV car and truck consumption
par(mfrow = c(1, 2)) # Arrange plots side by side
hist(bev_car_consumption,
main = "BEV Car Consumption",
xlab = "Consumption (kWh)",
col = "lightgreen",
breaks = 30,
border = "white")
hist(bev_truck_consumption,
main = "BEV Truck Consumption",
xlab = "Consumption (kWh)",
col = "lightgreen",
breaks = 30,
border = "white")
# Third pair: BEV grid demand for cars and trucks
par(mfrow = c(1, 2)) # Arrange plots side by side
hist(bev_car_grid_demand,
main = "BEV Car Grid Demand",
xlab = "Grid Demand (Inverse Efficiency)",
col = "orange",
breaks = 30,
border = "white")
hist(bev_truck_grid_demand,
main = "BEV Truck Grid Demand",
xlab = "Grid Demand (Inverse Efficiency)",
col = "orange",
breaks = 30,
border = "white")
# Reset plotting layout to default
par(mfrow = c(1, 1))
print(dim(bev_car_battery_production_matrix)) # Should be months x iterations
## [1] 60 1200
print(dim(bev_truck_battery_production_matrix)) # Should be months x iterations
## [1] 60 1200
print(dim(bev_car_grid_co2)) # Should be months x iterations
## [1] 60 1200
print(dim(bev_truck_grid_co2)) # Should be months x iterations
## [1] 60 1200
print(dim(bev_car_co2_matrix)) # Should be months x iterations
## [1] 60 1200
print(dim(bev_truck_co2_matrix)) # Should be months x iterations
## [1] 60 1200
# Retain all previous libraries and settings
# Load necessary libraries
library(dplyr)
library(triangle)
library(ggplot2)
library(stats)
# Set global seed for reproducibility
set.seed(123)
# Set number of iterations
iterations <- 1000
months <- 60
# Initialize arrays to store cumulative miles and CO₂ emissions per iteration
cumulative_miles_iterations <- matrix(0, nrow = months, ncol = iterations)
bev_car_co2_iterations <- matrix(0, nrow = months, ncol = iterations)
ice_car_co2_iterations <- matrix(0, nrow = months, ncol = iterations)
# Run simulation across iterations
set.seed(123) # Ensure reproducibility
for (i in 1:iterations) {
# Sample annual and monthly mileage for this iteration
set.seed(1)
annual_miles_singular <- rtriangle(1, 4785, 18858, 13476)
monthly_miles_singular <- annual_miles_singular / 12
# Initialize cumulative mileage and emissions for this iteration
cumulative_miles <- numeric(months)
bev_car_co2 <- numeric(months)
ice_car_co2 <- numeric(months)
# Apply initial battery production CO₂ for BEV
set.seed(2)
bev_battery_size_kwh <- rtriangle(1, 45, 135, 82)
bev_battery_co2_per_kwh <- rtriangle(1, 0.05, 0.2, 0.14)
bev_battery_co2 <- bev_battery_size_kwh * bev_battery_co2_per_kwh
bev_car_co2[1] <- bev_battery_co2
# Initial ICE emissions
set.seed(3)
car_co2_per_10k_miles <- rnorm(1, mean = (2.6 + 5.2) / 2, sd = (5.2 - 2.6) / 4)
cumulative_miles[1] <- monthly_miles_singular
ice_car_co2[1] <- (monthly_miles_singular / 10000) * car_co2_per_10k_miles
# Loop over months
for (month in 2:months) {
cumulative_miles[month] <- cumulative_miles[month - 1] + monthly_miles_singular
# BEV energy consumption and grid emissions
set.seed(4)
bev_energy_consumption_per_mile <- runif(1, 0.24, 0.35)
bev_energy_consumption <- bev_energy_consumption_per_mile * monthly_miles_singular
bev_car_co2[month] <- bev_car_co2[month - 1] + (bev_energy_consumption * 0.000233)
# ICE emissions
ice_car_co2[month] <- ice_car_co2[month - 1] + (monthly_miles_singular / 10000) * car_co2_per_10k_miles
}
# Store results in iteration matrices
cumulative_miles_iterations[, i] <- cumulative_miles
bev_car_co2_iterations[, i] <- bev_car_co2
ice_car_co2_iterations[, i] <- ice_car_co2
}
# Calculate mean cumulative miles and emissions across all iterations
mean_cumulative_miles <- rowMeans(cumulative_miles_iterations)
mean_bev_car_co2 <- rowMeans(bev_car_co2_iterations)
mean_ice_car_co2 <- rowMeans(ice_car_co2_iterations)
# Optionally calculate confidence intervals (95%)
bev_car_co2_se <- apply(bev_car_co2_iterations, 1, sd) / sqrt(iterations)
ice_car_co2_se <- apply(ice_car_co2_iterations, 1, sd) / sqrt(iterations)
bev_car_co2_lower <- mean_bev_car_co2 - qt(0.975, iterations - 1) * bev_car_co2_se
bev_car_co2_upper <- mean_bev_car_co2 + qt(0.975, iterations - 1) * bev_car_co2_se
ice_car_co2_lower <- mean_ice_car_co2 - qt(0.975, iterations - 1) * ice_car_co2_se
ice_car_co2_upper <- mean_ice_car_co2 + qt(0.975, iterations - 1) * ice_car_co2_se
# Create a data frame for plotting
df_bev_vs_ice_avg <- data.frame(
Miles = mean_cumulative_miles,
BEV_CO2_Mean = mean_bev_car_co2,
BEV_CO2_Lower = bev_car_co2_lower,
BEV_CO2_Upper = bev_car_co2_upper,
ICE_CO2_Mean = mean_ice_car_co2,
ICE_CO2_Lower = ice_car_co2_lower,
ICE_CO2_Upper = ice_car_co2_upper
)
library(ggplot2)
ggplot(df_bev_vs_ice_avg, aes(x = Miles)) +
# BEV Emissions
geom_line(aes(y = BEV_CO2_Mean), color = "green", linetype = "solid") +
geom_ribbon(aes(ymin = BEV_CO2_Lower, ymax = BEV_CO2_Upper), fill = "green", alpha = 0.2) +
# ICE Emissions
geom_line(aes(y = ICE_CO2_Mean), color = "blue", linetype = "dashed") +
geom_ribbon(aes(ymin = ICE_CO2_Lower, ymax = ICE_CO2_Upper), fill = "blue", alpha = 0.2) +
# Plot Labels
labs(
title = "Average CO₂ Emissions: BEV vs ICE (Multiple Iterations)",
x = "Cumulative Miles Driven",
y = "CO₂ Emissions (Tons)",
caption = "Green Solid: BEV (including battery production CO₂ at zero miles)\nBlue Dashed: ICE"
) +
theme_minimal() +
xlim(0, max(mean_cumulative_miles)) +
ylim(0, max(c(mean_bev_car_co2, mean_ice_car_co2)))
# Install necessary libraries if not already installed
# install.packages("plotly")
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
# Generating data (BEV battery size, ICE CO2 per 10,000 miles, and Miles to Offset)
bev_battery_size <- seq(40, 212, length.out = 30) # BEV battery size from 40 to 212 kWh
ice_co2_output <- seq(2.1, 8, length.out = 30) # ICE CO2 output from 2.1 to 8 tons
co2_per_kwh <- seq(0.05, 0.2, length.out = 10) # CO2 per kWh of battery production
# Create grid of values for battery size and ICE CO2
battery_ice_grid <- expand.grid(Battery = bev_battery_size, ICE_CO2 = ice_co2_output)
# Function to calculate Miles to Offset
miles_to_offset <- function(battery_size, ice_co2, co2_kwh) {
# Constants
co2_per_mile_bev <- 0.25 * 0.000233 # BEV CO2 per mile (fixed)
# BEV battery CO2 emissions
bev_battery_co2 <- battery_size * co2_kwh
# Calculate miles needed to offset
miles <- bev_battery_co2 / (ice_co2 / 10000 - co2_per_mile_bev)
return(miles)
}
# Prepare an empty list to store plot data
plot_data <- list()
# Generate surface plots for different values of CO2 per kWh (third variable)
for (co2_kwh in co2_per_kwh) {
# Calculate Miles to Offset for each combination of BEV battery size and ICE CO2
battery_ice_grid$Miles <- with(battery_ice_grid, miles_to_offset(Battery, ICE_CO2, co2_kwh))
# Add plot data for each CO2 per kWh scenario
plot_data[[as.character(co2_kwh)]] <- plot_ly(
x = ~battery_ice_grid$Battery,
y = ~battery_ice_grid$ICE_CO2,
z = ~battery_ice_grid$Miles,
type = "scatter3d",
mode = "markers",
marker = list(size = 3, color = ~battery_ice_grid$Miles, colorscale = "Viridis"),
text = paste("BEV Battery:", battery_ice_grid$Battery, "kWh", "<br>ICE CO2 Output:", battery_ice_grid$ICE_CO2,
"<br>Miles to Offset:", battery_ice_grid$Miles, "miles")
)
}
# Render the first plot for one CO2 per kWh value
plot_data[[1]]
# Load the triangle package
if (!require(triangle)) {
install.packages("triangle")
}
library(triangle)
# Set seed for reproducibility
set.seed(123)
# Generate random samples from a triangular distribution
n <- 1000 # Number of samples
min_val <- 40 # Minimum value
max_val <- 118 # Maximum value
mode_val <- 82 # Mode (peak) value
# Generate the data
observed_samples <- rtriangle(n, a = min_val, b = max_val, c = mode_val)
# Create bins for the range of the distribution
num_bins <- 10 # Number of bins
breaks <- seq(min_val, max_val, length.out = num_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(observed_samples, breaks = breaks, plot = FALSE)$counts
# Function for Triangular PDF
triangular_pdf <- function(x, a, b, c) {
if (x < a || x > b) return(0)
if (x <= c) {
return(2 * (x - a) / ((b - a) * (c - a)))
} else {
return(2 * (b - x) / ((b - a) * (b - c)))
}
}
# Calculate expected frequencies
expected_freq <- sapply(1:num_bins, function(i) {
lower <- breaks[i]
upper <- breaks[i + 1]
mid <- (lower + upper) / 2 # Approximate PDF using the bin midpoint
prob <- triangular_pdf(mid, min_val, max_val, mode_val) * (upper - lower)
return(prob)
})
# Scale probabilities to match the total number of observations
expected_freq <- expected_freq * n
# Perform the Chi-Square Goodness-of-Fit Test
chisq_result <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Display the result
print(chisq_result)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 4.0981, df = 9, p-value = 0.9048
# Visualization
barplot(rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("skyblue", "orange"),
names.arg = round(breaks[-1], 1),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Triangular Distribution)",
xlab = "Bins",
ylab = "Frequency")
# Load the triangle package
if (!require(triangle)) {
install.packages("triangle")
}
library(triangle)
# Set seed for reproducibility
set.seed(123)
# Generate random samples from a triangular distribution
n <- 1000 # Number of samples
min_val <- 92 # Minimum value
max_val <- 212 # Maximum value
mode_val <- 135 # Mode (peak) value
# Generate the data
observed_samples <- rtriangle(n, a = min_val, b = max_val, c = mode_val)
# Create bins for the range of the distribution
num_bins <- 10 # Number of bins
breaks <- seq(min_val, max_val, length.out = num_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(observed_samples, breaks = breaks, plot = FALSE)$counts
# Function for Triangular PDF
triangular_pdf <- function(x, a, b, c) {
if (x < a || x > b) return(0)
if (x <= c) {
return(2 * (x - a) / ((b - a) * (c - a)))
} else {
return(2 * (b - x) / ((b - a) * (b - c)))
}
}
# Calculate expected frequencies
expected_freq <- sapply(1:num_bins, function(i) {
lower <- breaks[i]
upper <- breaks[i + 1]
mid <- (lower + upper) / 2 # Approximate PDF using the bin midpoint
prob <- triangular_pdf(mid, min_val, max_val, mode_val) * (upper - lower)
return(prob)
})
# Scale probabilities to match the total number of observations
expected_freq <- expected_freq * n
# Perform the Chi-Square Goodness-of-Fit Test
chisq_result <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Display the result
print(chisq_result)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 0.70284, df = 9, p-value = 0.9999
# Visualization
barplot(rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("blue", "yellow"),
names.arg = round(breaks[-1], 1),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Triangular Distribution)",
xlab = "Bins",
ylab = "Frequency")
# Load the triangle package
if (!require(triangle)) {
install.packages("triangle")
}
library(triangle)
# Set seed for reproducibility
set.seed(123)
# Generate random samples from a triangular distribution
n <- 1000 # Number of samples
min_val <- 4785 # Minimum value
max_val <- 18858 # Maximum value
mode_val <- 13476 # Mode (peak) value
# Generate the data
observed_samples <- rtriangle(n, a = min_val, b = max_val, c = mode_val)
# Create bins for the range of the distribution
num_bins <- 10 # Number of bins
breaks <- seq(min_val, max_val, length.out = num_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(observed_samples, breaks = breaks, plot = FALSE)$counts
# Function for Triangular PDF
triangular_pdf <- function(x, a, b, c) {
if (x < a || x > b) return(0)
if (x <= c) {
return(2 * (x - a) / ((b - a) * (c - a)))
} else {
return(2 * (b - x) / ((b - a) * (b - c)))
}
}
# Calculate expected frequencies
expected_freq <- sapply(1:num_bins, function(i) {
lower <- breaks[i]
upper <- breaks[i + 1]
mid <- (lower + upper) / 2 # Approximate PDF using the bin midpoint
prob <- triangular_pdf(mid, min_val, max_val, mode_val) * (upper - lower)
return(prob)
})
# Scale probabilities to match the total number of observations
expected_freq <- expected_freq * n
# Perform the Chi-Square Goodness-of-Fit Test
chisq_result <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Display the result
print(chisq_result)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 2.4652, df = 9, p-value = 0.9818
# Visualization
barplot(rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("skyblue", "orange"),
names.arg = round(breaks[-1], 1),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Triangular Distribution)",
xlab = "Bins",
ylab = "Frequency")
# Load the triangle package
if (!require(triangle)) {
install.packages("triangle")
}
library(triangle)
# Set seed for reproducibility
set.seed(123)
# Generate random samples from a triangular distribution
n <- 1000 # Number of samples
min_val <- 0.05 # Minimum value
max_val <- 0.2 # Maximum value
mode_val <- 0.14 # Mode (peak) value
# Generate the data
observed_samples <- rtriangle(n, a = min_val, b = max_val, c = mode_val)
# Create bins for the range of the distribution
num_bins <- 10 # Number of bins
breaks <- seq(min_val, max_val, length.out = num_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(observed_samples, breaks = breaks, plot = FALSE)$counts
# Function for Triangular PDF
triangular_pdf <- function(x, a, b, c) {
if (x < a || x > b) return(0)
if (x <= c) {
return(2 * (x - a) / ((b - a) * (c - a)))
} else {
return(2 * (b - x) / ((b - a) * (b - c)))
}
}
# Calculate expected frequencies
expected_freq <- sapply(1:num_bins, function(i) {
lower <- breaks[i]
upper <- breaks[i + 1]
mid <- (lower + upper) / 2 # Approximate PDF using the bin midpoint
prob <- triangular_pdf(mid, min_val, max_val, mode_val) * (upper - lower)
return(prob)
})
# Scale probabilities to match the total number of observations
expected_freq <- expected_freq * n
# Perform the Chi-Square Goodness-of-Fit Test
chisq_result <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Display the result
print(chisq_result)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 3.0583, df = 9, p-value = 0.9619
# Visualization
barplot(rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("blue", "yellow"),
names.arg = round(breaks[-1], 1),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Triangular Distribution)",
xlab = "Bins",
ylab = "Frequency")
# Load the triangle package
if (!require(triangle)) {
install.packages("triangle")
}
library(triangle)
# Set seed for reproducibility
set.seed(123)
# Generate random samples from a triangular distribution
n <- 1000 # Number of samples
min_val <- 3000000 # Minimum value
max_val <- 5000000 # Maximum value
mode_val <- 4000000 # Mode (peak) value
# Generate the data
observed_samples <- rtriangle(n, a = min_val, b = max_val, c = mode_val)
# Create bins for the range of the distribution
num_bins <- 10 # Number of bins
breaks <- seq(min_val, max_val, length.out = num_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(observed_samples, breaks = breaks, plot = FALSE)$counts
# Function for Triangular PDF
triangular_pdf <- function(x, a, b, c) {
if (x < a || x > b) return(0)
if (x <= c) {
return(2 * (x - a) / ((b - a) * (c - a)))
} else {
return(2 * (b - x) / ((b - a) * (b - c)))
}
}
# Calculate expected frequencies
expected_freq <- sapply(1:num_bins, function(i) {
lower <- breaks[i]
upper <- breaks[i + 1]
mid <- (lower + upper) / 2 # Approximate PDF using the bin midpoint
prob <- triangular_pdf(mid, min_val, max_val, mode_val) * (upper - lower)
return(prob)
})
# Scale probabilities to match the total number of observations
expected_freq <- expected_freq * n
# Perform the Chi-Square Goodness-of-Fit Test
chisq_result <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Display the result
print(chisq_result)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 2.9368, df = 9, p-value = 0.9667
# Visualization
barplot(rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("lightblue", "pink"),
names.arg = round(breaks[-1], 1),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Triangular Distribution)",
xlab = "Bins",
ylab = "Frequency")
# Load the triangle package
if (!require(triangle)) {
install.packages("triangle")
}
library(triangle)
# Set seed for reproducibility
set.seed(123)
# Generate random samples from a triangular distribution
n <- 1000 # Number of samples
min_val <- 6000000 # Minimum value
max_val <- 8000000 # Maximum value
mode_val <- 7000000 # Mode (peak) value
# Generate the data
observed_samples <- rtriangle(n, a = min_val, b = max_val, c = mode_val)
# Create bins for the range of the distribution
num_bins <- 10 # Number of bins
breaks <- seq(min_val, max_val, length.out = num_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(observed_samples, breaks = breaks, plot = FALSE)$counts
# Function for Triangular PDF
triangular_pdf <- function(x, a, b, c) {
if (x < a || x > b) return(0)
if (x <= c) {
return(2 * (x - a) / ((b - a) * (c - a)))
} else {
return(2 * (b - x) / ((b - a) * (b - c)))
}
}
# Calculate expected frequencies
expected_freq <- sapply(1:num_bins, function(i) {
lower <- breaks[i]
upper <- breaks[i + 1]
mid <- (lower + upper) / 2 # Approximate PDF using the bin midpoint
prob <- triangular_pdf(mid, min_val, max_val, mode_val) * (upper - lower)
return(prob)
})
# Scale probabilities to match the total number of observations
expected_freq <- expected_freq * n
# Perform the Chi-Square Goodness-of-Fit Test
chisq_result <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Display the result
print(chisq_result)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 2.9368, df = 9, p-value = 0.9667
# Visualization
barplot(rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("blue", "yellow"),
names.arg = round(breaks[-1], 1),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Triangular Distribution)",
xlab = "Bins",
ylab = "Frequency")
# Load the triangle package
if (!require(triangle)) {
install.packages("triangle")
}
library(triangle)
# Set seed for reproducibility
set.seed(123)
# Generate random samples from a triangular distribution
n <- 1000 # Number of samples
min_val <- 0.6 # Minimum value
max_val <- 0.89 # Maximum value
mode_val <- 0.8 # Mode (peak) value
# Generate the data
observed_samples <- rtriangle(n, a = min_val, b = max_val, c = mode_val)
# Create bins for the range of the distribution
num_bins <- 10 # Number of bins
breaks <- seq(min_val, max_val, length.out = num_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(observed_samples, breaks = breaks, plot = FALSE)$counts
# Function for Triangular PDF
triangular_pdf <- function(x, a, b, c) {
if (x < a || x > b) return(0)
if (x <= c) {
return(2 * (x - a) / ((b - a) * (c - a)))
} else {
return(2 * (b - x) / ((b - a) * (b - c)))
}
}
# Calculate expected frequencies
expected_freq <- sapply(1:num_bins, function(i) {
lower <- breaks[i]
upper <- breaks[i + 1]
mid <- (lower + upper) / 2 # Approximate PDF using the bin midpoint
prob <- triangular_pdf(mid, min_val, max_val, mode_val) * (upper - lower)
return(prob)
})
# Scale probabilities to match the total number of observations
expected_freq <- expected_freq * n
# Perform the Chi-Square Goodness-of-Fit Test
chisq_result <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Display the result
print(chisq_result)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 0.47266, df = 9, p-value = 1
# Visualization
barplot(rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("lightblue", "lightgreen"),
names.arg = round(breaks[-1], 1),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Triangular Distribution)",
xlab = "Bins",
ylab = "Frequency")
# Load required libraries
library(ggplot2)
# Set parameters for the normal distribution
set.seed(123)
n_samples <- 5000 # Number of samples
mean_value <- 5 # Mean of the normal distribution
sd_value <- 0.4 # Standard deviation of the normal distribution
# Generate random samples from a normal distribution
sample_data <- rnorm(n_samples, mean = mean_value, sd = sd_value)
# Define the number of bins
n_bins <- 10
# Create bins for the histogram
breaks <- seq(min(sample_data), max(sample_data), length.out = n_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(sample_data, breaks = breaks, plot = FALSE)$counts
# Calculate expected frequencies using the normal PDF
expected_freq <- diff(pnorm(breaks, mean = mean_value, sd = sd_value)) * n_samples
# Ensure no expected frequency is zero (adjust if necessary)
if (any(expected_freq == 0)) {
stop("Some expected frequencies are zero. Adjust the number of bins or sample size.")
}
# Perform the Chi-Square Goodness-of-Fit Test
chi_sq_test <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Print the test results
print(chi_sq_test)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 5.8746, df = 9, p-value = 0.7524
# Plot the observed vs expected frequencies
barplot(
rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("skyblue", "orange"),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Normal Distribution)",
xlab = "Bins",
ylab = "Frequency"
)
# Load required libraries
library(ggplot2)
# Set parameters for the normal distribution
set.seed(123)
n_samples <- 5000 # Number of samples
mean_value <- 4.15 # Mean of the normal distribution
sd_value <- 0.675 # Standard deviation of the normal distribution
# Generate random samples from a normal distribution
sample_data <- rnorm(n_samples, mean = mean_value, sd = sd_value)
# Define the number of bins
n_bins <- 10
# Create bins for the histogram
breaks <- seq(min(sample_data), max(sample_data), length.out = n_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(sample_data, breaks = breaks, plot = FALSE)$counts
# Calculate expected frequencies using the normal PDF
expected_freq <- diff(pnorm(breaks, mean = mean_value, sd = sd_value)) * n_samples
# Ensure no expected frequency is zero (adjust if necessary)
if (any(expected_freq == 0)) {
stop("Some expected frequencies are zero. Adjust the number of bins or sample size.")
}
# Perform the Chi-Square Goodness-of-Fit Test
chi_sq_test <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Print the test results
print(chi_sq_test)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 5.8746, df = 9, p-value = 0.7524
# Plot the observed vs expected frequencies
barplot(
rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("skyblue", "orange"),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Normal Distribution)",
xlab = "Bins",
ylab = "Frequency"
)
# Load required libraries
library(ggplot2)
# Set parameters for the normal distribution
set.seed(123)
n_samples <- 5000 # Number of samples
mean_value <- 990000 # Mean of the normal distribution
sd_value <- 156174 # Standard deviation of the normal distribution
# Generate random samples from a normal distribution
sample_data <- rnorm(n_samples, mean = mean_value, sd = sd_value)
# Define the number of bins
n_bins <- 10
# Create bins for the histogram
breaks <- seq(min(sample_data), max(sample_data), length.out = n_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(sample_data, breaks = breaks, plot = FALSE)$counts
# Calculate expected frequencies using the normal PDF
expected_freq <- diff(pnorm(breaks, mean = mean_value, sd = sd_value)) * n_samples
# Ensure no expected frequency is zero (adjust if necessary)
if (any(expected_freq == 0)) {
stop("Some expected frequencies are zero. Adjust the number of bins or sample size.")
}
# Perform the Chi-Square Goodness-of-Fit Test
chi_sq_test <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Print the test results
print(chi_sq_test)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 5.8746, df = 9, p-value = 0.7524
# Plot the observed vs expected frequencies
barplot(
rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("skyblue", "orange"),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Normal Distribution)",
xlab = "Bins",
ylab = "Frequency"
)
# Load required libraries
library(ggplot2)
# Set parameters for the normal distribution
set.seed(123)
n_samples <- 5000 # Number of samples
mean_value <- 1800000 # Mean of the normal distribution
sd_value <- 120000 # Standard deviation of the normal distribution
# Generate random samples from a normal distribution
sample_data <- rnorm(n_samples, mean = mean_value, sd = sd_value)
# Define the number of bins
n_bins <- 10
# Create bins for the histogram
breaks <- seq(min(sample_data), max(sample_data), length.out = n_bins + 1)
# Calculate observed frequencies
observed_freq <- hist(sample_data, breaks = breaks, plot = FALSE)$counts
# Calculate expected frequencies using the normal PDF
expected_freq <- diff(pnorm(breaks, mean = mean_value, sd = sd_value)) * n_samples
# Ensure no expected frequency is zero (adjust if necessary)
if (any(expected_freq == 0)) {
stop("Some expected frequencies are zero. Adjust the number of bins or sample size.")
}
# Perform the Chi-Square Goodness-of-Fit Test
chi_sq_test <- chisq.test(x = observed_freq, p = expected_freq / sum(expected_freq), rescale.p = TRUE)
# Print the test results
print(chi_sq_test)
##
## Chi-squared test for given probabilities
##
## data: observed_freq
## X-squared = 5.8746, df = 9, p-value = 0.7524
# Plot the observed vs expected frequencies
barplot(
rbind(observed_freq, expected_freq),
beside = TRUE,
col = c("skyblue", "orange"),
legend.text = c("Observed", "Expected"),
args.legend = list(x = "topright"),
main = "Observed vs Expected Frequencies (Normal Distribution)",
xlab = "Bins",
ylab = "Frequency"
)
# ------------------------------
# Fleet-Wide Monte Carlo Sobol Sensitivity Analysis
# ------------------------------
# Install and load required libraries
if (!requireNamespace("sensitivity", quietly = TRUE)) install.packages("sensitivity")
## Registered S3 method overwritten by 'sensitivity':
## method from
## print.src dplyr
if (!requireNamespace("lhs", quietly = TRUE)) install.packages("lhs")
library(sensitivity)
## Warning: package 'sensitivity' was built under R version 4.4.2
##
## Attaching package: 'sensitivity'
## The following object is masked from 'package:dplyr':
##
## src
library(lhs)
## Warning: package 'lhs' was built under R version 4.4.2
# 1. Define Parameter Ranges
param_ranges_fleet <- data.frame(
ice_car_consumption = c(3e6, 5e6), # Range for ICE car consumption (kWh)
ice_truck_consumption = c(6e6, 8e6), # Range for ICE truck consumption (kWh)
bev_car_consumption = c(720000, 1260000),# Range for BEV car consumption (kWh)
bev_truck_consumption = c(1.6e6, 2e6) # Range for BEV truck consumption (kWh)
)
# 2. Generate Latin Hypercube Samples
n_samples <- 50000
lhs_samples_fleet <- randomLHS(n_samples, ncol(param_ranges_fleet))
colnames(lhs_samples_fleet) <- colnames(param_ranges_fleet)
# Scale samples to parameter ranges
lhs_scaled_fleet <- as.data.frame(
sweep(lhs_samples_fleet, 2, param_ranges_fleet[,1], FUN = "*") +
sweep(lhs_samples_fleet, 2, diff(t(param_ranges_fleet)), FUN = "*")
)
## Warning in sweep(lhs_samples_fleet, 2, diff(t(param_ranges_fleet)), FUN = "*"):
## STATS is longer than the extent of 'dim(x)[MARGIN]'
# 3. Define the Fleet-Wide Simulation Model
fleet_model <- function(params) {
ice_car_energy <- params$ice_car_consumption * 0.8 # Arbitrary efficiency factor
ice_truck_energy <- params$ice_truck_consumption * 0.85
bev_car_energy <- params$bev_car_consumption * 0.9
bev_truck_energy <- params$bev_truck_consumption * 0.95
total_energy <- ice_car_energy + ice_truck_energy + bev_car_energy + bev_truck_energy
return(total_energy)
}
# 4. Perform Sobol Sensitivity Analysis
sobol_result_fleet <- sobol(
model = fleet_model,
X1 = lhs_scaled_fleet,
X2 = lhs_scaled_fleet,
nboot = 100
)
# 5. Display and Visualize Results
print(sobol_result_fleet)
##
## Call:
## sobol(model = fleet_model, X1 = lhs_scaled_fleet, X2 = lhs_scaled_fleet, nboot = 100)
##
## Model runs: 250000
##
## Sobol indices
## original bias std. error min. c.i. max. c.i.
## ice_car_consumption 1.000066 5.146731e-08 5.276134e-07 1.000065 1.000067
## ice_truck_consumption 1.000066 5.146731e-08 5.276134e-07 1.000065 1.000067
## bev_car_consumption 1.000066 5.146731e-08 5.276134e-07 1.000065 1.000067
## bev_truck_consumption 1.000066 5.146731e-08 5.276134e-07 1.000065 1.000067
plot(sobol_result_fleet, main = "Sobol Sensitivity Analysis: Fleet-Wide Monte Carlo Simulation")
# ------------------------------
# Single-Vehicle Monte Carlo Sobol Sensitivity Analysis
# ------------------------------
# Install and load required libraries
if (!requireNamespace("sensitivity", quietly = TRUE)) install.packages("sensitivity")
if (!requireNamespace("lhs", quietly = TRUE)) install.packages("lhs")
library(sensitivity)
library(lhs)
# 1. Define Parameter Ranges
param_ranges_single <- data.frame(
annual_miles_singular = c(4785, 18858), # Range for annual miles driven
bev_battery_size = c(40, 135), # Range for BEV battery size (kWh)
car_co2_per_10k_miles = c(2.6, 5.2) # Range for ICE CO2 emissions per 10,000 miles (tons)
)
# 2. Generate Latin Hypercube Samples
n_samples <- 1000
lhs_samples_single <- randomLHS(n_samples, ncol(param_ranges_single))
colnames(lhs_samples_single) <- colnames(param_ranges_single)
# Scale samples to parameter ranges
lhs_scaled_single <- as.data.frame(
sweep(lhs_samples_single, 2, param_ranges_single[,1], FUN = "*") +
sweep(lhs_samples_single, 2, diff(t(param_ranges_single)), FUN = "*")
)
## Warning in sweep(lhs_samples_single, 2, param_ranges_single[, 1], FUN = "*"):
## STATS does not recycle exactly across MARGIN
## Warning in sweep(lhs_samples_single, 2, diff(t(param_ranges_single)), FUN =
## "*"): STATS is longer than the extent of 'dim(x)[MARGIN]'
# 3. Define the Single-Vehicle Simulation Model
single_vehicle_model <- function(params) {
bev_battery_co2 <- params$bev_battery_size * 0.14 # Upstream CO2 emissions per kWh
ice_emissions <- params$car_co2_per_10k_miles * (params$annual_miles_singular / 10000)
total_emissions <- bev_battery_co2 + ice_emissions
return(total_emissions)
}
# 4. Perform Sobol Sensitivity Analysis
sobol_result_single <- sobol(
model = single_vehicle_model,
X1 = lhs_scaled_single,
X2 = lhs_scaled_single,
nboot = 100
)
# 5. Display and Visualize Results
print(sobol_result_single)
##
## Call:
## sobol(model = single_vehicle_model, X1 = lhs_scaled_single, X2 = lhs_scaled_single, nboot = 100)
##
## Model runs: 4000
##
## Sobol indices
## original bias std. error min. c.i. max. c.i.
## annual_miles_singular 1.000545 2.913504e-06 2.300299e-05 1.000497 1.000585
## bev_battery_size 1.000545 2.913504e-06 2.300299e-05 1.000497 1.000585
## car_co2_per_10k_miles 1.000545 2.913504e-06 2.300299e-05 1.000497 1.000585
plot(sobol_result_single, main = "Sobol Sensitivity Analysis: Single-Vehicle Monte Carlo Simulation")
# Fleet-Wide Monte Carlo Wilcoxon Rank-Sum Test
# Ensure necessary libraries are loaded
library(ggplot2)
# Variables from Fleet-Wide Simulation
fleet_emissions_run1 <- rowSums(bev_car_co2_matrix) # Total BEV car emissions per iteration
fleet_emissions_run2 <- rowSums(ice_car_co2_matrix) # Total ICE car emissions per iteration
# Remove any NA values
fleet_emissions_run1 <- na.omit(fleet_emissions_run1)
fleet_emissions_run2 <- na.omit(fleet_emissions_run2)
# Perform Wilcoxon Rank-Sum Test
wilcox_fleet <- wilcox.test(fleet_emissions_run1, fleet_emissions_run2,
alternative = "two.sided",
exact = FALSE,
correct = TRUE)
# Print test results
print(wilcox_fleet)
##
## Wilcoxon rank sum test with continuity correction
##
## data: fleet_emissions_run1 and fleet_emissions_run2
## W = 3600, p-value < 2.2e-16
## alternative hypothesis: true location shift is not equal to 0
# Visualization for Comparison
boxplot(fleet_emissions_run1, fleet_emissions_run2,
names = c("BEV Fleet Emissions", "ICE Fleet Emissions"),
col = c("skyblue", "lightgreen"),
main = "Wilcoxon Test: Fleet-Wide Simulation Comparison",
ylab = "CO₂ Emissions (Tons)")
# Interpretation:
if (wilcox_fleet$p.value < 0.05) {
print("Significant difference detected between BEV and ICE Fleet Simulation Outputs.")
} else {
print("No significant difference detected between BEV and ICE Fleet Simulation Outputs.")
}
## [1] "Significant difference detected between BEV and ICE Fleet Simulation Outputs."
# Single-Vehicle Monte Carlo Wilcoxon Rank-Sum Test
# Variables from Single-Vehicle Simulation
single_vehicle_emissions_run1 <- mean_bev_car_co2 # BEV single vehicle emissions
single_vehicle_emissions_run2 <- mean_ice_car_co2 # ICE single vehicle emissions
# Remove any NA values
single_vehicle_emissions_run1 <- na.omit(single_vehicle_emissions_run1)
single_vehicle_emissions_run2 <- na.omit(single_vehicle_emissions_run2)
# Perform Wilcoxon Rank-Sum Test
wilcox_single <- wilcox.test(single_vehicle_emissions_run1, single_vehicle_emissions_run2,
alternative = "two.sided",
exact = FALSE,
correct = TRUE)
# Print test results
print(wilcox_single)
##
## Wilcoxon rank sum test with continuity correction
##
## data: single_vehicle_emissions_run1 and single_vehicle_emissions_run2
## W = 2524, p-value = 0.0001462
## alternative hypothesis: true location shift is not equal to 0
# Visualization for Comparison
boxplot(single_vehicle_emissions_run1, single_vehicle_emissions_run2,
names = c("BEV Vehicle Emissions", "ICE Vehicle Emissions"),
col = c("lightcoral", "lightblue"),
main = "Wilcoxon Test: Single-Vehicle Simulation Comparison",
ylab = "CO₂ Emissions (Tons)")
# Interpretation:
if (wilcox_single$p.value < 0.05) {
print("Significant difference detected between BEV and ICE Single Vehicle Simulation Outputs.")
} else {
print("No significant difference detected between BEV and ICE Single Vehicle Simulation Outputs.")
}
## [1] "Significant difference detected between BEV and ICE Single Vehicle Simulation Outputs."
# Load necessary libraries
library(ggplot2)
library(dplyr)
library(car) # For ANOVA analysis
## Warning: package 'car' was built under R version 4.4.2
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.4.2
##
## Attaching package: 'car'
## The following object is masked from 'package:sensitivity':
##
## scatterplot
## The following object is masked from 'package:dplyr':
##
## recode
# Expand grid for all three variables
battery_ice_grid <- expand.grid(
Battery = bev_battery_size,
ICE_CO2 = ice_co2_output,
co2_kwh = co2_per_kwh
)
# Calculate Miles for each combination
battery_ice_grid$Miles <- with(battery_ice_grid, miles_to_offset(Battery, ICE_CO2, co2_kwh))
# Fit the Response Surface Regression Model
rsm_model <- lm(Miles ~ Battery + ICE_CO2 + co2_kwh, data = battery_ice_grid)
# Display summary of the regression model
summary_rsm <- summary(rsm_model)
print(summary_rsm)
##
## Call:
## lm(formula = Miles ~ Battery + ICE_CO2 + co2_kwh, data = battery_ice_grid)
##
## Residuals:
## Min 1Q Median 3Q Max
## -29762 -9706 -4932 5382 147897
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 13776.713 830.727 16.58 <2e-16 ***
## Battery 341.806 3.445 99.22 <2e-16 ***
## ICE_CO2 -11256.302 100.426 -112.08 <2e-16 ***
## co2_kwh 344540.909 3694.147 93.27 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 16780 on 8996 degrees of freedom
## Multiple R-squared: 0.7757, Adjusted R-squared: 0.7756
## F-statistic: 1.037e+04 on 3 and 8996 DF, p-value: < 2.2e-16