loading packages and data set:

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(corrplot)
## corrplot 0.95 loaded
data("airquality")

head(airquality)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 5    NA      NA 14.3   56     5   5
## 6    28      NA 14.9   66     5   6

1. Measures of Central Tendency and Spread:

Ozone:

mean(airquality$Ozone, na.rm = TRUE)
## [1] 42.12931
median(airquality$Ozone, na.rm = TRUE)
## [1] 31.5
sd(airquality$Ozone, na.rm = TRUE)
## [1] 32.98788
min(airquality$Ozone, na.rm = TRUE)
## [1] 1
max(airquality$Ozone, na.rm = TRUE)
## [1] 168

Temp:

mean(airquality$Temp, na.rm = TRUE)
## [1] 77.88235
median(airquality$Temp, na.rm = TRUE)
## [1] 79
sd(airquality$Temp, na.rm = TRUE)
## [1] 9.46527
min(airquality$Temp, na.rm = TRUE)
## [1] 56
max(airquality$Temp, na.rm = TRUE)
## [1] 97

Wind:

mean(airquality$Wind, na.rm = TRUE)
## [1] 9.957516
median(airquality$Wind, na.rm = TRUE)
## [1] 9.7
sd(airquality$Wind, na.rm = TRUE)
## [1] 3.523001
min(airquality$Wind, na.rm = TRUE)
## [1] 1.7
max(airquality$Wind, na.rm = TRUE)
## [1] 20.7

The mean and median for Temp and Wind are close, which means their distributions are fairly balanced. For Ozone, the mean is 42.13 and the median is 31.5. The mean is higher, which suggests the ozone data is right-skewed. Ozone also has the largest standard deviation, showing that ozone levels have more variability.

2. Histogram:

ggplot(airquality, aes(x = Ozone)) + geom_histogram(binwidth = 10, fill = "skyblue", color = "black") +
labs( title = "Histogram of Ozone Levels", 
    x = "Ozone",
    y = "Frequency" ) + 
theme_minimal()
## Warning: Removed 37 rows containing non-finite outside the scale range
## (`stat_bin()`).

The ozone distribution is right-skewed and has one main peak. Most ozone values are lower, but there are a few very high values. These high values could be unusual ozone days.

3. Box-plot:

airquality <- airquality |>
  mutate(month_name = case_when( 
    Month == 5 ~ "May", 
    Month == 6 ~ "June", 
    Month == 7 ~ "July", 
    Month == 8 ~ "August", 
    Month == 9 ~ "September" ))

airquality$month_name <- factor(       airquality$month_name, 
levels = c("May", "June", "July", "August", "September") )
ggplot(airquality, aes(
  x = month_name, 
  y = Ozone)) + 
  geom_boxplot(fill = "lightblue") +     labs( title = "Ozone Levels by Month", x = "Month", 
  y = "Ozone" ) + 
  
  theme_minimal()
## Warning: Removed 37 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Ozone levels are lower in May and June and higher during July and August. August has the highest median ozone level. There are also some outliers, which show days when ozone was much higher than normal for that month.

4. Scatter-plot

ggplot(airquality, aes(
  x = Temp, 
  y = Ozone, 
  color = factor(Month))) +
  geom_point() + 
  labs( title = "Temperature vs. Ozone", x = "Temperature", 
  y = "Ozone", color = "Month" ) +
  
theme_minimal()
## Warning: Removed 37 rows containing missing values or values outside the scale range
## (`geom_point()`).

There is a positive relationship between temperature and ozone. As temperature increases, ozone levels also tend to increase. Warmer months such as July and August have more points with high temperatures and high ozone levels.

5. Correlation Matrix:

air_cor <- airquality |> 
  
  select(Ozone, Temp, Wind) |> 
  
  cor(use = "complete.obs") 


air_cor
##            Ozone       Temp       Wind
## Ozone  1.0000000  0.6983603 -0.6015465
## Temp   0.6983603  1.0000000 -0.5110750
## Wind  -0.6015465 -0.5110750  1.0000000
corrplot( air_cor, 
method = "color", 
addCoef.col = "black" )

Ozone and Temp have the strongest correlation at about 0.70. This is a positive relationship, meaning higher temperatures are associated with higher ozone levels. Ozone and Wind have a correlation of about -0.61, meaning ozone tends to decrease when wind increases. Temp and Wind have the weakest correlation at about -0.50.

6. Summary Table

monthly_summary <- airquality |>
  group_by(month_name) |>
  summarise(
  count = n(),
    mean_ozone = mean(Ozone, na.rm = TRUE),
    mean_temp = mean(Temp, na.rm = TRUE),
    mean_wind = mean(Wind, na.rm = TRUE)
  )


monthly_summary
## # A tibble: 5 × 5
##   month_name count mean_ozone mean_temp mean_wind
##   <fct>      <int>      <dbl>     <dbl>     <dbl>
## 1 May           31       23.6      65.5     11.6 
## 2 June          30       29.4      79.1     10.3 
## 3 July          31       59.1      83.9      8.94
## 4 August        31       60.0      84.0      8.79
## 5 September     30       31.4      76.9     10.2

August has the highest average ozone level at about 59.96, followed closely by July at about 59.12. July and August also have the highest average temperatures and lower average wind speeds. May has the lowest average temperature and higher average wind speed. Warmer temperatures may contribute to higher ozone levels, while stronger winds may help move and spread air pollutants. This may help explain why ozone levels are higher during the warmer summer months.