Master of Science in Big Data Analytics

R for Data Science

Mid Term Exam

Stock Market Analysis and Prediction by Using a Regression Model

# Load all the datasets in R Stidio separately 
# excluding NIFTY50_all.csv and stock_metadata.csv
# ================================================

ADANIPORTS <- read.csv("ADANIPORTS.csv")
ASIANPAINT <- read.csv("ASIANPAINT.csv")
AXISBANK <- read.csv("AXISBANK.csv")
BAJAJ_AUTO <- read.csv("BAJAJ-AUTO.csv")
BAJAJFINSV <- read.csv("BAJAJFINSV.csv")
BAJFINANCE <- read.csv("BAJFINANCE.csv")
BHARTIARTL <- read.csv("BHARTIARTL.csv")
BPCL <- read.csv("BPCL.csv")
BRITANNIA <- read.csv("BRITANNIA.csv")
CIPLA <- read.csv("CIPLA.csv")
COALINDIA <- read.csv("COALINDIA.csv")
DRREDDY <- read.csv("DRREDDY.csv")
EICHERMOT <- read.csv("EICHERMOT.csv")
GAIL <- read.csv("GAIL.csv")
GRASIM <- read.csv("GRASIM.csv")
HCLTECH <- read.csv("HCLTECH.csv")
HDFC <- read.csv("HDFC.csv")
HDFCBANK <- read.csv("HDFCBANK.csv")
HEROMOTOCO <- read.csv("HEROMOTOCO.csv")
HINDALCO <- read.csv("HINDALCO.csv")
HINDUNILVR <- read.csv("HINDUNILVR.csv")
ICICIBANK <- read.csv("ICICIBANK.csv")
INDUSINDBK <- read.csv("INDUSINDBK.csv")
INFRATEL <- read.csv("INFRATEL.csv")
INFY <- read.csv("INFY.csv")
IOC <- read.csv("IOC.csv")
ITC <- read.csv("ITC.csv")
JSWSTEEL <- read.csv("JSWSTEEL.csv")
KOTAKBANK <- read.csv("KOTAKBANK.csv")
LT <- read.csv("LT.csv")
MARUTI <- read.csv("MARUTI.csv")
MM <- read.csv("MM.csv")
NESTLEIND <- read.csv("NESTLEIND.csv")
NTPC <- read.csv("NTPC.csv")
ONGC <- read.csv("ONGC.csv")
POWERGRID <- read.csv("POWERGRID.csv")
RELIANCE <- read.csv("RELIANCE.csv")
SBIN <- read.csv("SBIN.csv")
SHREECEM <- read.csv("SHREECEM.csv")
SUNPHARMA <- read.csv("SUNPHARMA.csv")
TATAMOTORS <- read.csv("TATAMOTORS.csv")
TATASTEEL <- read.csv("TATASTEEL.csv")
TCS <- read.csv("TCS.csv")
TECHM <- read.csv("TECHM.csv")
TITAN <- read.csv("TITAN.csv")
ULTRACEMCO <- read.csv("ULTRACEMCO.csv")
UPL <- read.csv("UPL.csv")
VEDL <- read.csv("VEDL.csv")
WIPRO <- read.csv("WIPRO.csv")
ZEEL <- read.csv("ZEEL.csv")


# Display first 6 rows of Zee Entertainment Enterprises Ltd Vedanta Ltd datasets
# Checking that datasets are loaded
# ==============================================================================

#Zee Entertainment Enterprises Ltd
head(ZEEL)
##         Date  Symbol Series Prev.Close    Open    High     Low    Last   Close
## 1 2000-01-03 ZEETELE     EQ    1092.55 1175.00 1179.95 1160.00 1179.95 1179.95
## 2 2000-01-04 ZEETELE     EQ    1179.95 1220.00 1274.35 1183.10 1274.35 1260.65
## 3 2000-01-05 ZEETELE     EQ    1260.65 1160.55 1317.70 1159.80 1190.95 1176.55
## 4 2000-01-06 ZEETELE     EQ    1176.55 1195.00 1200.00 1095.00 1106.00 1115.45
## 5 2000-01-07 ZEETELE     EQ    1115.45 1097.10 1097.10 1026.25 1026.25 1026.25
## 6 2000-01-10 ZEETELE     EQ    1026.25 1026.25 1026.25  944.30  962.00  966.70
##      VWAP  Volume     Turnover Trades Deliverable.Volume X.Deliverble
## 1 1177.03 1261391 1.484690e+14     NA                 NA           NA
## 2 1228.02 4616547 5.669220e+14     NA                 NA           NA
## 3 1238.35 8763127 1.085178e+15     NA                 NA           NA
## 4 1135.04 5164020 5.861353e+14     NA                 NA           NA
## 5 1029.94  755129 7.777374e+13     NA                 NA           NA
## 6  980.49 3942813 3.865885e+14     NA                 NA           NA
#Vedanta Ltd
head(VEDL)
##         Date  Symbol Series Prev.Close   Open   High    Low   Last  Close
## 1 2000-01-03 SESAGOA     EQ     107.70 111.00 116.35 108.00 116.35 116.35
## 2 2000-01-04 SESAGOA     EQ     116.35 113.75 116.00 108.00 116.00 114.70
## 3 2000-01-05 SESAGOA     EQ     114.70 107.55 115.85 107.55 114.50 114.00
## 4 2000-01-06 SESAGOA     EQ     114.00 112.00 123.10 112.00 118.80 119.30
## 5 2000-01-07 SESAGOA     EQ     119.30 119.85 120.00 114.05 116.50 116.50
## 6 2000-01-10 SESAGOA     EQ     116.50 120.50 120.85 116.00 119.00 119.00
##     VWAP Volume     Turnover Trades Deliverable.Volume X.Deliverble
## 1 114.80  20371 233859660000     NA                 NA           NA
## 2 113.34  22366 253499440000     NA                 NA           NA
## 3 112.78  18305 206436075000     NA                 NA           NA
## 4 119.89  25800 309313325000     NA                 NA           NA
## 5 116.84  17361 202840260000     NA                 NA           NA
## 6 118.69  20707 245767815000     NA                 NA           NA

4.1 Exploratory data analysis

Create a function to profile each stock by displaying the following information: trading date range, missing values, number of outliers, top 5 rows, data types, and summary statistics. Then, apply the function to the Zee Entertainment Enterprises Ltd dataset and display the results.

# =========================================================
# Load Zee Entertainment dataset
# =========================================================

ZEEL <- read.csv("ZEEL.csv")

# Convert Date column into proper date format
ZEEL$Date <- as.Date(ZEEL$Date)

# =========================================================
# Function to profile stock dataset
# =========================================================

stock_profile <- function(data) {
  
  print("Trading Date Range")
  print(range(data$Date))
  
  print("Missing Values")
  print(colSums(is.na(data)))
  
  print("Number of Outliers in Close Price")
  
  # Detect outliers using IQR method
  Q1 <- quantile(data$Close, 0.25)
  Q3 <- quantile(data$Close, 0.75)
  
  IQR_value <- Q3 - Q1
  
  lower_limit <- Q1 - 1.5 * IQR_value
  upper_limit <- Q3 + 1.5 * IQR_value
  
  outliers <- data$Close[
    data$Close < lower_limit |
    data$Close > upper_limit
  ]
  
  print(length(outliers))
  
  print("Top 5 Rows")
  print(head(data, 5))
  
  print("Data Types")
  print(str(data))
  
  print("Summary Statistics")
  print(summary(data))
}

# =========================================================
# Apply function to ZEEL dataset
# =========================================================

stock_profile(ZEEL)
## [1] "Trading Date Range"
## [1] "2000-01-03" "2021-04-30"
## [1] "Missing Values"
##               Date             Symbol             Series         Prev.Close 
##                  0                  0                  0                  0 
##               Open               High                Low               Last 
##                  0                  0                  0                  0 
##              Close               VWAP             Volume           Turnover 
##                  0                  0                  0                  0 
##             Trades Deliverable.Volume       X.Deliverble 
##               2850                519                519 
## [1] "Number of Outliers in Close Price"
## [1] 84
## [1] "Top 5 Rows"
##         Date  Symbol Series Prev.Close    Open    High     Low    Last   Close
## 1 2000-01-03 ZEETELE     EQ    1092.55 1175.00 1179.95 1160.00 1179.95 1179.95
## 2 2000-01-04 ZEETELE     EQ    1179.95 1220.00 1274.35 1183.10 1274.35 1260.65
## 3 2000-01-05 ZEETELE     EQ    1260.65 1160.55 1317.70 1159.80 1190.95 1176.55
## 4 2000-01-06 ZEETELE     EQ    1176.55 1195.00 1200.00 1095.00 1106.00 1115.45
## 5 2000-01-07 ZEETELE     EQ    1115.45 1097.10 1097.10 1026.25 1026.25 1026.25
##      VWAP  Volume     Turnover Trades Deliverable.Volume X.Deliverble
## 1 1177.03 1261391 1.484690e+14     NA                 NA           NA
## 2 1228.02 4616547 5.669220e+14     NA                 NA           NA
## 3 1238.35 8763127 1.085178e+15     NA                 NA           NA
## 4 1135.04 5164020 5.861353e+14     NA                 NA           NA
## 5 1029.94  755129 7.777374e+13     NA                 NA           NA
## [1] "Data Types"
## 'data.frame':    5306 obs. of  15 variables:
##  $ Date              : Date, format: "2000-01-03" "2000-01-04" ...
##  $ Symbol            : chr  "ZEETELE" "ZEETELE" "ZEETELE" "ZEETELE" ...
##  $ Series            : chr  "EQ" "EQ" "EQ" "EQ" ...
##  $ Prev.Close        : num  1093 1180 1261 1177 1115 ...
##  $ Open              : num  1175 1220 1161 1195 1097 ...
##  $ High              : num  1180 1274 1318 1200 1097 ...
##  $ Low               : num  1160 1183 1160 1095 1026 ...
##  $ Last              : num  1180 1274 1191 1106 1026 ...
##  $ Close             : num  1180 1261 1177 1115 1026 ...
##  $ VWAP              : num  1177 1228 1238 1135 1030 ...
##  $ Volume            : int  1261391 4616547 8763127 5164020 755129 3942813 6802005 2968833 2251046 2949092 ...
##  $ Turnover          : num  1.48e+14 5.67e+14 1.09e+15 5.86e+14 7.78e+13 ...
##  $ Trades            : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ Deliverable.Volume: num  NA NA NA NA NA NA NA NA NA NA ...
##  $ X.Deliverble      : num  NA NA NA NA NA NA NA NA NA NA ...
## NULL
## [1] "Summary Statistics"
##       Date                  Symbol           Series       Prev.Close    
##  Min.   :2000-01-03   Length   :5306   Length   :5306   Min.   :  62.3  
##  1st Qu.:2005-04-13   N.unique :   2   N.unique :   1   1st Qu.: 143.2  
##  Median :2010-08-17   N.blank  :   0   N.blank  :   0   Median : 238.2  
##  Mean   :2010-08-18   Min.nchar:   4   Min.nchar:   2   Mean   : 273.4  
##  3rd Qu.:2015-12-17   Max.nchar:   7   Max.nchar:   2   3rd Qu.: 345.6  
##  Max.   :2021-04-30                                     Max.   :1541.7  
##                                                                         
##       Open           High             Low              Last       
##  Min.   :  62   Min.   :  66.3   Min.   :  60.1   Min.   :  62.7  
##  1st Qu.: 144   1st Qu.: 146.9   1st Qu.: 140.0   1st Qu.: 143.5  
##  Median : 238   Median : 244.0   Median : 231.4   Median : 237.7  
##  Mean   : 274   Mean   : 279.6   Mean   : 267.6   Mean   : 273.2  
##  3rd Qu.: 346   3rd Qu.: 352.8   3rd Qu.: 338.4   3rd Qu.: 345.1  
##  Max.   :1640   Max.   :1645.0   Max.   :1512.2   Max.   :1564.0  
##                                                                   
##      Close             VWAP             Volume             Turnover        
##  Min.   :  62.3   Min.   :  63.08   Min.   :     4415   Min.   :7.021e+10  
##  1st Qu.: 143.2   1st Qu.: 143.68   1st Qu.:  1218226   1st Qu.:2.595e+13  
##  Median : 238.1   Median : 238.90   Median :  2138807   Median :5.250e+13  
##  Mean   : 273.2   Mean   : 273.63   Mean   :  4825422   Mean   :1.249e+14  
##  3rd Qu.: 345.6   3rd Qu.: 345.64   3rd Qu.:  4532904   3rd Qu.:1.137e+14  
##  Max.   :1541.7   Max.   :1578.11   Max.   :165959680   Max.   :4.286e+15  
##                                                                            
##      Trades        Deliverable.Volume  X.Deliverble   
##  Min.   :    296   Min.   :    4415   Min.   :0.0557  
##  1st Qu.:  24579   1st Qu.:  513686   1st Qu.:0.3073  
##  Median :  41074   Median :  893532   Median :0.4635  
##  Mean   :  62646   Mean   : 1415718   Mean   :0.4522  
##  3rd Qu.:  71463   3rd Qu.: 1593444   3rd Qu.:0.5939  
##  Max.   :1088460   Max.   :42891428   Max.   :1.0000  
##  NAs    :2850      NAs    :519        NAs    :519

Analyze trading volume trends and identify unusual volume spikes. Identify at least 3 significant market events visible in the data (e.g., COVID-19,…) and annotate them on chart.

# =========================================================
# Trading Volume Trend Analysis
# =========================================================

# Plot trading volume trend

plot(
  ZEEL$Date,
  ZEEL$Volume,
  type = "l",
  main = "ZEEL Trading Volume Trend",
  xlab = "Date",
  ylab = "Trading Volume"
)

# =========================================================
# Identify unusual volume spikes
# =========================================================

volume_threshold <- mean(ZEEL$Volume) + 2 * sd(ZEEL$Volume)

spikes <- ZEEL[ZEEL$Volume > volume_threshold, ]

# Display unusual spikes
head(spikes)
##           Date  Symbol Series Prev.Close  Open   High   Low   Last  Close
## 161 2000-08-23 ZEETELE     EQ     492.75 495.2 510.95 483.3 498.55 505.15
## 235 2000-12-07 ZEETELE     EQ     306.45 306.0 329.80 305.0 327.70 324.05
## 265 2001-01-19 ZEETELE     EQ     227.95 229.0 263.90 228.6 262.00 258.10
## 267 2001-01-23 ZEETELE     EQ     267.00 265.5 289.95 265.0 285.50 285.85
## 269 2001-01-25 ZEETELE     EQ     278.15 280.0 284.00 263.1 277.60 276.35
## 288 2001-02-22 ZEETELE     EQ     237.20 235.5 240.70 227.1 231.50 233.50
##       VWAP   Volume     Turnover Trades Deliverable.Volume X.Deliverble
## 161 500.04 23396356 1.169918e+15     NA                 NA           NA
## 235 318.36 22379180 7.124565e+14     NA                 NA           NA
## 265 245.36 26527273 6.508762e+14     NA                 NA           NA
## 267 281.88 23827589 6.716586e+14     NA                 NA           NA
## 269 272.20 24840007 6.761374e+14     NA                 NA           NA
## 288 233.76 23414924 5.473381e+14     NA                 NA           NA
# Highlight spikes on chart
points(
  spikes$Date,
  spikes$Volume,
  col = "red",
  pch = 19
)

# =========================================================
# Add significant market events
# =========================================================

# COVID-19 Market Crash
abline(v = as.Date("2020-03-01"), col = "blue", lty = 2)

text(
  as.Date("2020-03-01"),
  max(ZEEL$Volume),
  "COVID-19",
  pos = 4
)

# Market Recovery
abline(v = as.Date("2021-01-01"), col = "green", lty = 2)

text(
  as.Date("2021-01-01"),
  max(ZEEL$Volume) * 0.9,
  "Market Recovery",
  pos = 4
)

# Inflation / Global Uncertainty
abline(v = as.Date("2022-02-01"), col = "purple", lty = 2)

text(
  as.Date("2022-02-01"),
  max(ZEEL$Volume) * 0.8,
  "Global Uncertainty",
  pos = 4
)

4.3 Visualization

# ============================================
# Load packages
# ============================================

library(ggplot2)
library(zoo)
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
# ============================================
# Load dataset
# ============================================

ZEEL <- read.csv("ZEEL.csv")

# Convert Date column
ZEEL$Date <- as.Date(ZEEL$Date)

# ============================================
# Percentage Change
# ============================================

ZEEL$Percentage_Change <- 
  ((ZEEL$Close - ZEEL$Prev.Close) /
     ZEEL$Prev.Close) * 100

# ============================================
# Moving Averages
# ============================================

ZEEL$MA15 <- rollmean(ZEEL$Close, 15, fill = NA)

ZEEL$MA30 <- rollmean(ZEEL$Close, 30, fill = NA)

ZEEL$MA45 <- rollmean(ZEEL$Close, 45, fill = NA)

# ============================================
# Closing Price Trend
# ============================================

ggplot(ZEEL, aes(Date, Close)) +
  geom_line() +
  ggtitle("Closing Price Trend")

# ============================================
# Percentage Change Trend
# ============================================

ggplot(ZEEL, aes(Date, Percentage_Change)) +
  geom_line() +
  ggtitle("Percentage Change Trend")

# ============================================
# Sales Volume Trend
# ============================================

ggplot(ZEEL, aes(Date, Volume)) +
  geom_line() +
  ggtitle("Sales Volume Trend")

# ============================================
# Moving Average Trend
# ============================================

ggplot(ZEEL, aes(Date, Close)) +
  
  geom_line() +
  
  geom_line(aes(y = MA15), color = "blue") +
  
  geom_line(aes(y = MA30), color = "red") +
  
  geom_line(aes(y = MA45), color = "green") +
  
  ggtitle("15, 30 and 45 Days Moving Average")
## Warning: Removed 14 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 29 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 44 rows containing missing values or values outside the scale range
## (`geom_line()`).

# ============================================
# Histogram
# ============================================

ggplot(ZEEL, aes(Percentage_Change)) +
  
  geom_histogram(bins = 30) +
  
  ggtitle("Histogram of Percentage Change")

4.4 Correlation Analysis

# ============================================
# Load dataset
# ============================================

ZEEL <- read.csv("ZEEL.csv")

# ============================================
# Select numerical columns
# ============================================

data <- ZEEL[, c(
  "Prev.Close",
  "Open",
  "High",
  "Low",
  "Close",
  "Volume"
)]

# ============================================
# Correlation Matrix
# ============================================

cor(data)
##             Prev.Close        Open        High         Low       Close
## Prev.Close  1.00000000  0.99942268  0.99885060  0.99838428  0.99790147
## Open        0.99942268  1.00000000  0.99913584  0.99869374  0.99811311
## High        0.99885060  0.99913584  1.00000000  0.99814370  0.99880555
## Low         0.99838428  0.99869374  0.99814370  1.00000000  0.99911821
## Close       0.99790147  0.99811311  0.99880555  0.99911821  1.00000000
## Volume     -0.04934908 -0.04832402 -0.03974465 -0.05694402 -0.04744036
##                 Volume
## Prev.Close -0.04934908
## Open       -0.04832402
## High       -0.03974465
## Low        -0.05694402
## Close      -0.04744036
## Volume      1.00000000
# ============================================
# Scatter Plot Matrix
# ============================================

pairs(data)

# ============================================
# Heatmap of Correlation
# ============================================

heatmap(cor(data))

# ============================================
# Find highly correlated pairs
# ============================================

correlation <- cor(data)

print(correlation)
##             Prev.Close        Open        High         Low       Close
## Prev.Close  1.00000000  0.99942268  0.99885060  0.99838428  0.99790147
## Open        0.99942268  1.00000000  0.99913584  0.99869374  0.99811311
## High        0.99885060  0.99913584  1.00000000  0.99814370  0.99880555
## Low         0.99838428  0.99869374  0.99814370  1.00000000  0.99911821
## Close       0.99790147  0.99811311  0.99880555  0.99911821  1.00000000
## Volume     -0.04934908 -0.04832402 -0.03974465 -0.05694402 -0.04744036
##                 Volume
## Prev.Close -0.04934908
## Open       -0.04832402
## High       -0.03974465
## Low        -0.05694402
## Close      -0.04744036
## Volume      1.00000000

4.5 Regression Analysis

# ============================================
# Load dataset
# ============================================

ZEEL <- read.csv("ZEEL.csv")

# ============================================
# Select variables
# ============================================

data <- ZEEL[, c(
  "Prev.Close",
  "Open",
  "High",
  "Low",
  "Volume",
  "Close"
)]

# Remove missing values
data <- na.omit(data)

# ============================================
# Split data into training and test sets
# ============================================

set.seed(123)

sample_size <- floor(0.8 * nrow(data))

train_index <- sample(
  1:nrow(data),
  sample_size
)

train_data <- data[train_index, ]

test_data <- data[-train_index, ]

# Print sizes
print(dim(train_data))
## [1] 4244    6
print(dim(test_data))
## [1] 1062    6
# ============================================
# Train regression model
# ============================================

model <- lm(
  Close ~ Prev.Close + Open + High + Low + Volume,
  data = train_data
)

# ============================================
# Predict test data
# ============================================

predicted <- predict(
  model,
  test_data
)

# ============================================
# Performance Metrics
# ============================================

# RMSE
rmse <- sqrt(
  mean((test_data$Close - predicted)^2)
)

print(rmse)
## [1] 4.847351
# MAE
mae <- mean(
  abs(test_data$Close - predicted)
)

print(mae)
## [1] 2.403604
# R2
r2 <- cor(
  test_data$Close,
  predicted
)^2

print(r2)
## [1] 0.9992598
# ============================================
# Scatter Plot
# ============================================

plot(
  test_data$Close,
  predicted,
  main = "Actual vs Predicted Close Price",
  xlab = "Actual Close Price",
  ylab = "Predicted Close Price"
)

# 45-degree reference line
abline(0, 1, col = "red")

# ============================================
# Standardize independent variables
# ============================================

x <- data[, c(
  "Prev.Close",
  "Open",
  "High",
  "Low",
  "Volume"
)]

scaled_x <- scale(x)

# Mean after scaling
print(colMeans(scaled_x))
##    Prev.Close          Open          High           Low        Volume 
##  1.260117e-16 -1.713930e-17  3.974498e-17 -4.879196e-17  1.369993e-17
# Standard deviation after scaling
print(apply(scaled_x, 2, sd))
## Prev.Close       Open       High        Low     Volume 
##          1          1          1          1          1
# ============================================
# PCA
# ============================================

pca <- prcomp(
  scaled_x,
  center = TRUE,
  scale. = TRUE
)

# Select first 2 components
pca_data <- pca$x[, 1:2]

# Split PCA data
train_pca <- pca_data[train_index, ]

test_pca <- pca_data[-train_index, ]

# Train PCA regression model
pca_model <- lm(
  train_data$Close ~ .,
  data = as.data.frame(train_pca)
)

# Predict PCA model
pca_pred <- predict(
  pca_model,
  as.data.frame(test_pca)
)

# PCA R2
pca_r2 <- cor(
  test_data$Close,
  pca_pred
)^2

print(pca_r2)
## [1] 0.9976517

4.6 Sales volume comparisons

# ============================================
# Load datasets
# ============================================

ZEEL <- read.csv("ZEEL.csv")

VEDL <- read.csv("VEDL.csv")

# ============================================
# Convert Date column
# ============================================

ZEEL$Date <- as.Date(ZEEL$Date)

VEDL$Date <- as.Date(VEDL$Date)

# ============================================
# Extract Year
# ============================================

ZEEL$Year <- format(ZEEL$Date, "%Y")

VEDL$Year <- format(VEDL$Date, "%Y")

# ============================================
# Annual Sales Volume
# ============================================

zeel_volume <- aggregate(
  Volume ~ Year,
  data = ZEEL,
  sum
)

vedl_volume <- aggregate(
  Volume ~ Year,
  data = VEDL,
  sum
)

# ============================================
# Combine datasets
# ============================================

combined <- data.frame(
  
  Year = zeel_volume$Year,
  
  ZEEL = zeel_volume$Volume,
  
  VEDL = vedl_volume$Volume
)

print(combined)
##    Year       ZEEL       VEDL
## 1  2000 2124967599    3859848
## 2  2001 2136706114    7426543
## 3  2002 1402554565   20751661
## 4  2003 1000731804   46142649
## 5  2004  569852081  100736719
## 6  2005  459053470  171258643
## 7  2006  611240479   45725647
## 8  2007  408755292   72642593
## 9  2008  307791908  641538432
## 10 2009  436102564 1888019256
## 11 2010  377601412 1266509516
## 12 2011  465542142  652829352
## 13 2012  477606441  664266631
## 14 2013  626168229 1064395380
## 15 2014  631955791 1516787175
## 16 2015  565559180 1896714942
## 17 2016  506730371 4038767678
## 18 2017  493681594 2598719114
## 19 2018  598775408 3276296751
## 20 2019 3696617196 2944363596
## 21 2020 6403204532 7377503381
## 22 2021 1302490317 1430971315
# ============================================
# Clustered Bar Chart
# ============================================

barplot(
  
  t(as.matrix(combined[, 2:3])),
  
  beside = TRUE,
  
  names.arg = combined$Year,
  
  col = c("blue", "green"),
  
  main = "Annual Sales Volume Comparison",
  
  xlab = "Year",
  
  ylab = "Total Volume"
)

legend(
  "topright",
  
  legend = c("ZEEL", "VEDL"),
  
  fill = c("blue", "green")
)

# ============================================
# 2018 Highest Volume
# ============================================

volume_2018 <- combined[
  combined$Year == "2018",
]

print(volume_2018)
##    Year      ZEEL       VEDL
## 19 2018 598775408 3276296751
# ============================================
# 2021 Lowest Volume
# ============================================

volume_2021 <- combined[
  combined$Year == "2021",
]

print(volume_2021)
##    Year       ZEEL       VEDL
## 22 2021 1302490317 1430971315
# ============================================
# Ratio for 2021
# ============================================

ratio_2021 <- volume_2021$ZEEL /
  volume_2021$VEDL

print(ratio_2021)
## [1] 0.9102141