Search code examples
rggplot2chartsfacet

Using geom_point with geom_col and faceting


I have the below example code that's been melted from a dataframe (this is an example; in reality I have 8 portfolios with 30 tickers per portfolio):

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

This also assumes US portfolio is composed of only AAPL and INTL portfolio is composed only of ABBV. I have some code that allows me to build a stacked bar chart (for risk) and a line (for weight):

Raw_Portfolio_Data_melt$Type = factor(ifelse(Raw_Portfolio_Data_melt$variable == "Weight", "Weight", "Risk"),
             levels = c("Weight", "Risk"))

ggplot(Raw_Portfolio_Data_melt, aes(x = Ticker, y = value)) +
  geom_col(data = subset(Raw_Portfolio_Data_melt, variable != "Weight"), aes    (fill = variable)) +
  geom_line(data = subset(Raw_Portfolio_Data_melt, variable == "Weight"), aes   (group = 1, color = variable)) +
  scale_color_manual(values = "black") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Two questions (very new to R and even newer to ggplot) 1. How can I adjust the line so as to use geom point (basically just have a marker instead of a line) for weight 2. How can I facet on portfolios so that US will be a chart of stocks and INTL will be a chart right underneath US?

Thank you for any and all help.


Solution

  • Here's an example that should help. I built dummy data off of what you posted, just so you could see more being plotted on the x-axes.

    I used fct_collapse from forcats (ships with tidyverse) to collapse variable into Risk or Weight. What you wanted to do with this, I wasn't entirely clear on, so feel free to correct me on that.

    For faceting, you tell it what column you want to split on--in your case, Portfolio. To get a single column (you said you wanted one below the other), use ncol = 1, and to get only x-axis labels that occur in each portfolio, use scales = "free_x".

    library(tidyverse)
    
    dummy <- tibble(
        Ticker = rep(letters[1:6], each = 3),
        variable = rep(c("Factor_Risk", "Stock_Specific_Risk", "Weight"), times = 6),
        value = runif(18, 0, 1),
        Portfolio = rep(c("US", "INTL"), each = 9)
        ) %>%
        arrange(Ticker, variable, Portfolio) %>%
        mutate(type = as.factor(variable) %>% fct_collapse(Risk = c("Factor_Risk", "Stock_Specific_Risk")))
    
    
    ggplot(dummy, aes(x = Ticker, y = value)) +
            geom_col(data = . %>% filter(type == "Risk")) +
            geom_point(data = . %>% filter(type != "Risk")) +
            facet_wrap(~ Portfolio, ncol = 1, scales = "free_x")
    

    Created on 2018-04-30 by the reprex package (v0.2.0).