Search code examples
rggplot2melt

Plotting two columns, one stacked using melt and ggplot


I've searched all over the place and can't seem to find the answer to this question. I have a dataframe with a number of variables that I'd like to make into a barplot.

That code is here:

Raw_Portfolio_Data <- read_excel("RData2.xlsx", range = "Exposures!  
A10:E47", col_names = FALSE)
Raw_Portfolio_Data <- na.omit(Raw_Portfolio_Data)
Raw_Portfolio_Data <- round(Raw_Portfolio_Data, 2)

names(Raw_Portfolio_Data) <- c  
("Ticker", "Factor_Risk", "Stock_Specific_Risk", "Total_Risk", "Weight")
Raw_Portfolio_Data_melt <- melt(Raw_Portfolio_Data, id.vars = "Ticker")
Raw_Portfolio_Data_melt$value <- round(Raw_Portfolio_Data_melt$value, 2)

The "melted" variable looks like this (only an example of a couple tickers)

Ticker       variable         value
AAPL          Factor_Risk      4.66
ABBV          Factor_Risk      1.71
AAPL          Stock_Specific_Risk 0.21
ABBV          Stock_Specific_Risk 0.07
AAPL          Weight              4.00
ABBV          Weight              1.66

That said, my goal is to have Ticker on the X axis and two bars for each ticker. One bar will represent weight, and one will be STACKED and a combination of factor risk and stock specific risk figures.

So far, I haven't made much progress...

ggplot(Raw_Portfolio_Data_melt, aes(x = Ticker, y = value))

Can anyone help me please? As you can tell, I'm new to R and VERY new to ggplot2. Thanks for your time.


Solution

  • To me it sounds like you want two variables on the x-axis, Ticker, and weight/risk. We can't actually have two variables on the x-axis, but an easy way to get around this is to use faceting, we can facet by Ticker and create the weight/risk variable for the x-axis. Calling your data dd for brevity...

    dd$Type = factor(ifelse(dd$variable == "Weight", "Weight", "Risk"),
                     levels = c("Weight", "Risk"))
    ggplot(dd, aes(x = Type, y = value, fill = variable)) +
        geom_col() +
        facet_wrap(~Ticker)
    

    enter image description here


    Using a line for weight instead:

    ggplot(dd, aes(x = Ticker, y = value)) +
        geom_col(data = subset(dd, variable != "Weight"), aes(fill = variable)) +
        geom_line(data = subset(dd, variable == "Weight"), aes(group = 1, color = variable)) +
        scale_color_manual(values = "black")
    

    enter image description here


    Using this data:

    dd = read.table(text = "Ticker       variable         value
    AAPL          Factor_Risk      4.66
    ABBV          Factor_Risk      1.71
    AAPL          Stock_Specific_Risk 0.21
    ABBV          Stock_Specific_Risk 0.07
    AAPL          Weight              4.00
    ABBV          Weight              1.66", header = T)