0

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.

Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
bigjdawg43
  • 93
  • 1
  • 1
  • 7

1 Answers1

0

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)
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Ok that's pretty close. And yes, I believe that's what I want. Tickers (e.g., AAPL, and ABBV) on the x axis with two columns per ticker, one for weight and one stacked as you put together above. Are you basically saying that's not possible? If it's not possible in the way I've described it, I think your solution will definitely work. Bigger picture, I'm trying to run through this exercise with multiple portfolios, each with 30 or so stocks. If I can get it down where all tickers would be on x axis and two columns per ticker, my thought was to facet on the portfolio level, if possible. – bigjdawg43 Apr 26 '18 at 15:46
  • As an update to this, I believe I understand what you're talking about. Is it possible then to make the factor and specific values part of a stacked chart and have the weight be a line chart? I can do this in excel but because I'm doing this with multiple portfolios, I wanted to incorporate faceting each portfolio to have more of a clean appearance – bigjdawg43 Apr 26 '18 at 16:21
  • With my first answer, you could use `facet_grid(portfolio ~ ticker)` to put portfolios in rows and tickers in columns. From a design perspective, a ggplot bar layer has a `position` argument. The default position is `"stack"`, an alternative is `"dodge"` (next to each other). At a single x-value, you want a single value dodged, and the other values stacked, which isn't supported - you have to pick one. – Gregor Thomas Apr 26 '18 at 16:47
  • There are a couple hacks to get around - you could paste the ticker value together with my "Type" variable, and then AAPL-weight and AAPL-risk would be different x values (labeling this nicely could be a real pain). Or, as you suggest, you could do a line for the weight - that wouldn't be too hard. Just give `geom_col` the risk subset, and add a `geom_line` layer with the weight subset. I don't have time now, but I can try to add some examples later. – Gregor Thomas Apr 26 '18 at 16:49
  • Yes, I think the line for weight would probably be easiest. Thanks so much for your help, very much appreciated. Seeing as how I'm so new, any examples would be great when you have a second. I'll play around in the meantime. – bigjdawg43 Apr 26 '18 at 17:42
  • That's perfect, thank you so much. Is it possible to add markers and remove line segments are left. Essentially, that leaves a floating marker. But maybe id be better served if I used geom_point for that? I'm not sure. Also, if we assume another column "Portfolio," say Portfolio 1 holding only APPL and Portfolio 2 holding only ABBV, how could I then facet on that category so that Portfolio 1 would be on top and Portfolio 2 would be immediately below? Thanks so much again. – bigjdawg43 Apr 26 '18 at 21:52
  • If you don't want line segments then yes, use `geom_point` (you also can get rid of the `group = 1` if you do that). As for the rest, if you have additional questions I'd recommend asking a new question focused on that. – Gregor Thomas Apr 27 '18 at 12:24
  • Thank you very much, will do. – bigjdawg43 Apr 27 '18 at 14:56