SusFin Assignment Week 2

Author

Boyuan Gao

Problem 1

Recreate the chart above in Esquisse.

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ 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
# the URL of our data on GitHub
github_url <- "https://raw.githubusercontent.com/t-emery/sais-susfin_data/main/datasets/etf_comparison-2022-10-03.csv"

# read the data from GitHub
blackrock_esg_vs_non_esg_etf <- github_url |> 
  read_csv() |> 
  # select the four columns we will use in our anlaysis here
  select(company_name:standard_etf)
Rows: 537 Columns: 14
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (4): ticker, company_name, sector, esg_uw_ow
dbl (7): esg_etf, standard_etf, esg_tilt, esg_tilt_z_score, esg_tilt_rank, e...
lgl (3): in_esg_only, in_standard_only, in_on_index_only

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# recreate the chart
ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = esg_etf, y = standard_etf, colour = sector) +
  geom_point(shape = "circle", size = 1.5) +
  geom_smooth(span = 0.75) +
  scale_color_viridis_d(option = "inferno", direction = 1) +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10") +
  labs(
    x = "ESG ETF (ESGU)",
    y = "Standard ETF (IVV)",
    title = "Large Cap American Equities ETFs: ESG vs. Non-ESG",
    subtitle = "A comparison of the holdings of BlackRock iShares ESGU and IVV",
    caption = "Boyuan Gao"
  ) +
  theme_minimal() +
  facet_wrap(vars(sector))
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: Removed 261 rows containing non-finite values (`stat_smooth()`).

Problem 2

Exploring the outliers.

# change data from wide to long
blackrock_esg_vs_non_esg_etf_long <- blackrock_esg_vs_non_esg_etf |> 
  pivot_longer(cols = contains("etf"), names_to = "fund_type", values_to = "weight") |> 
  mutate(fund_type = case_when(fund_type == "esg_etf" ~ "ESG ETF (ESGU)",
                               fund_type == "standard_etf" ~ "Standard ETF (IVV)"))

# reload data
blackrock_esg_vs_non_esg_etf_long
# A tibble: 1,074 × 4
   company_name                  sector                 fund_type         weight
   <chr>                         <chr>                  <chr>              <dbl>
 1 PRUDENTIAL FINANCIAL INC      Financials             ESG ETF (ESGU)    0.537 
 2 PRUDENTIAL FINANCIAL INC      Financials             Standard ETF (IV… 0.106 
 3 GENERAL MILLS INC             Consumer Staples       ESG ETF (ESGU)    0.552 
 4 GENERAL MILLS INC             Consumer Staples       Standard ETF (IV… 0.151 
 5 KELLOGG                       Consumer Staples       ESG ETF (ESGU)    0.453 
 6 KELLOGG                       Consumer Staples       Standard ETF (IV… 0.0592
 7 AUTOMATIC DATA PROCESSING INC Information Technology ESG ETF (ESGU)    0.649 
 8 AUTOMATIC DATA PROCESSING INC Information Technology Standard ETF (IV… 0.312 
 9 ECOLAB INC                    Materials              ESG ETF (ESGU)    0.441 
10 ECOLAB INC                    Materials              Standard ETF (IV… 0.118 
# ℹ 1,064 more rows
# create the chart
blackrock_esg_vs_non_esg_etf_long %>%
  # limit the weight variable to companies over a 1% weight
  filter(weight >= 1L & weight <= 7L) %>%
  ggplot() +
  aes(
    x = weight,
    y = company_name,
    colour = fund_type,
    size = weight
  ) +
  geom_point(shape = "circle") +
  # change the color for ESG fund points to green, and the non-ESG fund to grey
  scale_color_manual(
    values = c(`ESG ETF (ESGU)` = "#AAEB7C",
               `Standard ETF (IVV)` = "#797678")
  ) +
  labs(
    x = "Weight (%)",
    y = "Company Name",
    title = "Companies with High Weight in ESG and Non-ESG ETFs",
    caption = "Boyuan Gao",
    color = "ESG vs. Non ESG",
    size = "Weight"
  ) +
  theme_minimal()

Reflection: Most of the companies with a high weight in ESG and Non-ESG ETFs are leading tech companies, i.e. Apple, Microsoft, Alphabet, Amazon, etc. This could be that these tech companies have shown significant revenue and earnings growth, and hence a larger presence in the indices.

Problem 3

Make your own charts with esquisse.

Question 1: What kind of companies are excluded from the ESG fund?

Companies excluded from ESGU are primarily from certain key sectors. Out of the 226 companies that are included in the IVV index but excluded from the ESGU index, the predominant sectors are Information Technology, Industrials, Financials, and Consumer Discretionary. These four sectors collectively constitute half of the excluded companies.

# filter companies with 0 weight in the ESG fund
blackrock_esg_excluded <- blackrock_esg_vs_non_esg_etf |> 
  filter(esg_etf == 0)

blackrock_esg_excluded
# A tibble: 226 × 4
   company_name                       sector                esg_etf standard_etf
   <chr>                              <chr>                   <dbl>        <dbl>
 1 DISH NETWORK CORP                  Communication               0       0.0113
 2 RALPH LAUREN CORP                  Consumer Discretiona…       0       0.0120
 3 VORNADO REALTY TRUST REIT          Real Estate                 0       0.0127
 4 MOHAWK INDUSTRIES INC              Consumer Discretiona…       0       0.0155
 5 NORWEGIAN CRUISE LINE HOLDINGS LTD Consumer Discretiona…       0       0.0157
 6 ALASKA AIR GROUP INC               Industrials                 0       0.0170
 7 NEWELL BRANDS INC                  Consumer Discretiona…       0       0.0174
 8 DXC TECHNOLOGY                     Information Technolo…       0       0.0188
 9 ORGANON                            Health Care                 0       0.0196
10 DENTSPLY SIRONA INC                Health Care                 0       0.0196
# ℹ 216 more rows
# create the chart
ggplot(blackrock_esg_excluded) +
  aes(x = sector, fill = sector) +
  geom_bar() +
  scale_fill_hue(direction = 1) +
  labs(
    x = "Sector",
    y = "Number of Companies",
    title = "Companies Excluded from the ESG Fund",
    subtitle = "Distribution by sector",
    caption = "Boyuan Gao"
  ) +
  coord_flip() +
  theme_minimal()

Question 2: What kind of companies are excluded from the Non-ESG fund?

Companies excluded from IVV are primarily from the Information Technology sector. Out of the 35 companies that are included in the ESGU index but excluded from the IVV index, 15 are tech companies. This indicates a significant sectoral focus or bias in the exclusion criteria.

# filter companies with 0 weight in the Non-ESG fund
blackrock_non_esg_excluded <- blackrock_esg_vs_non_esg_etf |> 
  filter(standard_etf == 0)

blackrock_non_esg_excluded
# A tibble: 35 × 4
   company_name                    sector                 esg_etf standard_etf
   <chr>                           <chr>                    <dbl>        <dbl>
 1 CHENIERE ENERGY INC             Energy                   0.274            0
 2 BUNGE LTD                       Consumer Staples         0.199            0
 3 VAIL RESORTS INC                Consumer Discretionary   0.173            0
 4 UBER TECHNOLOGIES INC           Industrials              0.170            0
 5 INSULET CORP                    Health Care              0.149            0
 6 MERCADOLIBRE INC                Consumer Discretionary   0.145            0
 7 SNOWFLAKE                       Information Technology   0.142            0
 8 VMWARE CLASS A INC              Information Technology   0.134            0
 9 MARVELL TECHNOLOGY INC          Information Technology   0.130            0
10 HORIZON THERAPEUTICS PUBLIC PLC Health Care              0.121            0
# ℹ 25 more rows
# create the chart
ggplot(blackrock_non_esg_excluded) +
  aes(x = sector, fill = sector) +
  geom_bar() +
  scale_fill_hue(direction = 1) +
  labs(
    x = "Sector",
    y = "Number of Companies",
    title = "Company Excluded from the Non-ESG Fund",
    subtitle = "Distribution by sector",
    caption = "Boyuan Gao"
  ) +
  coord_flip() +
  theme_minimal()

Problem 4

Understanding aes( ).

Chart 1

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = esg_etf, y = standard_etf) +
  geom_point(shape = "circle", size = 1.5, aes(color = sector)) +
  geom_smooth(span = 0.75) +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10")
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: Removed 261 rows containing non-finite values (`stat_smooth()`).

Chart 2

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = esg_etf, y = standard_etf, color = sector) +
  geom_point(shape = "circle", size = 1.5) +
  geom_smooth(span = 0.75) +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10")
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: Removed 261 rows containing non-finite values (`stat_smooth()`).

Chart 3

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = esg_etf, y = standard_etf) +
  geom_point(shape = "circle", size = 1.5, color = "purple") +
  geom_smooth(span = 0.75, color = "yellow") +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10")
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: Removed 261 rows containing non-finite values (`stat_smooth()`).

Problem 5

Make a new chart from the R Graph Gallery.

I added a linear trend (red) to the scatterplot along with a 45 degree line (black). Observations above the 45 degree line indicates a higher weight in the standard ETF fund (IVV). Note that the linear trend line is below the 45 degree line, which means that many companies included in the IVV has a higher weight in the ESGU fund.

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = esg_etf, y = standard_etf) +
  geom_point(shape = "circle", size = 1.5, aes(color = sector)) +
  # add a linear trend
  geom_smooth(method = lm, color = "RED", se = FALSE) +
  # add a 45 degree line
  geom_abline() +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10") +
  labs(
    x = "ESG ETF (ESGU)",
    y = "Standard ETF (IVV)",
    caption = "Boyuan Gao"
  ) 
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
`geom_smooth()` using formula = 'y ~ x'
Warning: Removed 261 rows containing non-finite values (`stat_smooth()`).

Problem 6

Make a new chart from the ggplot2 Extensions Gallery.

On top of Chart 2 in Problem 4, I added labels to each trended lines using an extension from ggplot2 Extensions Gallery. Although the lines are a bit cramped up for our data set, it is a good tool to indicate what each line represents.

install.packages("remotes", repos = "https://cloud.r-project.org/")

The downloaded binary packages are in
    /var/folders/n8/_cd4n0yj163cg0ch3vvcyk4h0000gn/T//RtmpGNDerL/downloaded_packages
remotes::install_github("AllanCameron/geomtextpath")
Skipping install of 'geomtextpath' from a github remote, the SHA1 (d6a9a9a6) has not changed since last install.
  Use `force = TRUE` to force installation
library(geomtextpath)

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = esg_etf, y = standard_etf, color = sector) +
  geom_point(shape = "circle", size = 1.5) +
  geom_smooth() +
  geom_labelsmooth(aes(label = sector), text_smoothing = 30, fill = "#F6F6FF", alpha = 0.6, method = "loess", formula = y ~x, size = 3, linewidth = 1, boxlinewidth = 0.3) +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10")
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Warning: Removed 261 rows containing non-finite values (`stat_smooth()`).
Warning: Removed 261 rows containing non-finite values (`stat_smooth()`).