The goal of this report is to use R Markdown to analyze the recent GDP release from the Bureau of Economic Analysis. The data includes figures for the last three fiscal years, but this report will be focusing on the three quarters of FY23 data that is available in the most recent release (December 21, 2023).

Each quarter is subdivided in advance, second, and third estimates. The terms “advance,” “second,” and “third” estimates refer to different stages in the process of economic data reporting and revision. Here’s an explanation of each term:

The advance estimate is the first release of economic data for a particular period. It is typically released shortly after the end of the reference period, providing an initial snapshot of economic performance. The advance estimate is based on a subset of available data and statistical models, and it is subject to revision as more comprehensive data becomes available.

The second estimate is an updated release of economic data that occurs after the advance estimate. It incorporates additional data and revisions, providing a more accurate picture of economic indicators.

The third estimate incorporates even more comprehensive data, adjustments, and revisions based on additional information that becomes available over time. The third estimate is often considered more accurate and reliable than the advance and second estimates.

The exact data set used in this analysis is not directly supplied by the BEA. The data set was manually created by inputting values from all 9 GDP releases from FY23.

data <- read_excel("FY23 GDP Revision Summary.xlsx")

df <- data %>%
  clean_names() %>% 
  pivot_longer(cols = 2:19, names_to = "period", values_to = "value") %>% 
  rename(name = x1) %>% 
  separate(period, into = c("quarter", "estimate"), sep = 3) %>% 
  mutate(quarter = toupper(str_remove(quarter,"_"))) %>% 
  separate(estimate, into = c("release_type", "estimate"), sep = "_") %>% 
  group_by(quarter) %>% 
  mutate(estimate_var = if_else(estimate != "advance", value - lag(value), NA)) %>% 
  mutate(full_estimate_var = if_else(estimate == "third", value - lag(value,2), NA)) %>% 
  ungroup()
  
head(df)
## # A tibble: 6 × 7
##   name        quarter release_type estimate value estimate_var full_estimate_var
##   <chr>       <chr>   <chr>        <chr>    <dbl>        <dbl>             <dbl>
## 1 Gross Dome… Q1      delta        advance    1.1       NA                NA    
## 2 Gross Dome… Q1      delta        second     1.3        0.2              NA    
## 3 Gross Dome… Q1      delta        third      2          0.7               0.9  
## 4 Gross Dome… Q2      delta        advance    2.4       NA                NA    
## 5 Gross Dome… Q2      delta        second     2.1       -0.300            NA    
## 6 Gross Dome… Q2      delta        third      2.1        0                -0.300

Desciption of Variables:

name - components involved in calculation of GDP
quarter - fiscal quarter of 2023
release_type - delta represents the percent change from proceeding period and contribution represents contribution to percent change in GDP
estimate - represents each quarterly revision
value - in percentage points, percent change from proceeding period or contribution to percent change in GDP
estimate_var - represents the variance from the advance to second estimate and the second to third estimate
full_estimate_var - represents the variance from the advance to third estimate


The first analysis is a summary of the final Q3 estimates, which shows GDP and the four main components used in its calculations.

delta_summary <- df %>% 
  filter(name %in% c("Gross Domestic Product",
                     "Personal Consumption Expenditures",
                     "Gross Private Domestic Investment",
                     "Net Exports of Goods and Services",
                     "Government Consumption Expenditures and Gross Investment")) %>% 
  filter(release_type == "delta") %>% 
  filter(quarter == "Q3") %>% 
  filter(estimate == "third")

ggplot(delta_summary, aes(x = reorder(name, value), y = value, fill = name)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Percent Change of Q3 GDP and Corresponding Components",
       x = "",
       y = "Percent Change") +
  theme(plot.title = element_text(hjust = -0.3)) +
  scale_fill_brewer(palette = 18) +
  theme(axis.text.x = element_blank()) +
  guides(fill = guide_legend(reverse = F, title = "Components"))






Next, let’s take a look at the final Q3 contributions of these four components. Consumer spending and private investment were the main drivers of Q3 GDP expansion.

contribution_summary <- df %>% 
  filter(name %in% c("Gross Domestic Product",
                     "Personal Consumption Expenditures",
                     "Gross Private Domestic Investment",
                     "Net Exports of Goods and Services",
                     "Government Consumption Expenditures and Gross Investment")) %>% 
  filter(release_type == "contribution") %>% 
  filter(quarter == "Q3") %>% 
  filter(estimate == "third")

gdp_data <- contribution_summary %>% filter(name == "Gross Domestic Product")
categories_data <- contribution_summary %>% filter(name != "Gross Domestic Product")

ggplot() +
  geom_bar(data = gdp_data, aes(x = "GDP", y = value), stat = "identity", fill = "darkred") +
  geom_bar(data = categories_data, aes(x = "Components", y = value, fill = reorder(name, value)), stat = "identity", position = "stack") +
  geom_text(data = categories_data, aes(x = "Components", y = value, label = sprintf("%.2f%%", value), group = reorder(name, value)),
            position = position_stack(vjust = .2), color = "black", size = 5) +
  geom_text(data = gdp_data, aes(x = "GDP", y = value, label = sprintf("%.1f%%", value)),
            position = position_stack(vjust = .5), color = "black", size = 5) +
  labs(title = "Summary of Contributions to Percent Change in Q3 GDP",
       x = "",
       y = "") +
  theme(plot.title = element_text(hjust = -0.6)) +
  scale_fill_brewer(palette = 18, direction = -1) +
  guides(fill = guide_legend(reverse = T, title = "Components")) +
  coord_cartesian(ylim = c(0, 5.2), clip = "off")







When reviewing Gross Domestic Product as a whole, it can be observed that Q1 experienced a substantial revision from the advance to third estimate. Q2 GDP remained relatively flat across all three estimates, as well as from Q1’s third estimate. All Q3 estimates reflect strong economic expansion.

gdp <- df %>% 
  filter(name == "Gross Domestic Product") %>% 
  filter(release_type == "delta")

ggplot(gdp, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "FY23 Gross Domestic Product Estimates and Revisions ",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







To understand what is driving the large increase in Q3 GDP, let’s look closer at what is under the hood.

Personal Consumption Expenditures is used to measure the total value of goods and services consumed by households in an economy over a specific period. Personal Consumption Expenditures are a crucial component of the Gross Domestic Product calculation, representing the portion of GDP attributed to consumer spending.

Looking at Q3, it is clear that strong consumer spending was a material driver for the growth seen in GDP. It is important to note the revisions to Q3, as the third estimate ended up being a large miss to the advance estimate. This tells us that consumer spending was not as strong as anticipated. The previous plot showed no variance between the advance and third estimates of Q3 GDP, however, PCE had a whole percentage point variance between the estimates. This hints that at least 1 of the 3 other components displayed a significant variance between the advance and third estimates.

pce <- df %>% 
  filter(name == "Personal Consumption Expenditures") %>% 
  filter(release_type == "delta")

ggplot(pce, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "FY23 Personal Consumption Estimates and Revisions ",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







Gross Private Domestic Investment measures the total value of all capital expenditures made by private businesses, households, and nonprofit organizations within a country’s borders. It provides insights into the level of investment activity in an economy.

Focusing on Q3, it can be seen that this component was a significant driver of GDP expansion. The advance to third variance in Q3 is in line with the assumption at the end of the previous section.

gpdi <- df %>% 
  filter(name == "Gross Private Domestic Investment") %>% 
  filter(release_type == "delta")

ggplot(gpdi, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "FY23 Gross Private Domestic Investment Estimates and Revisions ",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







Government consumption refers to the total value of goods and services purchased and consumed by the government at all levels (federal, state, and local) within a country’s borders. This includes spending on salaries for public employees, public infrastructure, defense, education, healthcare, and other government services. Government consumption represents the value of resources used by the government to provide public goods and services. It’s a crucial component of GDP because it reflects the direct contribution of the government to the economy through the provision of services and the employment of resources.

Gross Investment represents the total value of spending on capital goods (such as machinery, equipment, and structures) that will be used to produce future goods and services. It includes both business and government investment. Gross Investment reflects the level of capital formation and the expansion of the economy’s productive capacity. It is a key driver of future economic growth.

gcegi <- df %>% 
  filter(name == "Government Consumption Expenditures and Gross Investment") %>% 
  filter(release_type == "delta")

ggplot(gcegi, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "FY23 Government Consumption & Gross Investment Estimates and Revisions ",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







Exports and imports are vital components of international trade, and they reveal important information about a country’s economic health, competitiveness, and relationships with other nations.

exim <- df %>%
  filter(name %in% c("Exports", "Imports")) %>% 
  filter(release_type == "delta")

ggplot(exim, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  facet_grid(. ~ name, scales = "free_y") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "FY23 Exports and Imports Estimates and Revisions",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







Net Exports and Imports.

exim <- df %>%
  filter(name == "Net Exports of Goods and Services") %>% 
  filter(release_type == "delta")

ggplot(exim, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  facet_grid(. ~ name, scales = "free_y") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "FY23 Net Exports and Imports Estimates and Revisions",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







Let’s look closer at what makes up the percent change in Government Consumption Expenditures and Gross Investment.

National Defense spending remained strong in 2023, with a large increase in Q3. Interestingly, State and Local spending was revised significantly in all three quarters.

deep_gcegi <- df %>%
  filter(name %in% c("National Defense", "Nondefense", "State and Local")) %>% 
  filter(release_type == "delta")

ggplot(deep_gcegi, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  facet_grid(. ~ name, scales = "free_y") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "Breakdown of Government Consumption Expenditures and Gross Investment",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







Analyzing the percent change in subgroups of GDP provided a glimpse of what the major drivers of growth were. To get a clearer picture of what is driving GDP expansions or contractions, we can analyze the Contributions to Percent Change in Real Gross Domestic Product. Contributions factor in the relative size of each component to the economy.

It is clear that Personal Consumption Expenditures was the largest driving force of GDP expansion in 2023. Gross Private Domestic Investment was also a driver of expansion in Q3.

contributions <- df %>% 
  filter(name %in% c("Personal Consumption Expenditures",
                     "Gross Private Domestic Investment",
                     "Net Exports of Goods and Services",
                     "Government Consumption Expenditures and Gross Investment")) %>% 
  filter(release_type == "contribution")

contributions$name <- str_wrap(contributions$name, width = 20)

ggplot(contributions, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  facet_grid(. ~ name, scales = "free_y") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "Contributions to GDP Growth",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







Government Consumption Expenditures and Gross Investment can be subdivided into two main categories: Federal and State & Local. Both categories contain Consumption Expenditures and Gross investment, with Federal grouping this into National Defense and Nondefense.

gov_spending <- df %>% 
  filter(name %in% c("Federal",
                     "National Defense",
                     "Nondefense",
                     "State and Local")) %>% 
  filter(release_type == "contribution")

ggplot(gov_spending, aes(x = quarter, y = value, fill = estimate)) +
  geom_col(position = "dodge") +
  facet_grid(. ~ name, scales = "free_y") +
  geom_hline(yintercept = 0, color = "black", linetype = "solid", linewidth = 1) +
  labs(title = "Government Consumption and Gross Investment Contributions to GDP Growth",
       x = "Quarter",
       y = "Value") +
  scale_fill_brewer(palette = 18)







This concludes the report.

Further analysis regarding the subcategories of each component and the statistical significance of revisions will be released soon.