Objective

The objective of this applied project is to explain the price of avocados using some basic descriptive analysis. This analysis can be used by producers, retailers, and groceries to make decisions about their pricing strategies, advertising strategies, and supply chain strategies among others.

Dataset

Weekly retail scan data for Hass avocados from the Hass Avocado Board: average price per avocado, total volume, type (conventional or organic), year, city (geography), and Mileage (distance in miles) for 41 U.S. cities.

# avocado.csv must be saved in the same folder as this .Rmd file
data <- read.csv("avocado.csv", fileEncoding = "UTF-8-BOM", check.names = FALSE)
names(data) <- trimws(names(data))                    # removes the extra space in "average_price "
data$date <- as.Date(data$date, format = "%Y/%m/%d")

summary(data)
##       date            average_price    total_volume            type      
##  Min.   :2017-12-03   Min.   :0.500   Min.   :    253   Length   :12628  
##  1st Qu.:2018-08-19   1st Qu.:1.100   1st Qu.:  15733   N.unique :    2  
##  Median :2019-06-12   Median :1.320   Median :  94806   N.blank  :    0  
##  Mean   :2019-06-02   Mean   :1.359   Mean   : 325259   Min.nchar:    7  
##  3rd Qu.:2020-03-08   3rd Qu.:1.570   3rd Qu.: 430222   Max.nchar:   12  
##  Max.   :2020-11-29   Max.   :2.780   Max.   :5660216                    
##       year          geography        Mileage    
##  Min.   :2017   Length   :12628   Min.   : 111  
##  1st Qu.:2018   N.unique :   41   1st Qu.:1097  
##  Median :2019   N.blank  :    0   Median :2193  
##  Mean   :2019   Min.nchar:    5   Mean   :1911  
##  3rd Qu.:2020   Max.nchar:   20   3rd Qu.:2632  
##  Max.   :2020                     Max.   :2998
str(data)
## 'data.frame':    12628 obs. of  7 variables:
##  $ date         : Date, format: "2017-12-03" "2017-12-03" ...
##  $ average_price: num  1.39 1.44 1.07 1.62 1.43 1.58 1.14 1.77 1.4 1.88 ...
##  $ total_volume : int  139970 3577 504933 10609 658939 38754 86646 1829 488588 21338 ...
##  $ type         : chr  "conventional" "organic" "conventional" "organic" ...
##  $ year         : int  2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 ...
##  $ geography    : chr  "Albany" "Albany" "Atlanta" "Atlanta" ...
##  $ Mileage      : int  2832 2832 2199 2199 2679 2679 827 827 2998 2998 ...

Class analysis

library(ggplot2)

# Simple histogram
hist(data$average_price,
     main = "Histogram of average_price",
     xlab = "Price in USD (US Dollar)")

# Price distribution by type
ggplot(data, aes(x = average_price, fill = type)) + 
  geom_histogram(bins = 30, col = "red") + 
  scale_fill_manual(values = c("blue", "green")) +
  ggtitle("Frequency of Average Price - Organic vs. Conventional")

# Total volume by city
ggplot() + 
  geom_col(data, mapping = aes(x = reorder(geography, total_volume), 
                               y = total_volume, fill = year)) +
  xlab("geography") +
  ylab("total_volume") +
  theme(axis.text.x = element_text(angle = 90, size = 7)) 

Question 1: Price range

summary(data$average_price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.500   1.100   1.320   1.359   1.570   2.780
data[which.min(data$average_price), ]   # lowest price
##            date average_price total_volume         type year geography Mileage
## 1755 2018-04-22           0.5      2335867 conventional 2018   Houston    1656
data[which.max(data$average_price), ]   # highest price
##            date average_price total_volume    type year geography Mileage
## 6712 2019-07-14          2.78        15994 organic 2019 San Diego     253

Prices range from $0.50 (conventional, Houston, week of April 22, 2018) to $2.78 (organic, San Diego, week of July 14, 2019).

Question 2: Top cities by dollar sales, 2017 and 2018

# Dollar sales = average price per avocado x number of avocados sold
data$dollar_sales <- data$average_price * data$total_volume

# Pivot table: total dollar sales by year, type, and city
sales <- aggregate(dollar_sales ~ year + type + geography,
                   data = subset(data, year %in% c(2017, 2018)), FUN = sum)

# Rank cities within each year and type, keep the top 3
sales$rank <- ave(-sales$dollar_sales, sales$year, sales$type, FUN = rank)
top3 <- sales[sales$rank <= 3, ]
top3 <- top3[order(top3$year, top3$type, top3$rank), ]
top3$dollar_sales <- format(round(top3$dollar_sales), big.mark = ",")
top3
##     year         type     geography dollar_sales rank
## 81  2017 conventional   Los Angeles   13,456,647    1
## 101 2017 conventional      New York    9,322,034    2
## 29  2017 conventional       Chicago    5,161,767    3
## 103 2017      organic      New York      720,451    1
## 83  2017      organic   Los Angeles      622,945    2
## 147 2017      organic       Seattle      550,111    3
## 82  2018 conventional   Los Angeles  153,526,216    1
## 102 2018 conventional      New York  118,997,580    2
## 142 2018 conventional San Francisco   59,780,808    3
## 104 2018      organic      New York    9,391,204    1
## 84  2018      organic   Los Angeles    8,561,139    2
## 148 2018      organic       Seattle    5,920,932    3

Los Angeles led conventional sales and New York led organic sales in both 2017 and 2018. Note that the 2017 data only covers December 2017.

Question 3: Custom figures

Figure 1: Average price by year (bar chart instead of a line)

Instead of tracking every week, this figure looks at the average price per year for each type — a simpler comparison at a glance.

library(ggplot2)

yearly <- aggregate(average_price ~ year + type, data = data, FUN = mean)

ggplot(yearly, aes(x = factor(year), y = average_price, fill = type)) +
  geom_col(position = "dodge") +
  labs(title = "Figure 1. Average avocado price by year",
       x = "Year", y = "Average price (USD)", fill = "Type")

yearly
##   year         type average_price
## 1 2017 conventional      1.150439
## 2 2018 conventional      1.156655
## 3 2019 conventional      1.199695
## 4 2020 conventional      1.065473
## 5 2017      organic      1.596341
## 6 2018      organic      1.577949
## 7 2019      organic      1.622406
## 8 2020      organic      1.518786

Organic avocados were consistently pricier than conventional in every year, and both types trended upward from 2017 to 2020.

Figure 2: Average price by city (bar chart instead of scatterplot)

This figure ranks cities by average price rather than plotting price against distance — a simpler way to see where avocados are cheapest and priciest.

city_avg <- aggregate(average_price ~ geography, data = data, FUN = mean)
city_avg <- city_avg[order(city_avg$average_price), ]

ggplot(city_avg, aes(x = reorder(geography, average_price), y = average_price)) +
  geom_col(fill = "darkgreen") +
  coord_flip() +
  labs(title = "Figure 2. Average avocado price by city",
       x = NULL, y = "Average price (USD)")

head(city_avg, 3)   # cheapest
##             geography average_price
## 11   Dallas/Ft. Worth      1.071396
## 17            Houston      1.107110
## 25 New Orleans/Mobile      1.146299
tail(city_avg, 3)   # most expensive
##               geography average_price
## 37              Seattle      1.640974
## 16 Hartford/Springfield      1.687175
## 36        San Francisco      1.689091

Prices vary noticeably by city, but the pattern isn’t obviously tied to distance — some far-away cities are cheap and some nearby cities are expensive, suggesting local demand or supply matters more than shipping distance alone.