Data Import and Preparation

avocado <- read.csv(
  "avocado.csv",
  stringsAsFactors = FALSE
)

names(avocado) <- trimws(names(avocado))

head(avocado)
##        date average_price total_volume         type year            geography
## 1 2017/12/3          1.39       139970 conventional 2017               Albany
## 2 2017/12/3          1.44         3577      organic 2017               Albany
## 3 2017/12/3          1.07       504933 conventional 2017              Atlanta
## 4 2017/12/3          1.62        10609      organic 2017              Atlanta
## 5 2017/12/3          1.43       658939 conventional 2017 Baltimore/Washington
## 6 2017/12/3          1.58        38754      organic 2017 Baltimore/Washington
##   Mileage
## 1    2832
## 2    2832
## 3    2199
## 4    2199
## 5    2679
## 6    2679
str(avocado)
## 'data.frame':    12628 obs. of  7 variables:
##  $ date         : chr  "2017/12/3" "2017/12/3" "2017/12/3" "2017/12/3" ...
##  $ 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 ...
summary(avocado)
##         date       average_price    total_volume            type      
##  Length   :12628   Min.   :0.500   Min.   :    253   Length   :12628  
##  N.unique :  154   1st Qu.:1.100   1st Qu.:  15733   N.unique :    2  
##  N.blank  :    0   Median :1.320   Median :  94806   N.blank  :    0  
##  Min.nchar:    8   Mean   :1.359   Mean   : 325259   Min.nchar:    7  
##  Max.nchar:   10   3rd Qu.:1.570   3rd Qu.: 430222   Max.nchar:   12  
##                    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

Estimated Dollar Sales

avocado$dollar_sales <-
  avocado$average_price * avocado$total_volume

head(avocado)
##        date average_price total_volume         type year            geography
## 1 2017/12/3          1.39       139970 conventional 2017               Albany
## 2 2017/12/3          1.44         3577      organic 2017               Albany
## 3 2017/12/3          1.07       504933 conventional 2017              Atlanta
## 4 2017/12/3          1.62        10609      organic 2017              Atlanta
## 5 2017/12/3          1.43       658939 conventional 2017 Baltimore/Washington
## 6 2017/12/3          1.58        38754      organic 2017 Baltimore/Washington
##   Mileage dollar_sales
## 1    2832    194558.30
## 2    2832      5150.88
## 3    2199    540278.31
## 4    2199     17186.58
## 5    2679    942282.77
## 6    2679     61231.32

Histogram of Average Prices

hist(
  avocado$average_price,
  main = "Histogram of Average Prices",
  xlab = "Price in U.S. Dollars",
  col = "lightblue",
  border = "white"
)

ggplot(avocado, aes(x = average_price, fill = type)) +
  geom_histogram(
    bins = 30,
    color = "white"
  ) +
  scale_fill_manual(
    values = c(
      conventional = "steelblue",
      organic = "darkgreen"
    )
  ) +
  labs(
    title = "Average Price: Organic versus Conventional Avocados",
    x = "Average Price",
    y = "Number of Observations",
    fill = "Avocado Type"
  ) +
  theme_minimal()

Total Sales Volume by Geography

ggplot(
  avocado,
  aes(
    x = reorder(geography, total_volume, FUN = sum),
    y = total_volume,
    fill = factor(year)
  )
) +
  geom_col() +
  labs(
    title = "Total Avocado Volume by Geography",
    x = "Geography",
    y = "Total Volume",
    fill = "Year"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(
      angle = 90,
      vjust = 0.5,
      hjust = 1,
      size = 7
    )
  )

Question 1 Analysis: Price Range

price_range <- data.frame(
  Lowest_Price = min(
    avocado$average_price,
    na.rm = TRUE
  ),
  Highest_Price = max(
    avocado$average_price,
    na.rm = TRUE
  )
)

price_range
##   Lowest_Price Highest_Price
## 1          0.5          2.78

Question 2 Analysis: City Dollar Sales

city_sales <- avocado |>
  filter(year %in% c(2017, 2018)) |>
  group_by(year, type, geography) |>
  summarise(
    dollar_sales = sum(
      dollar_sales,
      na.rm = TRUE
    ),
    total_volume = sum(
      total_volume,
      na.rm = TRUE
    ),
    average_price = mean(
      average_price,
      na.rm = TRUE
    ),
    .groups = "drop"
  )

city_sales |>
  arrange(
    year,
    type,
    desc(dollar_sales)
  )
## # A tibble: 164 × 6
##     year type         geography          dollar_sales total_volume average_price
##    <int> <chr>        <chr>                     <dbl>        <int>         <dbl>
##  1  2017 conventional Los Angeles           13456647.     13753082         0.99 
##  2  2017 conventional New York               9322034.      7198480         1.33 
##  3  2017 conventional Chicago                5161767.      4186532         1.29 
##  4  2017 conventional Houston                5125212.      6048049         0.862
##  5  2017 conventional San Francisco          5080416.      4502091         1.16 
##  6  2017 conventional Dallas/Ft. Worth       4940102.      5748621         0.864
##  7  2017 conventional Baltimore/Washing…     4767953.      3702282         1.31 
##  8  2017 conventional Denver                 4212002.      3997494         1.07 
##  9  2017 conventional Phoenix/Tucson         3817358.      5383359         0.712
## 10  2017 conventional Miami/Ft. Lauderd…     3732871.      3160387         1.20 
## # ℹ 154 more rows
highest_city <- city_sales |>
  group_by(year, type) |>
  slice_max(
    order_by = dollar_sales,
    n = 1,
    with_ties = FALSE
  ) |>
  ungroup()

highest_city
## # A tibble: 4 × 6
##    year type         geography   dollar_sales total_volume average_price
##   <int> <chr>        <chr>              <dbl>        <int>         <dbl>
## 1  2017 conventional Los Angeles    13456647.     13753082          0.99
## 2  2017 organic      New York         720451.       395248          1.82
## 3  2018 conventional Los Angeles   153526216.    145880803          1.07
## 4  2018 organic      New York        9391204.      5312552          1.82

Customized Figure 1: Dollar Sales

annual_sales <- avocado |>
  filter(year %in% c(2017, 2018)) |>
  group_by(year, type) |>
  summarise(
    dollar_sales = sum(
      dollar_sales,
      na.rm = TRUE
    ),
    .groups = "drop"
  )

ggplot(
  annual_sales,
  aes(
    x = factor(year),
    y = dollar_sales,
    fill = type
  )
) +
  geom_col(position = "dodge") +
  scale_y_continuous(labels = dollar) +
  labs(
    title = "Estimated Hass Avocado Dollar Sales",
    subtitle = "2017 and 2018 comparison",
    x = "Year",
    y = "Estimated Dollar Sales",
    fill = "Avocado Type"
  ) +
  theme_minimal()

Customized Figure 2: Regional Price and Volume

regional_2018 <- avocado |>
  filter(year == 2018) |>
  group_by(type, geography) |>
  summarise(
    total_volume = sum(
      total_volume,
      na.rm = TRUE
    ),
    average_price = mean(
      average_price,
      na.rm = TRUE
    ),
    .groups = "drop"
  )

ggplot(
  regional_2018,
  aes(
    x = total_volume,
    y = average_price,
    color = type
  )
) +
  geom_point(
    size = 2,
    alpha = 0.75
  ) +
  geom_smooth(
    method = "lm",
    se = TRUE
  ) +
  scale_x_log10() +
  labs(
    title = "Regional Price and Sales Volume in 2018",
    subtitle = "Organic versus conventional avocados",
    x = "Total Regional Volume, Log Scale",
    y = "Average Price",
    color = "Avocado Type"
  ) +
  theme_minimal()