Red Wine Quality [Lions Team]

Authors

Collin Stephens

Colin Breault

Hammad Rana

Published

April 30, 2026

Figure 1: Wine and food

Credit: Maria Das Dores on Unsplash



Introduction

In this project, we analyzed the “Wine Quality” dataset from UC Irvine and donated from Cortez et al., 2009. UC Irvine used this dataset for machine learning research, as seen in this Kaggle page. These researchers went into quite a lot of depth, that we won’t be going into; however, we will just cover the basics. They looked at both red and white wine, but we chose, for the sake of simplicity, to analyze only the red wine samples, and they do have different tasting profiles as well which would make things more complex if we included both. These wines are from the north of Portugal, and the grape varieties were not specified, neither were the specific brands or wineries, or the price for that matter. In essence, this dataset looks at only the wines’ physicochemical properties to assess which properties correlate more with higher quality, which was judged by human tasters, and thus this also lets us know what properties are aligned with people’s preferences. This is ideal as it opens us up for correlation analysis and multiple linear regression analysis.

Figure 2: Region in Portugal where the wines come from (Credit: Wikipedia.org)

We used the following packages for our overall analysis:

# Code Author: Hammad Rana

# # Uncomment to install packages (if necessary)
# install.packages("DT")
# install.packages("tidyverse")
# install.packages("patchwork")
# install.packages("ggrepel")
# install.packages("scales")
# install.packages("ggthemes")
# install.packages("ggridges")
# install.packages("knitr")
# install.packages("tinytex")

library(DT)
library(tinytex)
library(knitr)


# Code Author: Collin Stephens 

library(tidyverse)  
library(patchwork)  
library(ggrepel)   
library(scales)    
library(ggthemes)  
library(ggridges)


wine <- read.csv("winequality-red.csv", sep = ';')


Our significance level whenever mentioned is \[\alpha = 0.05,\] any p-value less than that is below the threshold for statistical significance. Any p-value equal to or more than that is above the threshold.


Goals

  • Assess the relationship between physicochemical properties and red wine quality.

  • Delineate which chemical factors have the strongest positive and negative relationships with wine quality.

  • Utilize data visualization techniques to better understand trends, patterns, and potential outliers in the dataset.

  • Apply target analysis, two-dimensional analysis, three-dimensional analysis, and outlier analysis on wine quality.

  • Make use of data wrangling and transformation methods using R and the tidyverse package.

  • Formulate statistical models to help better understand the factors associated with higher wine quality.

  • Establish and convey findings concisely and clearly through visualizations, tables, and written interpretations.


Variables

# Code Author: Hammad Rana

library(DT)

datatable(wine,
          caption = "Table 1: Wine Quality Dataset Variables")

All of our variables are continuous numerical variables with the exception of quality which is an ordinal variable as it is scored from 1 to 10, and the quality of the wine is gauged by human taster preferences and the idealness of wine characteristics, as seen in the following table:


# Code Author: Hammad Rana

library(DT)

wine_variables <- data.frame(
  Variable = c(
    "Fixed acidity",
    "Volatile acidity",
    "Citric acid",
    "Residual sugar",
    "Chlorides",
    "Free sulfur dioxide",
    "Total sulfur dioxide",
    "Density",
    "pH",
    "Sulphates",
    "Alcohol (ABV)"
  ),
  
  Description = c(
    "Stable/fixed acids in the wine that give a basic tart/sour taste (malic, citric, tartaric acids).",
    "Readily evaporating acids that can give a vinegar-like taste (e.g., acetic acid). Too much exposure to air can turn wine vinegary.",
    "Adds freshness and brightness; gives slight lemon/lime-like flavor.",
    "Sugar left after fermentation; contributes to sweetness. Not all of the sugar was fermented, perhaps, or added/excess sugar in the fermentation process.",
    "Salt content; higher levels may indicate poorer quality and can taste slightly salty or heavy. Can signify grape/water quality.",
    "Active preservative; protects wine but can cause off-putting smells (e.g., harsh burnt matchstick) if too high. Too little can impact wine's quality over time. ",
    "Total amount of sulfur dioxide (both active and inactive forms, inactive is bound up with other chemicals).",
    "Related to sugar and alcohol levels (more sugar = higher density, more alcohol = lower density).",
    "Measures acidity (lower pH = more acidic, higher pH = less acidic).",
    "Mineral salts that can improve crispness in moderation but taste harsh in excess.",
    "Alcohol percentage (ABV); affects warmth, body, intensity, and overall flavor perception. Wines past 16% ABV can taster fuller bodied and oddly sweeter. "
  )
)

datatable(wine_variables,
          caption = "Table 2: Wine Quality Dataset Variable Information")

As we can see there’s a lot of factors that go into a wine’s chemical makeup, and some of these factors clearly will play a role in the perceived quality of the wine. Note, that alcohol level and ABV will be used interchangeably throughout this presentation.


Target Analysis

# Code Author: Hammad Rana

library(tidyverse)

ggplot(wine, aes(x = quality)) +
  geom_bar(fill = "darkred", color = "black") +
  labs(
    title = "Distribution of Wine Quality Scores",
    x = "Wine Quality Score",
    y = "Count"
  ) +
  theme_classic()

Figure 3: Distribution of Wine Quality Scores
# Code Author: Hammad Rana

library(tidyverse)
library(knitr)

wine_summary <- wine |>
  summarize(
    Mean = round(mean(quality), 2),
    Median = median(quality),
    Minimum = min(quality),
    Maximum = max(quality)
  )

wine_summary |>
  kable(
    caption = "Table 3A: Summary Statistics of Wine Quality Scores"
  )
Table 3A: Summary Statistics of Wine Quality Scores
Mean Median Minimum Maximum
5.64 6 3 8
wine |>
  count(quality) |>
  kable(
    caption = "Table 3B: Count of Wine Quality Scores"
  )
Table 3B: Count of Wine Quality Scores
quality n
3 10
4 53
5 681
6 638
7 199
8 18


So we can see that on a scale from 1-10, most wines are around the 5-6 mark, which is average to slightly above average, so this indicates that most of the wines in this data were not rated too lowly, but not particularly high either, which is expected. Most of the things that make a wine good are fairly nuanced between different wines. No wines got any incredibly high or low rating, and they all fell within the 3-8 range.

Correlation Analysis

We did a basic correlation analysis to see how each variable individually correlates with quality. This is a global analysis, but it does give us some sense of what is happening with the data on a smaller scale through a pairwise metric.

# Code Author: Collin Stephens

library(tidyverse)
library(knitr)
library(patchwork)
library(scales)
library(ggthemes)
library(ggridges)
library(ggrepel)

quality_corr <- function(df) {
  results <- data.frame(
    variable = character(),
    correlation = numeric(),
    p_value = numeric()
  )
  
  for (col in names(df)) {
    if (col != "quality") {
      test <- cor.test(df[[col]], df$quality)
      
      results <- rbind(results, data.frame(
        variable = col,
        correlation = test$estimate,
        p_value = test$p.value
      ))
    }
  }
  
  return(results)
}

corr_results <- quality_corr(wine)

Correlation Table

# Code Author: Hammad Rana

corr_table <- data.frame(
  Variable = c(
    "Fixed Acidity", "Volatile Acidity", "Citric Acid", "Residual Sugar",
    "Chlorides", "Free Sulfur Dioxide", "Total Sulfur Dioxide", "Density",
    "pH", "Sulphates", "Alcohol"
  ),
  Correlation = c(
    0.12405165, -0.39055778, 0.22637251, 0.01373164, -0.12890656,
    -0.05065606, -0.18510029, -0.17491923, -0.05773139, 0.25139708,
    0.47616632
  ),
  P_Value = c(
    "6.50 × 10^-7",
    "2.05 × 10^-59",
    "4.99 × 10^-20",
    "0.583",
    "2.31 × 10^-7",
    "0.043",
    "8.62 × 10^-14",
    "1.87 × 10^-12",
    "0.021",
    "1.80 × 10^-24",
    "2.83 × 10^-91"
  )
)

kable(
  corr_table,
  caption = "Correlation of Wine Variables with Quality"
)
Correlation of Wine Variables with Quality
Variable Correlation P_Value
Fixed Acidity 0.1240516 6.50 × 10^-7
Volatile Acidity -0.3905578 2.05 × 10^-59
Citric Acid 0.2263725 4.99 × 10^-20
Residual Sugar 0.0137316 0.583
Chlorides -0.1289066 2.31 × 10^-7
Free Sulfur Dioxide -0.0506561 0.043
Total Sulfur Dioxide -0.1851003 8.62 × 10^-14
Density -0.1749192 1.87 × 10^-12
pH -0.0577314 0.021
Sulphates 0.2513971 1.80 × 10^-24
Alcohol 0.4761663 2.83 × 10^-91

One thing that is clear is that alcohol (ABV) is strongly associated with higher quality, with a correlation coefficient of 0.48 and a very significant p-value close to zero \((2.83 \times 10^{-91} \approx 0 \ll 0.05)\); the most statistically significant result. This makes sense as higher alcohol can increase body, flavor intensity, and perceived richness in wine.

Correlation Visualization

# Code Author: Collin Stephens

high_text <- "Alcohol has the strongest positive correlation with quality" |>
  str_wrap(width = 30)

low_text <- "Volatile Acidity has the strongest negative correlation with quality" |>
  str_wrap(width = 30)

corr <- ggplot(
  corr_results,
  aes(
    x = reorder(variable, correlation),
    y = correlation,
    fill = correlation
  )
) +
  geom_bar(stat = "identity", color = "black") +
  scale_fill_gradient2(
    low = "#D55E00",
    mid = "white",
    high = "#0072B2"
  ) +
  annotate(
    geom = "label",
    x = 8,
    y = 0.425,
    label = high_text
  ) +
  annotate(
    geom = "segment",
    x = 8,
    y = 0.365,
    xend = 10.55,
    yend = 0.3,
    arrow = arrow(type = "closed")
  ) +
  annotate(
    geom = "label",
    x = 3,
    y = 0.2,
    label = low_text
  ) +
  annotate(
    geom = "segment",
    x = 3,
    y = 0.14,
    xend = 1.2,
    yend = 0.01,
    arrow = arrow(type = "closed")
  ) +
  scale_x_discrete(labels = c(
    "volatile.acidity" = "Volatile Acidity",
    "total.sulfur.dioxide" = "Total Sulfur Dioxide",
    "free.sulfur.dioxide" = "Free Sulfur Dioxide",
    "fixed.acidity" = "Fixed Acidity",
    "citric.acid" = "Citric Acid",
    "residual.sugar" = "Residual Sugar",
    "chlorides" = "Chlorides",
    "density" = "Density",
    "pH" = "pH",
    "sulphates" = "Sulphates",
    "alcohol" = "Alcohol"
  )) +
  labs(
    title = "Correlation Between Chemical Properties and Wine Quality",
    x = "Chemical Properties",
    y = "Correlation with Quality",
    fill = "Correlation"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

corr

Correlation Between Chemical Properties and Wine Quality

Now, there is a limit to how much alcohol is good for the wine, and we can assess this later, but for now, it is clear there is a trend towards higher alcohol content correlating with higher quality wine, which signifies more sugar around for fermentation and greater efficiency for the yeast converting that sugar into alcohol. So out of curiosity, we ran a basic plot for a quick check:

Residual Sugar and Alcohol Check

# Code Author: Hammad Rana

ggplot(wine, aes(x = residual.sugar, y = alcohol)) +
  geom_point(alpha = 0.3, color = "black") +               
  geom_smooth(method = "lm", color = "#8B0000", size = 1.2) + 
  labs(
    x = "Residual Sugar (g/L)",
    y = "Alcohol (%)",
    title = "Relationship Between Residual Sugar and Alcohol Content"
  ) +
  theme_minimal()

Relationship Between Residual Sugar and Alcohol Content

So as we can see, most of the wines regardless of their ABV have fairly low amounts of residual sugar, which are honestly normal for wines anyways, and it just means that a lot of high alcohol wines can be fairly dry (term for less sweet alcohol) in actuality. But now we can go back to the question: what level of ABV specifically is most associated with the most quality?

Mean Quality by Chemical Level

Alcohol Level

# Code Author: Collin Stephens

alcohol_level <- wine |>
  mutate(alcohol_level = 
           case_when(
             alcohol < 10 ~ "Low",
             alcohol < 12 ~ "Medium",
             TRUE ~ "High"
           )
  )

alcohol_summary <- alcohol_level |>
  group_by(alcohol_level) |>
  summarise(mean_quality = mean(quality))

alcohol <- ggplot(alcohol_summary, aes(x = reorder(alcohol_level, mean_quality), 
                                       y = mean_quality, 
                                       fill = alcohol_level)) +
  geom_bar(stat = "identity") +
  scale_fill_brewer(palette = "RdPu") +
  labs(
    x = "Alcohol Level",
    y = "Mean Quality Score",
    fill = "Alcohol Level"
  ) +
  theme_classic()

alcohol

Mean Wine Quality by Alcohol Level

So we can see that, for sure, higher alcohol level is associated with higher mean quality score. Therefore, we can reasonably conclude based on the descriptive visualizations and the statistically significant values, ABV is the top contender for a factor associated with the quality of the red wine.

Volatile Acidity Level

# Code Author: Collin Stephens

volatile_acid <- wine |>
  mutate(
    acid_level = case_when(
      volatile.acidity < 0.4 ~ "Low",
      volatile.acidity < 0.7 ~ "Medium",
      TRUE ~ "High"
    )
  )

volatile_acid_level <- volatile_acid |>
  group_by(acid_level) |>
  summarise(mean_quality = mean(quality))

v_acid <- ggplot(volatile_acid_level, aes(x = reorder(acid_level, -mean_quality), 
                                          y = mean_quality, fill = mean_quality)) +
  geom_bar(stat = "identity") +
  labs(
    x = "Volatile Acidity Level",
    y = "Mean Quality Score",
    fill = "Mean Quality Score"
  ) +
  theme_classic()

v_acid

Mean Wine Quality by Volatile Acidity Level

Volatile acid has a negative association with mean quality score.

Sulphates Level

# Code Author: Collin Stephens

sulphate_groups <- wine |>
  mutate(
    sulphate_level = case_when(
      sulphates < 0.5 ~ "Low",
      sulphates < 0.8 ~ "Medium",
      TRUE ~ "High"
    )
  )

sulphate_level <- sulphate_groups |>
  group_by(sulphate_level) |>
  summarise(mean_quality = mean(quality))

sulphates <- ggplot(sulphate_level, aes(x = reorder(sulphate_level, mean_quality),
                                        y = mean_quality, fill = mean_quality)) +
  geom_bar(stat = "identity") +
  labs(
    x = "Sulphates Level",
    y = "Mean Quality Score",
    fill = "Mean Quality Score"
  ) +
  theme_classic()

sulphates

Mean Wine Quality by Sulphates Level

Higher sulphates correlate more with a higher mean quality score.

Total Sulfur Dioxide Level

# Code Author: Collin Stephens

sulfur_groups <- wine |>
  mutate(
    sulfur_level = case_when(
      total.sulfur.dioxide < 50 ~ "Low",
      total.sulfur.dioxide < 100 ~ "Medium",
      TRUE ~ "High"
    )
  )

sulfur_levels <- sulfur_groups |>
  group_by(sulfur_level) |>
  summarise(mean_quality = mean(quality))

sulfur <- ggplot(sulfur_levels, aes(x = reorder(sulfur_level, -mean_quality),
                                    y = mean_quality, fill = mean_quality)) +
  geom_bar(stat = "identity") +
  labs(
    x = "Total Sulfur Dioxide",
    y = "Mean Quality Score",
    fill = "Mean Quality Score"
  ) +
  theme_classic()

sulfur

Mean Wine Quality by Total Sulfur Dioxide Level

We can see here that higher sulfur dioxide associates with a lower mean quality score.

Combined Mean Quality Bar Charts

# Code Author: Collin Stephens

bars <- (alcohol + sulphates) / (v_acid + sulfur) +
  plot_annotation("Effect of Key Chemical Properties on Wine Quality")

bars

Effect of Key Chemical Properties on Wine Quality

Here are all the figures put together for a better view.

Pairwise Chemical Variable Analysis

# Code Author: Collin Stephens

alc_sulph <- ggplot(wine, aes(x = alcohol, y = sulphates)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Alcohol vs Sulphates",
    x = "Alcohol",
    y = "Sulphates",
    color = "Quality"
  ) +
  theme_classic() +
  theme(legend.position = "none")

alc_vol <- ggplot(wine, aes(x = alcohol, y = volatile.acidity)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Alcohol vs Volatile Acidity",
    x = "Alcohol",
    y = "Volatile Acidity",
    color ="Quality"
  ) +
  theme_classic() + 
  theme(legend.position = "none")

sulph_vol <- ggplot(wine, aes(x = sulphates, y = volatile.acidity)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Sulphates vs Volatile Acidity",
    x = "Sulphates",
    y = "Volatile Acidity",
    color = "Quality"
  ) +
  theme_classic() +
  theme(legend.position = "none")

alc_sulfdio <- ggplot(wine, aes(x = alcohol, y = total.sulfur.dioxide)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Alcohol vs Total Sulfur Dioxide",
    x = "Alcohol",
    y = "Total Sulfur Dioxide",
    color = "Quality"
  ) +
  theme_classic() +
  theme(legend.position = "none")

sulph_sulfdio <- ggplot(wine, aes(x = sulphates, y = total.sulfur.dioxide)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Sulphates vs Total Sulfur Dioxide",
    x = "Sulphates",
    y = "Total Sulfur Dioxide",
    color = "Quality"
  ) +
  theme_classic() +
  theme(legend.position = "none")

vol_sulphdio <- ggplot(wine, aes(x = volatile.acidity, y = total.sulfur.dioxide)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Volatile Acidity vs Total Sulfur Dioxide",
    x = "Volatile Acidity",
    y = "Total Sulfur Dioxide",
    color = "Quality"
  ) +
  theme_classic()

corr_matrix <- (alc_sulph + alc_vol) /
  (sulph_vol + sulph_sulfdio) /
  (alc_sulfdio + vol_sulphdio) +
  plot_annotation(title = "Pairwise Relationships Between Key Chemical Properties")

corr_matrix

Pairwise Relationships Between Key Chemical Properties

Alcohol and sulphates show slight positive relationships, while volatile acidity tends to decrease as alcohol and sulphates increase. Relationships involving total sulfur dioxide are weaker overall.

Two-Way & Outlier Analysis

# Code Author: Hammad Rana & Collin Stephens

library(tidyverse)
library(patchwork)

wine_l <- wine |>
  pivot_longer(
    cols = c(alcohol, sulphates, volatile.acidity),
    names_to = "variable",
    values_to = "value"
  )

p1 <- ggplot(wine_l, aes(x = value, y = quality)) +
  geom_point(alpha = 0.4, color = "darkred") +
  geom_smooth(method = "lm", color = "red") +
  facet_wrap(~ variable, scales = "free_x") +
  labs(
    title = "Wine Quality Compared to Key Chemical Variables",
    x = "Variable Value",
    y = "Wine Quality"
  ) +
  theme_classic()

p2 <- ggplot(wine, aes(x = alcohol, y = sulphates)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Alcohol vs Sulphates",
    x = "Alcohol",
    y = "Sulphates",
    color = "Quality"
  ) +
  theme_classic()

p3 <- ggplot(wine, aes(x = sulphates, y = volatile.acidity)) +
  geom_point(alpha = 0.3, aes(color = factor(quality))) +
  geom_smooth(method = "lm") +
  labs(
    title = "Sulphates vs Volatile Acidity",
    x = "Sulphates",
    y = "Volatile Acidity",
    color = "Quality"
  ) +
  theme_classic()

p1 / (p2 | p3)

Figure 4: Two-Dimensional Analysis of Key Chemical Variables and Wine Quality

Alcohol and sulphates show positive relationships with wine quality, meaning higher values are generally associated with better wines; more alcohol means a fuller bodied and more flavorful wine. Higher sulphate association with higher quality indicates a better degree of quality control when it comes to adding sulfur dioxide components towards the end of the wine making process to maintain freshness; in contrast, high amounts of naturally occurring sulfur dioxides could be a sign of bad batch control.

Volatile acidity shows the strongest negative relationship, indicating that higher less stable acidity (like vinegar) is associated with lower quality wines, which makes sense as that signifies the wine has been exposed to more air and/or has gone more stale (or the fermentation process was too inefficient or not controlled for temperature and humidity/sanitation).

Factors such as chlorides, density, and total sulfur dioxide also show slight negative relationships; whereas, residual sugar shows little to no relationship with quality.

Overall, alcohol appears to be the strongest positive predictor of wine quality; whereas, volatile acidity appears to be the strongest negative predictor.


# Code Author: Colin Breault

wine_2 <- wine |>
  pivot_longer(
    cols = c(alcohol, sulphates, volatile.acidity),
    names_to = "variable",
    values_to = "value"
  )

outliers <- wine_2 |>
  group_by(variable, quality) |>
  filter(
    value < quantile(value, 0.25) - 1.5 * IQR(value) |
    value > quantile(value, 0.75) + 1.5 * IQR(value)
  )

ggplot(
  wine_2,
  aes(x = factor(quality), y = value, fill = factor(quality))
) +
  geom_boxplot() +
  geom_point(
    data = outliers,
    color = "red",
    shape = 8,
    size = 2
  ) +
  facet_wrap(~ variable, scales = "free_y") +
  labs(
    title = "Chemical Variables Across Wine Quality Scores",
    x = "Wine Quality",
    y = "Variable Value",
    fill = "Quality"
  ) +
  theme_classic()

Figure 6: Outlier Analysis of Key Chemical Variables Across Wine Quality Scores

Alcohol shows the most obvious positive trend. Wines rated 7 and 8 generally have higher median alcohol levels than wines rated 3 through 5, further pushing the idea that stronger alcohol content is associated with higher quality wines.

Sulphates show a an intermediate positive trend. Wines with higher quality scores generally have slightly higher median sulphate levels, implying that increased sulphates are associated with better preserved and more balanced wines.

Volatile acidity shows a clear negative trend. Wines rated 3 through 5 tend to have higher median volatile acidity levels, while wines rated 7 and 8 have much lower acidity levels, implying that higher volatile acidity is associated with lower quality wines.

The outliers signify real life variance and batch production, so we figured that it was best to use these outliers in our analysis because wine production can be quite variable from season to season, and that can have a profound effect on wine chemistry, especially with acidity and sulphate count. Bad batches happen often too.

Multiple Regression Analysis


# Code Author: Colin Breault

multiple_linear_regression <- lm(quality ~ ., data = wine)

# Code Author: Hammad Rana

summary_lm <- summary(multiple_linear_regression)

regression_table <- data.frame(
  Variable = rownames(summary_lm$coefficients),
  Estimate = summary_lm$coefficients[, "Estimate"],
  Std_Error = summary_lm$coefficients[, "Std. Error"],
  t_value = summary_lm$coefficients[, "t value"],
  P_Value = c(
    "0.3002",        
    "0.3357",         
    "8.95 × 10^-16",  
    "0.2150",         
    "0.2765",         
    "8.37 × 10^-6",   
    "0.0447",         
    "8.00 × 10^-6",   
    "0.4086",         
    "0.0310",         
    "2.13 × 10^-15",
    "2 × 10^-16"      
  )
)

regression_table_2 <- regression_table
regression_table_2$Estimate <- round(regression_table$Estimate, 3)
regression_table_2$Std_Error <- round(regression_table$Std_Error, 3)
regression_table_2$t_value <- round(regression_table$t_value, 3)

library(DT)
datatable(
  regression_table_2,
  caption = "Table: Multiple Linear Regression Summary Predicting Wine Quality"
)

Alcohol, sulphates, volatile acidity, chlorides, and sulfur dioxide, have statistically significant p-values below 0.05, meaning their relationships with wine quality are quite meaningful. Alcohol had the largest positive contribution, suggesting that wines with higher alcohol content generally received higher quality ratings. On the other hand, higher volatile acidity and chlorides were associated with lower wine quality.

The regression analysis shows the same major trends seen throughout the project: higher-quality wines tend to have higher alcohol and sulphate levels and lower volatile acidity levels.

Interactive Plots

# Code Author: Hammad Rana

library(plotly)

interaction_alcohol <- ggplot(wine, aes(x = alcohol, y = quality)) +
  geom_point(alpha = 0.5, color = "darkred") +
  geom_smooth(method = "lm", color = "red") +
  labs(
    title = "Interaction Plot: Alcohol vs Wine Quality",
    x = "Alcohol",
    y = "Wine Quality"
  ) +
  theme_classic()

ggplotly(interaction_alcohol)
# Code Author: Hammad Rana

library(plotly)

interaction_sulphates <- ggplot(wine, aes(x = sulphates, y = quality)) +
  geom_point(alpha = 0.5, color = "darkred") +
  geom_smooth(method = "lm", color = "red") +
  labs(
    title = "Interaction Plot: Sulphates vs Wine Quality",
    x = "Sulphates",
    y = "Wine Quality"
  ) +
  theme_classic()

ggplotly(interaction_sulphates)

Summary

Our analysis demonstrated that alcohol had the strongest positive relationship with wine quality, while volatile acidity had the strongest negative relationship. Higher quality wines generally contained higher alcohol and sulphate levels and lower volatile acidity levels. Correlation analysis, grouped visualizations, and scatterplots consistently subsantiated these trends. Outlier analysis also showed batch variation. Overall, alcohol, sulphates, and volatile acidity were the most important variables associated with red wine quality in this dataset.

Contributions

Throughout each of the code chunks, the author who wrote that portion of the code was commented above their respective lines of code. This credits everyone appropriately. However, to summarize broadly: Hammad Rana selected the dataset, outlined the plan of attack, set up the Quatro document and website as well as many of the interpretations of the code output, Collin Stephens worked on the correlation analysis and plots as well as mutating and sorting the data out, and Colin Breault set up the linear model analysis. This doesn’t mean some people did not interchange their roles here and there, but this is the general overview of how the project was put together.

References

Quarto Team. Quarto. Posit, https://quarto.org/.

R Core Team. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, https://www.R-project.org/.

Neuwirth, Erich. RColorBrewer: ColorBrewer Palettes. R package version 1.1-3, 2022, https://cran.r-project.org/web/packages/RColorBrewer/index.html.

Cortez, Paulo, et al. “Modeling Wine Preferences by Data Mining from Physicochemical Properties.” Decision Support Systems, vol. 47, no. 4, 2009, pp. 547–553. ScienceDirect, https://www.sciencedirect.com/science/article/abs/pii/S0167923609001377.

UC Irvine Machine Learning Repository. Wine Quality Data Set, 2009, https://archive.ics.uci.edu/dataset/186/wine+quality.

UCIML. Red Wine Quality (Cortez et al., 2009), Kaggle, https://www.kaggle.com/datasets/uciml/red-wine-quality-cortez-et-al-2009.

Contact

  • Hammad Rana - hrana6@students.kennesaw.edu

  • Collin Stephens - cstep141@students.kennesaw.edu

  • Colin Breault - cbreault@students.kennesaw.edu