Sustainble Finance- Data Visualization Practice

Author

Zixi Fan

Data Visualization Practice HW

Load Data

library(esquisse)
library(ggplot2)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ lubridate 1.9.3     ✔ tibble    3.2.1
✔ purrr     1.0.2     ✔ tidyr     1.3.0
── 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("ggsci")
library("gridExtra")

Attaching package: 'gridExtra'

The following object is masked from 'package:dplyr':

    combine
# 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"
blackrock_esg_vs_non_esg_etf <- github_url |> 
  read_csv() |> 
  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.

Question 1

ggplot(blackrock_esg_vs_non_esg_etf) +
 aes(x = esg_etf, y = standard_etf, colour = sector) +
 geom_point(shape = "circle", 
 size = 0.9) +
 geom_smooth(span = 0.45) +
 scale_color_viridis_d(option = "plasma", direction = 1) +
 scale_x_continuous(trans = "log10") +
 scale_y_continuous(trans = "log10") +
 labs(x = "ESG ETF ", 
 y = "Standard ETF", title = "ETFs: ESG vs.Non-ESG", caption = "Zixi Fan") +
 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()`).
Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,
: span too small.  fewer data values than degrees of freedom.
Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,
: pseudoinverse used at -0.83043
Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,
: neighborhood radius 0.21739
Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,
: reciprocal condition number 0
Warning in simpleLoess(y, x, w, span, degree = degree, parametric = parametric,
: There are other near singularities as well. 0.052415
Warning in predLoess(object$y, object$x, newx = if (is.null(newdata)) object$x
else if (is.data.frame(newdata))
as.matrix(model.frame(delete.response(terms(object)), : span too small.  fewer
data values than degrees of freedom.
Warning in predLoess(object$y, object$x, newx = if (is.null(newdata)) object$x
else if (is.data.frame(newdata))
as.matrix(model.frame(delete.response(terms(object)), : pseudoinverse used at
-0.83043
Warning in predLoess(object$y, object$x, newx = if (is.null(newdata)) object$x
else if (is.data.frame(newdata))
as.matrix(model.frame(delete.response(terms(object)), : neighborhood radius
0.21739
Warning in predLoess(object$y, object$x, newx = if (is.null(newdata)) object$x
else if (is.data.frame(newdata))
as.matrix(model.frame(delete.response(terms(object)), : reciprocal condition
number 0
Warning in predLoess(object$y, object$x, newx = if (is.null(newdata)) object$x
else if (is.data.frame(newdata))
as.matrix(model.frame(delete.response(terms(object)), : There are other near
singularities as well. 0.052415
Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
-Inf

Question 2

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)"))
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
library(dplyr)
library(ggplot2)

blackrock_esg_vs_non_esg_etf_long %>%
 filter(weight >= 1 & weight <= 100) %>%
 ggplot() +
# Choose point char and assign vairable
 aes(x = weight, y = company_name, colour = fund_type, size = weight) +
 geom_point(shape = "circle") +
# Change color to the variable
 scale_color_manual(values = c(`ESG ETF (ESGU)` = "green", `Standard ETF (IVV)` = "gray"
)) +
 labs(x = "Weight", y = "Company", title = "Blackrock ETFs: ESG vs non-EGS", caption = "Zixi Fan") +
 theme_minimal()

Companies tend to put smaller wights on ESG ETF and relatively more weights on standard EFT. However, we can see from the chart that there are some outliers like Apple and Microsoft. They put lots of weight on both ESG ETF and standard ETF.

Question 3

Graph 1 shows that the weights in different sectors based on the fund type. And here, the x-axis is the sector, and y axis is the wights. The data are grouped by the fund type.

ggplot(blackrock_esg_vs_non_esg_etf_long) +
  aes(x = sector, y = weight, colour = fund_type) +
  geom_point(shape = "circle", size = 2.25) +
  scale_color_hue(direction = 1) +
  labs(
    title = "Weight on Different Sectors ",
    caption = "Zixi Fan"
  ) +
  theme_minimal()

Graph 2 demonstrates how wights for ESG and non-ESG etf are distributed based on different sectors. In this graph, the x-axis is the fund type and y axis is weights. And the data are grouped by sectors. There is a little bit difference from the previous graph.

blackrock_esg_vs_non_esg_etf_long %>%
 filter(weight >= 0.7 & weight <= 2.9) %>%
 ggplot() +
  aes(x = fund_type, y = weight, colour = sector) +
  geom_point(shape = "circle", size = 1.5) +
  scale_color_manual(
    values = c(Communication = "#F8766D",
    `Consumer Discretionary` = "#DA8C15",
    `Consumer Staples` = "#ACA000",
    Energy = "#58B016",
    Financials = "#00BB4C",
    `Health Care` = "#00C19F",
    Industrials = "#00BAD5",
    `Information Technology` = "#3AA7F3",
    Materials = "#918BFD",
    `Real Estate` = "#E26EEF",
    Utilities = "#FF61C3")
  ) +
  scale_y_continuous(trans = "log10") +
  labs(
    title = "Weights on ESg and non-EGS ETFs ",
    caption = "Zixi Fan"
  ) +
  theme_classic()

Question 4

plot 1

ggplot(blackrock_esg_vs_non_esg_etf) +
 aes(x = esg_etf, y = standard_etf, colour = sector) +
# Point graph 
 geom_point(shape = "circle", 
 size = 1.5) +
 scale_color_hue(direction = 1) +
# assign log 10 to both x and y axis. 
 scale_x_continuous(trans = "log10") +
 scale_y_continuous(trans = "log10") +
 theme_gray()
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis

This is a point graph that has esg_etf as x variable, and standard_etf as y variable. And the graph assign log 10 to both the x and y axis.

plot 2

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = esg_etf, y = standard_etf, colour = sector) +
  geom_point(shape = "circle", size = 1.5) +
# add smooth line to graoh
  geom_smooth(span = 0.79) +
  scale_color_hue(direction = 1) +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10") +
  theme_gray()
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()`).

This plot is different from the previous one that it adds the smooth line.

plot 3

ggplot(blackrock_esg_vs_non_esg_etf) +
  #Use standard_eft as color, not the sector
  aes(x = esg_etf, y = standard_etf, colour = standard_etf) +
  geom_point(shape = "circle", size = 1.6) +
  geom_smooth(span = 0.71) +
  #change color of the line 
  scale_color_gradient(low = "purple", high = "yellow") +
  scale_x_continuous(trans = "log10") +
  scale_y_continuous(trans = "log10") +
  theme_gray()
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: The following aesthetics were dropped during statistical transformation: colour
ℹ This can happen when ggplot fails to infer the correct grouping structure in
  the data.
ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
  variable into a factor?

This plot use standard ETF as color instead of using sector as color.

Question 5

I split the data into two graph, one is for ESG ETFand the other one is standard ETF For this graph, it is a bar graph that show the ESG ETF in different sectors.

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = sector, y = esg_etf) +
  geom_col(fill = "pink") +
  labs(
    x = "Sector",
    y = "ESG etf",
    title = "ESG ETF in Different Sectors"
  ) +
  coord_flip() +
  theme_minimal()

The second graph shows the standard etf in different sectors. And as we have two different graph for ESG and non ESG, we can compare them based on the sectors.

ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = sector, y = standard_etf) +
  geom_col(fill = "orange") +
  labs(
    x = "Sector",
    y = "Standard etf",
    title = "Standard ETF in Different Sectors"
  ) +
  coord_flip() +
  theme_minimal()

Question 6

This graph I utilized ggsci and gridExtra to put both the scatter plot and bar graph together. As putting two different kind s of graph together, it is easier to see how ESG ETF are distributed in different sectors comparing to non-ESG ETF. And from both graph, we can conclude that information technology and potential health care have more ESG ETF comparing to others.

#utilized ggsci and gridExtra. 
p1 <- ggplot(blackrock_esg_vs_non_esg_etf) +
 aes(x = esg_etf, y = standard_etf, colour = sector) +
 geom_point(shape = "circle", 
 size = 1.5) +
 scale_color_hue(direction = 1) +
 scale_x_continuous(trans = "log10") +
 scale_y_continuous(trans = "log10") +
 theme_bw()

p2 <- ggplot(blackrock_esg_vs_non_esg_etf) +
  aes(x = sector, y = esg_etf) +
  geom_col(fill = "red") +
  labs(
    x = "Sector",
    y = "ESG etf",
    title = "ESG ETF in Different Sectors"
  ) +
  coord_flip() +
  theme_minimal()

p1_npg <- p1 + scale_color_npg()
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
p2_npg <- p2 + scale_fill_npg()

grid.arrange(p1_npg, p2_npg, ncol = 2)
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Transformation introduced infinite values in continuous y-axis
Warning: This manual palette can handle a maximum of 10 values. You have
supplied 11
Warning: Removed 32 rows containing missing values (`geom_point()`).