Rows: 424 Columns: 18
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (10): ticker, name, asset_class, sub_asset_class, region, market, locat...
dbl (6): gross_expense_ratio_percent, net_expense_ratio_percent, net_asset...
dttm (2): incept_date, net_assets_as_of
ℹ 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.
blackrock_etf_screener |>#find ESG fundsgroup_by(sustainable_classification) |>summarize(# how many funds?n_funds =n(),# how much money?assets_usd =sum(net_assets_usd, na.rm =TRUE) ) |># arrange in descending orderarrange(assets_usd |>desc())
blackrock_etf_screener_w_new_features <- blackrock_etf_screener |>mutate(# if the sustainable_classification column is NA, then the fund is not an ESG fund.standard_or_esg =if_else(condition =is.na(sustainable_classification),true ="Standard",false ="ESG" ),# lubridate::year() extracts the year from a dateinception_year = lubridate::year(incept_date),# Change to a meaningful magnitude for the data. In asset management, billions is a good default. net_assets_bn_usd = net_assets_usd/10^9,# let's put our new variables at the front so we can see them easily..before =everything() ) |>rename(MSCI_WACI = msci_weighted_average_carbon_intensity_tons_co2e_m_sales)blackrock_etf_screener_w_new_features
# A tibble: 424 × 21
standard_or_esg inception_year net_assets_bn_usd ticker name
<chr> <dbl> <dbl> <chr> <chr>
1 Standard 2000 399. IVV iShares Core S&P 500…
2 Standard 2012 107. IEFA iShares Core MSCI EA…
3 Standard 2003 101. AGG iShares Core U.S. Ag…
4 Standard 2000 82.1 IWF iShares Russell 1000…
5 Standard 2000 78.2 IJR iShares Core S&P Sma…
6 Standard 2000 77.1 IJH iShares Core S&P Mid…
7 Standard 2012 73.9 IEMG iShares Core MSCI Em…
8 Standard 2000 67.7 IWM iShares Russell 2000…
9 Standard 2000 55.4 IWD iShares Russell 1000…
10 Standard 2002 52.2 TLT iShares 20+ Year Tre…
# ℹ 414 more rows
# ℹ 16 more variables: incept_date <dttm>, gross_expense_ratio_percent <dbl>,
# net_expense_ratio_percent <dbl>, net_assets_usd <dbl>,
# net_assets_as_of <dttm>, asset_class <chr>, sub_asset_class <chr>,
# region <chr>, market <chr>, location <chr>, investment_style <chr>,
# msci_esg_fund_rating_aaa_ccc <chr>, msci_esg_quality_score_0_10 <dbl>,
# MSCI_WACI <dbl>, msci_esg_percent_coverage <dbl>, …
#?fct_reorderten_small <- blackrock_etf_screener_w_new_features %>%filter(standard_or_esg =="ESG") %>%arrange(net_assets_bn_usd) %>%head(10)ten_small$name <-fct_reorder(ten_small$name,ten_small$net_assets_bn_usd)ggplot(ten_small) +aes(x= net_assets_bn_usd ,y=name) +geom_bar(stat="identity") +labs(title="10 Smallest ETFs in Net Assets (BN Dollars)",x="Net Assets (in billion USD)",y="ETF Name")+theme_classic()
Homework 3: Find the funds
Find the funds in the bottom quintile of the MSCI ESG quality score. calculate the number of funds by total assets by asset class and sub asset class.
bottom_quintile_threshold <-quantile(blackrock_etf_screener_w_new_features$msci_esg_quality_score_0_10, 0.2, na.rm =TRUE)# Filter the funds in the bottom quintilebottom_quintile_funds <- blackrock_etf_screener_w_new_features %>%filter(msci_esg_quality_score_0_10 <= bottom_quintile_threshold) %>%group_by(asset_class, sub_asset_class) %>%summarize(number_of_funds =n(),total_assets_usd =sum(net_assets_usd),.groups ="drop", )# view tibbleprint(bottom_quintile_funds)
# A tibble: 9 × 4
asset_class sub_asset_class number_of_funds total_assets_usd
<chr> <chr> <int> <dbl>
1 Equity All Cap 23 95486052602.
2 Equity Large Cap 1 1852506812.
3 Equity Large/Mid Cap 10 42421984678.
4 Equity Small Cap 17 187292555389.
5 Fixed Income Corporates 1 41339182.
6 Fixed Income Credit 1 408038372.
7 Fixed Income Government 3 17560711395.
8 Fixed Income High Yield 16 38239624578.
9 Real Estate Real Estate Securities 4 7145439523.
Homework 4
Graph 1 Asset Class Distribution of ESG Funds
# Calculate the number of funds issued per year for each fund type (Standard and ESG)funds_issued_per_year <- blackrock_etf_screener_w_new_features %>%group_by(inception_year, standard_or_esg, asset_class) %>%summarise(n_funds =n(), .groups ='drop')ggplot(funds_issued_per_year, aes(x = inception_year, y = n_funds, fill = standard_or_esg)) +geom_bar(stat ="identity") +labs(title ="Number of Standard and ESG Funds Issued Per Year",x ="Year",y ="Number of Funds",fill ="Fund Type") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1)) # Improve readability
Graph 2
# Calculate the average net and gross expense ratios for each year, for standard and ESG fundsexpense_ratios_by_year <- blackrock_etf_screener_w_new_features %>%group_by(inception_year, standard_or_esg) %>%summarize(avg_net_expense_ratio =mean(net_expense_ratio_percent, na.rm =TRUE),avg_gross_expense_ratio =mean(gross_expense_ratio_percent, na.rm =TRUE),.groups ='drop' )# Reshape for plottingexpense_ratios_long <- expense_ratios_by_year %>%pivot_longer(cols =starts_with("avg_"), names_to ="expense_type", values_to ="average_ratio") %>%mutate(expense_type =factor(expense_type, levels =c("avg_net_expense_ratio", "avg_gross_expense_ratio"), labels =c("Net Expense Ratio", "Gross Expense Ratio")))ggplot(expense_ratios_long, aes(x = inception_year, y = average_ratio, color = expense_type, group =interaction(standard_or_esg, expense_type))) +geom_line() +facet_wrap(~standard_or_esg, scales ="free_y") +labs(title ="Comparison of Average Net and Gross Expense Ratios by Fund Type Over Years",x ="Year",y ="Average Expense Ratio (%)",color ="Expense Type") +theme_minimal()
Graph 3 Net Assets USD Composition Comparison: Standard vs. ESG Funds
ggplot(blackrock_etf_screener_w_new_features, aes(x=standard_or_esg, y=net_assets_usd, fill=asset_class)) +geom_bar(stat="summary", fun="sum", position="dodge") +labs(title="Net Assets USD Composition Comparison: Standard vs. ESG Funds",x="Fund Type", y="Net Assets (USD)", fill="Asset Class") +scale_y_log10() +#log10 to improve readability but don't know how to make the x axis num showtheme_minimal() +theme(axis.text.x =element_text(angle=45, hjust=1)) # Improve x-axis labels readability
Graph 4 Share of Funds by Fund Type and Region
# Aggregating net_assets_usd by standard_or_esg and regionfunds_aggregated <- blackrock_etf_screener_w_new_features %>%group_by(standard_or_esg, region) %>%summarize(total_net_assets_usd =sum(net_assets_usd, na.rm =TRUE), .groups ='drop')# Calculate the proportion for the pie chartfunds_aggregated <- funds_aggregated %>%mutate(proportion = total_net_assets_usd /sum(total_net_assets_usd))ggplot(funds_aggregated, aes(x="", y=proportion, fill=factor(paste(standard_or_esg, region)))) +geom_bar(width =1, stat ="identity", color ="white") +coord_polar("y", start=0) +scale_fill_brewer(palette="Set3", name="Fund Type and Region") +labs(title="Share of Funds by Standard/ESG and Region, Weighted by Net Assets", x="", y="") +theme_void() +theme(legend.title =element_text(size=10), legend.text =element_text(size=9))
Graph 5 Average MSCI Weighted Average Carbon Intensity Over Years by Fund Type
#blackrock_etf_screener_w_new_features <- blackrock_etf_screener_w_new_features %>%# rename(MSCI_WACI = msci_weighted_average_carbon_intensity_tons_co2e_m_sales) added to top# Calculate the average MSCI_WACI per year for standard and ESG fundsavg_MSCI_WACI_per_year <- blackrock_etf_screener_w_new_features %>%group_by(inception_year, standard_or_esg) %>%summarize(average_MSCI_WACI =mean(MSCI_WACI, na.rm =TRUE), .groups ='drop')ggplot(avg_MSCI_WACI_per_year, aes(x =inception_year, y = average_MSCI_WACI, color = standard_or_esg)) +geom_point() +geom_smooth(method ="lm") +labs(title ="Average MSCI WACI Over Years by Fund Type",x ="Year", y ="Average MSCI WACI (tCO2e/$M sales)",color ="Fund Type") +theme_minimal()
`geom_smooth()` using formula = 'y ~ x'
Graph 6 Bonue Graph: Average MSCI WACI Over Years by ESG Classification
# Filter for ESG funds and calculate the average MSCI_WACI per year for each ESG classificationavg_MSCI_WACI_per_year_esg <- blackrock_etf_screener_w_new_features %>%filter(standard_or_esg =="ESG") %>%group_by(inception_year, sustainable_classification) %>%summarize(average_MSCI_WACI =mean(MSCI_WACI, na.rm =TRUE), .groups ='drop')ggplot(avg_MSCI_WACI_per_year_esg, aes(x = inception_year, y = average_MSCI_WACI, color = sustainable_classification)) +geom_point() +geom_smooth(method ="lm") +labs(title ="Average MSCI WACI Over Years by ESG Classification",subtitle ="Note that we don't yet have enough datapoints for this attempt",x ="Year", y ="Average MSCI WACI",color ="ESG Classification") +theme_minimal()