R中VAR模型历史方差误差分解ggplot绘图问题求助
Hey there, let's figure out why your ggplot isn't matching Daniel Ryback's Excel chart, and get it sorted step by step!
First, let's break down the core issues with your current code:
- Your
geom_bar(stat="identity")is stacking raw variance values, but historical variance decomposition plots (like the Excel version) almost always use 100% stacked bars where each period's bar sums to 100% (showing the proportion of variance each variable explains). - You're working with raw contribution values instead of normalizing them to percentages.
- There are small typos in your column names ("Emplyment" vs "Employment", "Unemplyment" vs "Unemployment") that might be causing confusion when cross-checking with Excel.
Here's the corrected approach:
Step 1: Normalize Values to Percentages
First, convert each row's variance contributions to percentages so every period adds up to 100%. This matches how the Excel chart is likely presenting the data:
# Normalize each row to percentages (base R version) ex2_pct <- ex2 ex2_pct[,1:4] <- apply(ex2[,1:4], 1, function(x) x / sum(x) * 100)
Step 2: Adjust ggplot for 100% Stacked Bars
Use position = "fill" in geom_bar to create the 100% stack, and format the y-axis to show percentages:
molten.ex_pct <- melt(ex2_pct, id = "Period") ggplot(molten.ex_pct, aes(x = Period, y = value, fill = variable)) + geom_bar(stat = "identity", position = "fill") + # Critical for 100% stack scale_y_continuous(labels = scales::percent_format()) + # Show y-axis as % guides(fill = guide_legend(reverse = TRUE)) + labs(y = "Variance Explained (%)", x = "Period", fill = "Variable") + theme_bw() # Clean theme to match typical Excel visuals
Step 3: Fix Typos & Align Variable Order
First, correct those column name typos to match your Excel data (this avoids mix-ups):
colnames(ex2) <- c("Employment", "Productivity", "Real Wages", "Unemployment")
If the Excel chart has variables in a specific order, reorder the factor levels to match:
molten.ex_pct$variable <- factor(molten.ex_pct$variable, levels = c("Employment", "Productivity", "Real Wages", "Unemployment"))
Full Corrected Code
Here's the full working code with all fixes:
library(vars) library(ggplot2) library(reshape2) library(scales) # For percentage formatting # Assuming you've already loaded the VARhd function from the tutorial data(Canada) ab <- VAR(Canada, p = 2, type = "both") HD <- VARhd(Estimation = ab) ex <- HD[,,1] ex1 <- as.data.frame(ex) ex2 <- ex1[3:84,1:4] # Fix column name typos colnames(ex2) <- c("Employment", "Productivity", "Real Wages", "Unemployment") ex2$Period <- 1:nrow(ex2) # Normalize to percentages ex2_pct <- ex2 ex2_pct[,1:4] <- apply(ex2[,1:4], 1, function(x) x / sum(x) * 100) # Reshape data for ggplot molten.ex_pct <- melt(ex2_pct, id = "Period") # Create matching 100% stacked bar chart ggplot(molten.ex_pct, aes(x = Period, y = value, fill = variable)) + geom_bar(stat = "identity", position = "fill") + scale_y_continuous(labels = percent) + guides(fill = guide_legend(reverse = TRUE)) + labs(y = "Variance Explained (%)", x = "Period", fill = "Variable") + theme_bw()
Quick Check
Before plotting, double-check that head(ex2_pct) matches your Excel values—this confirms your raw data is aligned correctly. The main fix here is the position = "fill" argument and percentage normalization, which should make your ggplot match the Excel chart perfectly.
内容的提问来源于stack exchange,提问作者asalasa209

