Introduction

This report analyzes stock price trends for 9 technology stocks from 2016 to 2024. The analysis includes:

  • Individual stock price trends
  • Normalized price comparisons
  • Summary statistics and returns

Load Required Libraries

library(ggplot2)
library(dplyr)
library(tidyr)
library(knitr)

Data Generation

We generate simulated stock price data for the following stocks: AAPL, AMD, MU, NIO, NVDA, PRPL, SNAP, TSLA, and TWTR.

# Set seed for reproducibility
set.seed(123)

# Function to generate stock price data
generate_stock_data <- function() {
  stocks <- c('AAPL', 'AMD', 'MU', 'NIO', 'NVDA', 'PRPL', 'SNAP', 'TSLA', 'TWTR')
  dates <- seq(as.Date("2016-01-01"), as.Date("2024-01-01"), by = "week")
  
  # Stock configurations
  configs <- list(
    AAPL = list(start = 25, trend = 0.0015, volatility = 0.02),
    AMD = list(start = 10, trend = 0.002, volatility = 0.04),
    MU = list(start = 15, trend = 0.0012, volatility = 0.035),
    NIO = list(start = 5, trend = 0.001, volatility = 0.06),
    NVDA = list(start = 20, trend = 0.0025, volatility = 0.045),
    PRPL = list(start = 10, trend = 0.0005, volatility = 0.05),
    SNAP = list(start = 15, trend = 0.0008, volatility = 0.055),
    TSLA = list(start = 20, trend = 0.002, volatility = 0.05),
    TWTR = list(start = 20, trend = 0.0008, volatility = 0.04)
  )
  
  # Generate data for all stocks
  all_data <- data.frame()
  
  for (stock in stocks) {
    config <- configs[[stock]]
    price <- config$start
    prices <- numeric(length(dates))
    
    for (i in 1:length(dates)) {
      change <- (runif(1) - 0.5) * config$volatility * price + config$trend * price
      price <- max(1, price + change)
      prices[i] <- price
    }
    
    stock_df <- data.frame(
      Date = dates,
      Stock = stock,
      Price = round(prices, 2)
    )
    
    all_data <- rbind(all_data, stock_df)
  }
  
  return(all_data)
}

# Generate the data
stock_data <- generate_stock_data()

Data Overview

# Display first few rows
kable(head(stock_data, 10), caption = "First 10 rows of stock data")
First 10 rows of stock data
Date Stock Price
2016-01-01 AAPL 24.93
2016-01-08 AAPL 25.11
2016-01-15 AAPL 25.10
2016-01-22 AAPL 25.33
2016-01-29 AAPL 25.60
2016-02-05 AAPL 25.40
2016-02-12 AAPL 25.45
2016-02-19 AAPL 25.69
2016-02-26 AAPL 25.76
2016-03-04 AAPL 25.77
# Data structure
str(stock_data)
## 'data.frame':    3762 obs. of  3 variables:
##  $ Date : Date, format: "2016-01-01" "2016-01-08" ...
##  $ Stock: chr  "AAPL" "AAPL" "AAPL" "AAPL" ...
##  $ Price: num  24.9 25.1 25.1 25.3 25.6 ...

Visualization 2: Normalized Stock Prices

This plot normalizes all stock prices to a base value of $1 at the start date, making it easier to compare relative performance across stocks with different price levels.

# Calculate normalized prices
normalized_data <- stock_data %>%
  group_by(Stock) %>%
  mutate(Normalized_Price = Price / first(Price)) %>%
  ungroup()

# Define colors for each stock
stock_colors <- c(
  "AAPL" = "#e74c3c",
  "AMD" = "#3498db",
  "MU" = "#2ecc71",
  "NIO" = "#9b59b6",
  "NVDA" = "#f39c12",
  "PRPL" = "#e8d21d",
  "SNAP" = "#1abc9c",
  "TSLA" = "#e91e63",
  "TWTR" = "#95a5a6"
)

ggplot(normalized_data, aes(x = Date, y = Normalized_Price, color = Stock)) +
  geom_line(size = 1) +
  scale_color_manual(values = stock_colors) +
  labs(
    x = "Date",
    y = "Normalized price (Base = $1)",
    title = "Normalized Stock Prices (2016-2024)",
    color = "Stock"
  ) +
  theme_minimal() +
  theme(
    legend.position = "right",
    panel.grid.minor = element_blank(),
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    axis.title = element_text(size = 11),
    axis.text = element_text(size = 9)
  )

Summary Statistics

# Calculate summary statistics by stock
summary_stats <- stock_data %>%
  group_by(Stock) %>%
  summarise(
    Start_Price = round(first(Price), 2),
    End_Price = round(last(Price), 2),
    Min_Price = round(min(Price), 2),
    Max_Price = round(max(Price), 2),
    Avg_Price = round(mean(Price), 2),
    Total_Return_Pct = round(((last(Price) - first(Price)) / first(Price)) * 100, 2)
  ) %>%
  arrange(desc(Total_Return_Pct))

kable(summary_stats, 
      caption = "Summary Statistics by Stock (Sorted by Total Return)",
      col.names = c("Stock", "Start Price", "End Price", "Min Price", 
                    "Max Price", "Avg Price", "Total Return (%)"))
Summary Statistics by Stock (Sorted by Total Return)
Stock Start Price End Price Min Price Max Price Avg Price Total Return (%)
NVDA 19.64 64.91 19.64 65.29 42.04 230.50
AMD 10.01 21.18 9.84 21.28 15.43 111.59
TSLA 20.28 40.16 18.62 40.25 28.61 98.03
AAPL 24.93 45.51 24.93 45.61 34.95 82.55
SNAP 15.34 26.35 14.36 27.00 18.43 71.77
TWTR 20.00 29.61 19.93 32.07 24.92 48.05
MU 15.13 21.05 14.63 22.47 18.54 39.13
NIO 4.90 6.65 4.10 7.19 5.59 35.71
PRPL 9.83 9.65 8.49 10.98 9.84 -1.83

Key Findings

# Best performer
best_stock <- summary_stats$Stock[1]
best_return <- summary_stats$Total_Return_Pct[1]

# Worst performer
worst_stock <- summary_stats$Stock[nrow(summary_stats)]
worst_return <- summary_stats$Total_Return_Pct[nrow(summary_stats)]

# Most volatile
volatility <- stock_data %>%
  group_by(Stock) %>%
  summarise(volatility = sd(Price)) %>%
  arrange(desc(volatility))

most_volatile <- volatility$Stock[1]

Based on the analysis:

  • Best Performer: NVDA with a total return of 230.5%
  • Worst Performer: PRPL with a total return of -1.83%
  • Most Volatile: NVDA (highest standard deviation)

Export Data

# Save to CSV
write.csv(stock_data, "stock_prices.csv", row.names = FALSE)
cat("Data exported to: stock_prices.csv\n")
## Data exported to: stock_prices.csv

Conclusion

This analysis demonstrates the varying performance of technology stocks from 2016 to 2024. The normalized view clearly shows which stocks outperformed others in terms of relative returns, while the faceted plots reveal individual price trends and volatility patterns.


Session Info

sessionInfo()
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 19045)
## 
## Matrix products: default
##   LAPACK version 3.12.1
## 
## locale:
## [1] LC_COLLATE=English_United States.utf8 
## [2] LC_CTYPE=English_United States.utf8   
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.utf8    
## 
## time zone: Asia/Taipei
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] knitr_1.50    tidyr_1.3.1   dplyr_1.1.4   ggplot2_4.0.0
## 
## loaded via a namespace (and not attached):
##  [1] vctrs_0.6.5        cli_3.6.5          rlang_1.1.6        xfun_0.52         
##  [5] purrr_1.1.0        generics_0.1.4     S7_0.2.0           jsonlite_2.0.0    
##  [9] labeling_0.4.3     glue_1.8.0         htmltools_0.5.8.1  sass_0.4.10       
## [13] scales_1.4.0       rmarkdown_2.29     grid_4.5.1         tibble_3.3.0      
## [17] evaluate_1.0.5     jquerylib_0.1.4    fastmap_1.2.0      yaml_2.3.10       
## [21] lifecycle_1.0.4    compiler_4.5.1     RColorBrewer_1.1-3 pkgconfig_2.0.3   
## [25] rstudioapi_0.17.1  farver_2.1.2       digest_0.6.37      R6_2.6.1          
## [29] tidyselect_1.2.1   pillar_1.11.1      magrittr_2.0.4     bslib_0.9.0       
## [33] withr_3.0.2        tools_4.5.1        gtable_0.3.6       cachem_1.1.0