Exploratory Data Analysis of Chocolate Data set

Introduction

Chocolate is something that almost everyone loves, whether it’s a fancy, high-end chocolate bar or a simple store-bought treat! But what makes it so enjoyable—when there’s so much chocolate to choose from, how do you really know which ones are the best?

To find out, I took a deep dive into a data set that breaks down ratings for different chocolate bars from all sorts of makers and regions. This data includes the basics like the bar’s name, who made it, where the cocoa beans came from, and even the cocoa percentage. The most interesting part of the data is the chocolate’s ratings! When choosing this data set I believed these scores could give us a good idea of what people think about the quality of various chocolate bars, and they can reveal trends and preferences among chocolate-eaters!

By analyzing this information, I’m hoping to uncover some useful insights into the chocolate industry. What makes a chocolate bar top-notch? What do people really want when they buy chocolate? The answers to these questions could be super helpful for chocolate makers, sellers, and anyone who’s just really into chocolate. With this data, I aim to shed light on what makes certain chocolate bars so popular and what factors play a role in their quality.

Data Preparation

In this section I go through how I prepared my data before analyzing it. First, I ensured that I had installed the required libraries. Then, I loaded them into my R environment.

# Load necessary libraries
library(tidyverse)  # Includes ggplot2, dplyr, and more
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.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(ggthemes)   # Additional ggplot themes
library(lubridate)  # For date manipulation

Next, I imported the chocolate data set from its location.

# Import the chocolate dataset
chocolate <- read.csv("~/Desktop/chocolate.csv")

To understand the data, I ran the following to examine the data set’s structure, including variable types and summary statistics.

# Get a summary of the dataset
summary(chocolate)
##       ref       company_manufacturer company_location    review_date  
##  Min.   :   5   Length:2530          Length:2530        Min.   :2006  
##  1st Qu.: 802   Class :character     Class :character   1st Qu.:2012  
##  Median :1454   Mode  :character     Mode  :character   Median :2015  
##  Mean   :1430                                           Mean   :2014  
##  3rd Qu.:2079                                           3rd Qu.:2018  
##  Max.   :2712                                           Max.   :2021  
##  country_of_bean_origin specific_bean_origin_or_bar_name cocoa_percent   
##  Length:2530            Length:2530                      Min.   :0.4200  
##  Class :character       Class :character                 1st Qu.:0.7000  
##  Mode  :character       Mode  :character                 Median :0.7000  
##                                                          Mean   :0.7164  
##                                                          3rd Qu.:0.7400  
##                                                          Max.   :1.0000  
##  ingredients        most_memorable_characteristics     rating     
##  Length:2530        Length:2530                    Min.   :1.000  
##  Class :character   Class :character               1st Qu.:3.000  
##  Mode  :character   Mode  :character               Median :3.250  
##                                                    Mean   :3.196  
##                                                    3rd Qu.:3.500  
##                                                    Max.   :4.000
# Check the first few rows of the dataset
head(chocolate)
##    ref company_manufacturer company_location review_date country_of_bean_origin
## 1 2454                 5150           U.S.A.        2019               Tanzania
## 2 2458                 5150           U.S.A.        2019     Dominican Republic
## 3 2454                 5150           U.S.A.        2019             Madagascar
## 4 2542                 5150           U.S.A.        2021                   Fiji
## 5 2546                 5150           U.S.A.        2021              Venezuela
## 6 2546                 5150           U.S.A.        2021                 Uganda
##   specific_bean_origin_or_bar_name cocoa_percent ingredients
## 1            Kokoa Kamili, batch 1          0.76    3- B,S,C
## 2                  Zorzal, batch 1          0.76    3- B,S,C
## 3           Bejofo Estate, batch 1          0.76    3- B,S,C
## 4            Matasawalevu, batch 1          0.68    3- B,S,C
## 5            Sur del Lago, batch 1          0.72    3- B,S,C
## 6         Semuliki Forest, batch 1          0.80    3- B,S,C
##      most_memorable_characteristics rating
## 1         rich cocoa, fatty, bready   3.25
## 2            cocoa, vegetal, savory   3.50
## 3      cocoa, blackberry, full body   3.75
## 4               chewy, off, rubbery   3.00
## 5 fatty, earthy, moss, nutty,chalky   3.00
## 6 mildly bitter, basic cocoa, fatty   3.25
# Explore the variable types
str(chocolate)
## 'data.frame':    2530 obs. of  10 variables:
##  $ ref                             : int  2454 2458 2454 2542 2546 2546 2542 797 797 1011 ...
##  $ company_manufacturer            : chr  "5150" "5150" "5150" "5150" ...
##  $ company_location                : chr  "U.S.A." "U.S.A." "U.S.A." "U.S.A." ...
##  $ review_date                     : int  2019 2019 2019 2021 2021 2021 2021 2012 2012 2013 ...
##  $ country_of_bean_origin          : chr  "Tanzania" "Dominican Republic" "Madagascar" "Fiji" ...
##  $ specific_bean_origin_or_bar_name: chr  "Kokoa Kamili, batch 1" "Zorzal, batch 1" "Bejofo Estate, batch 1" "Matasawalevu, batch 1" ...
##  $ cocoa_percent                   : num  0.76 0.76 0.76 0.68 0.72 0.8 0.68 0.7 0.63 0.7 ...
##  $ ingredients                     : chr  "3- B,S,C" "3- B,S,C" "3- B,S,C" "3- B,S,C" ...
##  $ most_memorable_characteristics  : chr  "rich cocoa, fatty, bready" "cocoa, vegetal, savory" "cocoa, blackberry, full body" "chewy, off, rubbery" ...
##  $ rating                          : num  3.25 3.5 3.75 3 3 3.25 3.5 3.5 3.75 2.75 ...

Exploratory Data Analysis (EDA)

In this section, I took a deep dive into the data set to break down what really affected the ratings using tools and methods I have learned from this semester in Statistics for Data Science. Taking a look at the summary of the data set, it seemed more worthy to look at how the percentage of cocoa (cocoa_percent) affects rating, and along the same lines how where the cocoa bean originates from (country_of_bean_origin) affects the chocolate’s rating. In this section I did the following:

1. Cocoa Percentage and Rating

  • Explored the relationship between cocoa percentage and chocolate ratings.

  • Analyzed any correlations or trends.

2. Country of Bean Origin Analysis

  • Explored the distribution of chocolate’s rating by country of bean origin.

  • Analyzed if there are any differences in ratings based on bean origin.

1. Cocoa Percentage and Rating

Descriptive Analyses

To start my analysis I decided to summarize the key statistics for the variables of interest (rating and cocoa_percent) from my chocolate data set. This provided me a high-level view of the data’s distribution.

# Summarized statistics for key variables
summary(chocolate)
##       ref       company_manufacturer company_location    review_date  
##  Min.   :   5   Length:2530          Length:2530        Min.   :2006  
##  1st Qu.: 802   Class :character     Class :character   1st Qu.:2012  
##  Median :1454   Mode  :character     Mode  :character   Median :2015  
##  Mean   :1430                                           Mean   :2014  
##  3rd Qu.:2079                                           3rd Qu.:2018  
##  Max.   :2712                                           Max.   :2021  
##  country_of_bean_origin specific_bean_origin_or_bar_name cocoa_percent   
##  Length:2530            Length:2530                      Min.   :0.4200  
##  Class :character       Class :character                 1st Qu.:0.7000  
##  Mode  :character       Mode  :character                 Median :0.7000  
##                                                          Mean   :0.7164  
##                                                          3rd Qu.:0.7400  
##                                                          Max.   :1.0000  
##  ingredients        most_memorable_characteristics     rating     
##  Length:2530        Length:2530                    Min.   :1.000  
##  Class :character   Class :character               1st Qu.:3.000  
##  Mode  :character   Mode  :character               Median :3.250  
##                                                    Mean   :3.196  
##                                                    3rd Qu.:3.500  
##                                                    Max.   :4.000
# Descriptive statistics for 'rating' and 'cocoa_percent'
chocolate |>
  summarize(
    min_rating = min(rating, na.rm = TRUE),
    max_rating = max(rating, na.rm = TRUE),
    mean_rating = mean(rating, na.rm = TRUE),
    min_cocoa = min(cocoa_percent, na.rm = TRUE),
    max_cocoa = max(cocoa_percent, na.rm = TRUE),
    mean_cocoa = mean(cocoa_percent, na.rm = TRUE)
  )
##   min_rating max_rating mean_rating min_cocoa max_cocoa mean_cocoa
## 1          1          4    3.196344      0.42         1  0.7163972

From this I was able to find that the lowest chocolate rating was 1, the highest was a 4, and the average rating was a 3.2. The lowest percentage of cocoa found in the chocolates was 42%, the highest being 100%, and the highest being around 71.6%.

Created Visualizations

Next, I decided to create visualizations to help identify relationships and patterns within these two variables (rating and cocoa_percent).

Histogram

Histograms show the distribution of a single variable, helping to identify its central tendency and dispersion. Here I decided to create a histogram for the two variables, cocoa_percent and rating.

# Histogram for 'rating'
ggplot(chocolate, aes(x = rating)) +
  geom_histogram(bins = 10, fill = "blue", color = "black") +
  labs(x = "Rating", y = "Count", title = "Distribution of Chocolate Ratings")

# Histogram for 'cocoa_percent'
ggplot(chocolate, aes(x = cocoa_percent)) +
  geom_histogram(bins = 10, fill = "green", color = "black") +
  labs(x = "Cocoa Percentage", y = "Count", title = "Distribution of Cocoa Percentage")

The cocoa_percent histogram did indicate more chocolates lingering around the 70% cocoa mark. The rating’s histogram did display that there was more instances of ratings around the 3.2 mark.

Box-plots

Box-plots are useful for visualizing the distribution of a variable, highlighting the median, quartiles, and potential outliers, I decided to create visualizations for both my variables.

# Boxplot for 'rating'
ggplot(chocolate, aes(x = 1, y = rating)) +
  geom_boxplot(fill = "blue") +
  labs(x = "", y = "Rating", title = "Boxplot of Chocolate Ratings")

# Boxplot for 'cocoa_percent'
ggplot(chocolate, aes(x = 1, y = cocoa_percent)) +
  geom_boxplot(fill = "green") +
  labs(x = "", y = "Cocoa Percentage", title = "Boxplot of Cocoa Percentage")

The chocolate’s rating box plot displayed that 50% of the data was around the 3-3.5 rating mark which is great, we have some great chocolate to look at! The cocoa percent box plot displayed the median mark being closer if not right on the bottom of the box, indicating skewness. This generally indicates that the data distribution is skewed towards the higher end, or what is known as right-skewed distribution. This happens when there are more extreme values on the higher end of the data range. In the case of my data set I took this as there are far more chocolates that have higher percentages of cocoa versus lighter amounts of cocoa.

Scatter Plots

Scatter plots are useful for exploring relationships between two numeric variables, in my case this allowed me to identify potential correlations between rating and cocoa_percent.

# Scatter plot of 'cocoa_percent' vs 'rating'
ggplot(chocolate, aes(x = cocoa_percent, y = rating)) +
  geom_point(color = "red", alpha = 0.5) +
  labs(x = "Cocoa Percentage", y = "Rating", title = "Scatter Plot: Cocoa Percentage vs Rating")

From this scatter-plot, I was able to note that the 4 star rating chocolates had a sweet spot of a cocoa percentage between 60-80%. This provides chocolate manufacturers insight into potentially ranges of cocoa they should take into consideration before launching their next products!

Correlation

Correlation analysis can help determine if there’s a relationship between two variables, which I decided to do in order to check if this could be a potential point into what makes chocolates so good!

# Correlation between 'rating' and 'cocoa_percent'
cor(chocolate$rating, chocolate$cocoa_percent, use = "complete.obs")
## [1] -0.1466896

The correlation of -0.1466896 between ‘rating’ and ‘cocoa_percent’ suggested a weak negative correlation between the two variables. In my data, this suggested:

  • The correlation is relatively weak, indicating that cocoa percentage might not be a strong predictor of chocolate rating.

  • There’s a slight tendency for higher cocoa percentages to be associated with lower ratings, but it’s not a consistent or strong pattern.

Linear Regression Analysis

In this section I completed the following:

  • Fit a linear regression model to investigate the relationship between cocoa percentage and chocolate ratings.

  • Evaluated the model’s performance and interpreted the coefficients.

To conduct a linear regression analysis that investigates the relationship between cocoa percentage and chocolate ratings, I completed the following steps:

Fit a Linear Regression Model

# Fit a linear regression model with 'rating' as the response variable and 'cocoa_percent' as the predictor
lm_model <- lm(rating ~ cocoa_percent, data = chocolate)

Evaluated the Model’s Performance

# Get the summary of the model to understand its performance
summary(lm_model)
## 
## Call:
## lm(formula = rating ~ cocoa_percent, data = chocolate)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.21541 -0.23867  0.03459  0.28459  0.99393 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     4.0295     0.1121  35.949  < 2e-16 ***
## cocoa_percent  -1.1630     0.1560  -7.456 1.22e-13 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4406 on 2528 degrees of freedom
## Multiple R-squared:  0.02152,    Adjusted R-squared:  0.02113 
## F-statistic: 55.59 on 1 and 2528 DF,  p-value: 1.218e-13

The summary provided information about the coefficients, standard errors, R-squared, and p-values to evaluate the model’s performance and determine if there’s a significant relationship between ‘cocoa_percent’ and ‘rating’.

Interpret the Coefficients

These are the results from fitting a linear regression model with ‘rating’ as the response variable and ‘cocoa_percent’ as the predictor.

Coefficients

  • The intercept (4.0295) represented the expected ‘rating’ when ‘cocoa_percent’ is zero. In this case, this really has no true significance as a chocolate isn’t a chocolate without cocoa!

  • The coefficient for ‘cocoa_percent’ (-1.1630) indicated that for every 1% increase in ‘cocoa_percent’, the ‘rating’ was expected to decrease by approximately 1.16 units. This makes general sense because the more cocoa in a chocolate bar, the more bitter it is which may not appeal to the masses.

Interpretation

The negative coefficient for ‘cocoa_percent’ suggested that as the cocoa percentage increases, the chocolate rating tends to decrease. However, the low R-squared indicated that cocoa percentage alone does not explain much of the variation in chocolate ratings. Other variables, such as ingredients, country of origin, or company, could have a more significant impact, but for time sake I only focused on rating and country of bean origin.

2. Country of Bean Origin Analysis

Expanding the Linear Regression Model

From the linear model I was able to see that cocoa percent alone does not affect rating, so I decided to look into adding another factor to this linear model. I thought a good direction to head was to take into consideration where the cocoa is coming from could be another factor that affects the rating.

lm_model <- lm(rating ~ cocoa_percent + country_of_bean_origin, data = chocolate)
summary(lm_model)
## 
## Call:
## lm(formula = rating ~ cocoa_percent + country_of_bean_origin, 
##     data = chocolate)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.20453 -0.27198  0.02375  0.29172  1.15850 
## 
## Coefficients:
##                                              Estimate Std. Error t value
## (Intercept)                                  4.095518   0.275367  14.873
## cocoa_percent                               -1.225389   0.158316  -7.740
## country_of_bean_originBelize                 0.030795   0.257786   0.119
## country_of_bean_originBlend                 -0.175680   0.255234  -0.688
## country_of_bean_originBolivia               -0.037043   0.257501  -0.144
## country_of_bean_originBrazil                 0.042041   0.257616   0.163
## country_of_bean_originBurma                 -0.237746   0.505548  -0.470
## country_of_bean_originCameroon              -0.162582   0.357475  -0.455
## country_of_bean_originChina                  0.286762   0.505568   0.567
## country_of_bean_originColombia              -0.029445   0.257547  -0.114
## country_of_bean_originCongo                  0.086006   0.285176   0.302
## country_of_bean_originCosta Rica            -0.068060   0.261472  -0.260
## country_of_bean_originCuba                   0.107021   0.282735   0.379
## country_of_bean_originDominican Republic    -0.003332   0.254476  -0.013
## country_of_bean_originDR Congo              -0.262254   0.505548  -0.519
## country_of_bean_originEcuador               -0.033216   0.254588  -0.130
## country_of_bean_originEl Salvador           -0.217323   0.309611  -0.702
## country_of_bean_originFiji                  -0.143846   0.275511  -0.522
## country_of_bean_originGabon                  0.073523   0.505635   0.145
## country_of_bean_originGhana                 -0.090748   0.261877  -0.347
## country_of_bean_originGrenada               -0.219170   0.271998  -0.806
## country_of_bean_originGuatemala              0.039292   0.258848   0.152
## country_of_bean_originHaiti                  0.040766   0.265129   0.154
## country_of_bean_originHonduras               0.036075   0.267576   0.135
## country_of_bean_originIndia                 -0.078712   0.263385  -0.299
## country_of_bean_originIndonesia             -0.093999   0.271127  -0.347
## country_of_bean_originIvory Coast           -0.368349   0.302138  -1.219
## country_of_bean_originJamaica               -0.019917   0.268138  -0.074
## country_of_bean_originLiberia               -0.146244   0.357485  -0.409
## country_of_bean_originMadagascar             0.044365   0.254931   0.174
## country_of_bean_originMalaysia              -0.124084   0.296432  -0.419
## country_of_bean_originMartinique            -0.830855   0.507350  -1.638
## country_of_bean_originMexico                -0.053746   0.259600  -0.207
## country_of_bean_originNicaragua              0.034654   0.256565   0.135
## country_of_bean_originNigeria               -0.258169   0.357476  -0.722
## country_of_bean_originPanama                -0.100766   0.291919  -0.345
## country_of_bean_originPapua New Guinea       0.050587   0.260259   0.194
## country_of_bean_originPeru                  -0.028349   0.254341  -0.111
## country_of_bean_originPhilippines           -0.099726   0.268126  -0.372
## country_of_bean_originPrincipe              -0.401969   0.505704  -0.795
## country_of_bean_originPuerto Rico           -0.544467   0.302123  -1.802
## country_of_bean_originSamoa                 -0.003281   0.358097  -0.009
## country_of_bean_originSao Tome              -0.153188   0.278561  -0.550
## country_of_bean_originSao Tome & Principe    0.292889   0.399707   0.733
## country_of_bean_originSierra Leone          -0.475492   0.334402  -1.422
## country_of_bean_originSolomon Islands        0.234311   0.288239   0.813
## country_of_bean_originSri Lanka             -0.332111   0.399707  -0.831
## country_of_bean_originSt. Lucia             -0.264464   0.288242  -0.918
## country_of_bean_originSt.Vincent-Grenadines -0.463238   0.505568  -0.916
## country_of_bean_originSulawesi              -0.036762   0.505568  -0.073
## country_of_bean_originSumatra               -0.237746   0.505548  -0.470
## country_of_bean_originSuriname               0.012254   0.505548   0.024
## country_of_bean_originTaiwan                -0.362746   0.399672  -0.908
## country_of_bean_originTanzania               0.024196   0.257580   0.094
## country_of_bean_originThailand               0.062254   0.319739   0.195
## country_of_bean_originTobago                 0.325984   0.399719   0.816
## country_of_bean_originTogo                  -0.154413   0.357478  -0.432
## country_of_bean_originTrinidad               0.027892   0.261681   0.107
## country_of_bean_originU.S.A.                -0.004605   0.264013  -0.017
## country_of_bean_originUganda                -0.145192   0.272044  -0.534
## country_of_bean_originVanuatu               -0.110108   0.280444  -0.393
## country_of_bean_originVenezuela              0.018205   0.254312   0.072
## country_of_bean_originVietnam                0.078797   0.257969   0.305
##                                             Pr(>|t|)    
## (Intercept)                                  < 2e-16 ***
## cocoa_percent                               1.44e-14 ***
## country_of_bean_originBelize                  0.9049    
## country_of_bean_originBlend                   0.4913    
## country_of_bean_originBolivia                 0.8856    
## country_of_bean_originBrazil                  0.8704    
## country_of_bean_originBurma                   0.6382    
## country_of_bean_originCameroon                0.6493    
## country_of_bean_originChina                   0.5706    
## country_of_bean_originColombia                0.9090    
## country_of_bean_originCongo                   0.7630    
## country_of_bean_originCosta Rica              0.7947    
## country_of_bean_originCuba                    0.7051    
## country_of_bean_originDominican Republic      0.9896    
## country_of_bean_originDR Congo                0.6040    
## country_of_bean_originEcuador                 0.8962    
## country_of_bean_originEl Salvador             0.4828    
## country_of_bean_originFiji                    0.6016    
## country_of_bean_originGabon                   0.8844    
## country_of_bean_originGhana                   0.7290    
## country_of_bean_originGrenada                 0.4204    
## country_of_bean_originGuatemala               0.8794    
## country_of_bean_originHaiti                   0.8778    
## country_of_bean_originHonduras                0.8928    
## country_of_bean_originIndia                   0.7651    
## country_of_bean_originIndonesia               0.7288    
## country_of_bean_originIvory Coast             0.2229    
## country_of_bean_originJamaica                 0.9408    
## country_of_bean_originLiberia                 0.6825    
## country_of_bean_originMadagascar              0.8619    
## country_of_bean_originMalaysia                0.6756    
## country_of_bean_originMartinique              0.1016    
## country_of_bean_originMexico                  0.8360    
## country_of_bean_originNicaragua               0.8926    
## country_of_bean_originNigeria                 0.4702    
## country_of_bean_originPanama                  0.7300    
## country_of_bean_originPapua New Guinea        0.8459    
## country_of_bean_originPeru                    0.9113    
## country_of_bean_originPhilippines             0.7100    
## country_of_bean_originPrincipe                0.4268    
## country_of_bean_originPuerto Rico             0.0716 .  
## country_of_bean_originSamoa                   0.9927    
## country_of_bean_originSao Tome                0.5824    
## country_of_bean_originSao Tome & Principe     0.4638    
## country_of_bean_originSierra Leone            0.1552    
## country_of_bean_originSolomon Islands         0.4164    
## country_of_bean_originSri Lanka               0.4061    
## country_of_bean_originSt. Lucia               0.3590    
## country_of_bean_originSt.Vincent-Grenadines   0.3596    
## country_of_bean_originSulawesi                0.9420    
## country_of_bean_originSumatra                 0.6382    
## country_of_bean_originSuriname                0.9807    
## country_of_bean_originTaiwan                  0.3642    
## country_of_bean_originTanzania                0.9252    
## country_of_bean_originThailand                0.8456    
## country_of_bean_originTobago                  0.4148    
## country_of_bean_originTogo                    0.6658    
## country_of_bean_originTrinidad                0.9151    
## country_of_bean_originU.S.A.                  0.9861    
## country_of_bean_originUganda                  0.5936    
## country_of_bean_originVanuatu                 0.6946    
## country_of_bean_originVenezuela               0.9429    
## country_of_bean_originVietnam                 0.7600    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4378 on 2467 degrees of freedom
## Multiple R-squared:  0.05712,    Adjusted R-squared:  0.03343 
## F-statistic: 2.411 on 62 and 2467 DF,  p-value: 7.663e-09

Coefficients

  • Cocoa Percent

    • The coefficient for cocoa_percent was a -1.23, with a very low p-value (1.44e-14), which suggested that higher cocoa percentages are associated with lower ratings.
  • Country of Bean Origin

    • The majority of countries had p-values that indicated their coefficients are not significant, suggesting that the country of bean origin had less impact on the rating.

Conclusion

  • Cocoa percentage had a significant negative impact on ratings, suggesting that higher cocoa percentages might have lead to lower ratings.

  • The country of bean origin generally didn’t show significant effects on ratings.

The linear regression model summary did not support that the origin of the cocoa beans significantly affected chocolate ratings when considering other factors like cocoa percentage.

Visualization

After discovering that many more factors besides percent cocoa and where that cocoa is sourced from affects the chocolate rating, I decided to visualize each country_of_bean_origin.

Box-plots

Box-plots can help visualize the distribution of chocolate ratings for each country of origin which I did here.

# Boxplot of chocolate ratings by cocoa bean country of origin
ggplot(chocolate, aes(x = country_of_bean_origin, y = rating)) +
  geom_boxplot(fill = "lightblue") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  labs(x = "Cocoa Bean Country of Origin", y = "Rating", title = "Chocolate Ratings by Country of Origin")

From a glance, I saw that Tobago had a box-plot that is in the higher ratings. However, there are other box-plots that were very small therefore suggesting variance in data points. Due to the existence of variance in the amount of data available for each country, I decided to separate the countries by the amount of data available and then create their respective box-plots. In the next section, I tried to work with that variance.

Box-plots Variance

# Grouped by country_of_bean_origin and counted the number of ratings for each country
country_rating_count <- chocolate |>
  group_by(country_of_bean_origin) |>
  summarize(count = n())

# Found the minimum, maximum, and average counts of data
min_max_count <- country_rating_count |>
  summarize(
    min_count = min(count),
    max_count = max(count),
    avg_count=mean(count)
  )

print(min_max_count)
## # A tibble: 1 × 3
##   min_count max_count avg_count
##       <int>     <int>     <dbl>
## 1         1       253      40.8

I found the minimum, maximum, and average amount of data points for a country to decide on my threshold. I decided to set a minimum threshold of 40 data points (the average), the following is for countries with equal to and higher than 40 data points:

# Set a minimum count threshold
min_count_threshold <- 40

# Filtered countries with at least the minimum count
filtered_chocolate <- chocolate |>
  group_by(country_of_bean_origin) |>
  filter(n() >= min_count_threshold)

# Calculated the mean rating for the filtered data
mean_ratings_filtered <- filtered_chocolate |>
  group_by(country_of_bean_origin) |>
  summarize(mean_rating = mean(rating, na.rm = TRUE))

# Created the box plot with annotations for the mean rating
ggplot(filtered_chocolate, aes(x = country_of_bean_origin, y = rating)) +
  geom_boxplot(fill = "lightblue") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  labs(x = "Cocoa Bean Country of Origin", y = "Rating", title = "Chocolate Ratings by Country of Origin (Filtered)") +
  
  # Annotated the box plot with the mean rating
  geom_text(
    data = mean_ratings_filtered,
    aes(x = country_of_bean_origin, y = mean_rating, label = round(mean_rating, 2)), # Rounded to 2 decimal places
    vjust = 0.5, # Adjusted vertical position
    hjust=0.5,
    color = "red", # Used a different color for visibility
    angle=90
  )

From the above box-plot, I noticed there was not one country that was standing out like Tobago in our other box-plot, but I do note that Vietnam has a higher average rating!

T-Test

In the first box-plot visualization l decided to fix the variance, but I decided to touch back on Tobago’s box-plot which indicated it’s cocoa bean produced highly rated chocolate. The t-test is a statistical test used to determine whether there is a significant difference between the means of two groups, in this case Tobago’s rating versus all the other countries.

# Created a subset for Tobago
tobago_data <- chocolate |>
  filter(country_of_bean_origin == "Tobago")

# Created a subset for all other countries
non_tobago_data <- chocolate |>
  filter(country_of_bean_origin != "Tobago")

# Performed an independent samples t-test
t_test_result <- t.test(
  tobago_data$rating, 
  non_tobago_data$rating, 
  var.equal = FALSE # Use var.equal = TRUE if you assume equal variances
)

# Printed the t-test result
print(t_test_result)
## 
##  Welch Two Sample t-test
## 
## data:  tobago_data$rating and non_tobago_data$rating
## t = 1.1437, df = 1.0011, p-value = 0.4572
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -4.324629  5.182620
## sample estimates:
## mean of x mean of y 
##  3.625000  3.196005

The t-test results indicated the following:

  • t-statistic: The value of 1.1437 suggested that the observed difference in means between the two groups was relatively small compared to the variability.

  • p-value: The p-value of 0.4572 indicated that the observed difference is not significant. Typically, a p-value below 0.05 is considered significant, suggesting the groups have a meaningful difference. A p-value above 0.05 suggested there was no strong evidence against the null hypothesis (that the groups have the same mean).

Given these results, there does not exist a significant difference in chocolate ratings between Tobago and the other countries. However, this outcome could be due to the small sample size for Tobago, the limited data points for Tobago could have reduced the test’s statistical power.

Statistical Analysis with ANOVA

In order to test whether there exist any significant differences in chocolate ratings across different countries of origin, I decided to use Analysis of Variance (ANOVA). ANOVA is appropriate for categorical predictors with more than two levels. This ANOVA model implied if there exists a significant difference in chocolate ratings across different countries of origin.

# Fit an ANOVA model to test differences in 'rating' by 'cocoa_bean_country_of_origin'
anova_model <- aov(rating ~ country_of_bean_origin, data = chocolate)

# Get the summary of the ANOVA model
summary(anova_model)
##                          Df Sum Sq Mean Sq F value Pr(>F)  
## country_of_bean_origin   61   17.2  0.2814   1.434 0.0162 *
## Residuals              2468  484.4  0.1963                 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Here is the interpretation of the data set’s ANOVA results:

P-Value (Pr(>F))

  • The p-value of 0.0162 (p < 0.05) suggested that there are significant differences in chocolate ratings across different countries of origin.

The ANOVA results suggested that the country of cocoa bean origin had a significant effect on chocolate ratings, with a p-value of 0.0162. This means that I rejected the null hypothesis (which assumed that there’s no difference in ratings across different countries) at the 5% significance level.

The ANOVA model suggested that the country of cocoa bean origin does affect the chocolate’s rating. This could potentially strike chocolate manufacturers to invest more time into researching the conditions that could make a country’s cocoa beans grow richer.

Conclusion

In this project I decided to explore a data set on the topic of chocolate to find what factors can make chocolate great. With the available variables in the data set, I decided to explore what factors can lead to higher chocolate ratings. Ultimately, I focused on cocoa_percent and country_of_bean_origin to determine whether those factors affect the chocolates rating.

The linear regression analysis of cocoa_percent suggested that as the cocoa percentage increased, the chocolate rating tended to decrease. However, the low R-squared indicated that cocoa percentage alone did not explain much of the variation in chocolate ratings. I then decided to incorporate country_of_bean_origin into the linear model and found the linear regression model summary did not support that the origin of the cocoa beans significantly affected chocolate ratings when considering other factors like cocoa percentage.

All in all, both results indicated that more complex or different models might be needed to examine this relationship in greater detail. Other variables, such as ingredients, and manufacturer could have a more significant impact, but for time sake I only focused on cocoa_percent and country_of_bean_origin.

A box-plot of ratings from each country_of_bean_origin resulted in displaying variance in countries due to some countries lacking data points. The box-plot did show Tobago having significantly higher ratings compared to the other countries which I decided to test using a T-test. The T-test suggested there did not exist a significant difference in chocolate ratings between Tobago and the other countries. However, this outcome could have been due to the small sample size for Tobago, the limited data points for Tobago could have reduced the test’s statistical power. It might be worth a chocolate manufacturer’s time to seek partnerships to include countries that have limited amounts of data because they might just lack those data points due to no manufacture taking the time to invest into their growth! They might have really rich land that hasn’t been discovered just yet!

To conclude the project I decided to run an ANOVA test that suggested the country of cocoa bean origin had an effect on chocolate ratings! This could lead chocolate manufacturers to invest more time into researching what conditions make a rich cocoa bean, and then find what land and environment hosts that!