Search code examples
rggplot2facet-wrap

include geom_abline() only on corresponding facets in facet_wrap()


I would like to add regression lines from a multi-level model to a facetted plot with ggplot. I thought the code would be something like this:

ggplot(merged_data, 
       aes(x = log_wealth_per_capita,  
           y = log_total_deaths_per_million)) +
       geom_text(aes(label = iso3), size = 3) + 
       geom_abline(data = beta_mean, aes(intercept = Intercept, slope = Slope), 
                   color = "red") +  # Add fitted lines
       facet_wrap(~ Continent) +  # Facet by continent
       labs(x = "Log(Wealth per Capita)", 
            y = "Log(Total Deaths per Million)") +  
       ggtitle("Scatterplots of Wealth per Capita vs. Total Deaths per Million, 
        by Continent") +  
       theme_minimal()  

The result is quite comical, with six regression lines on each plot, but I only want one regression line per plot--and the one associated with the respective continent.

enter image description here

The merged_data object is dput() below, but first I should explain how created the data frame of regression coefficients. The following extracts the coefficients from the object fit in Stan.

beta_samples <- extract(fit_var_int_var_slope_rob, "beta_c")
beta_mean <- data.frame(apply(beta_samples$beta, c(2, 3), mean))
colnames(beta_mean) <- c("Intercept", "Slope")

This produces the following:

structure(list(Intercept = c(9.64732954916488, 7.13774770517295, 
7.42222605208451, 8.00996749651911, 6.66528812477884, 8.12939250271545
), Slope = c(0.792835920084033, 0.217933401272108, -0.183173179979844, 
0.15706373664177, -0.0123708482256735, 0.064920576319393)), class = "data.frame", row.names = c(NA, 
-6L))

I can extract a list of continents with unique(merged_data$Continent) which returns:

 [1] Europe        Asia          South America Oceania       North America Africa       
 Levels: Africa Asia Europe North America Oceania South America

So my question is, how can I add one fitted line per plot, fitting the right line to the data for the respective continent.

For reproducibility the full dataset is:
structure(list(iso3 = c("ALB", "ARE", "ARG", "ARM", "AUS", "AUT", 
"AZE", "BEL", "BGD", "BGR", "BHR", "BHS", "BIH", "BLR", "BLZ", 
"BOL", "BRA", "BRB", "BWA", "CAF", "CAN", "CHE", "CHL", "CHN", 
"CMR", "COD", "COG", "COL", "COM", "CRI", "CYP", "DEU", "DJI", 
"DNK", "DZA", "ECU", "EGY", "ESP", "EST", "ETH", "FIN", "FJI", 
"FRA", "GAB", "GBR", "GEO", "GMB", "GNB", "GNQ", "GRC", "GUY", 
"HRV", "HUN", "IDN", "IND", "IRL", "IRN", "ISL", "ISR", "ITA", 
"JAM", "JOR", "JPN", "KAZ", "KEN", "KGZ", "KHM", "KOR", "KWT", 
"LAO", "LBN", "LBR", "LBY", "LKA", "LSO", "LTU", "LUX", "LVA", 
"MAR", "MDG", "MEX", "MLI", "MLT", "MNE", "MNG", "MOZ", "MUS", 
"MWI", "MYS", "NAM", "NIC", "NLD", "NOR", "NPL", "NZL", "OMN", 
"PAK", "PAN", "PER", "PHL", "POL", "PRT", "QAT", "ROU", "RUS", 
"SAU", "SEN", "SGP", "SLE", "SLV", "SRB", "SVK", "SVN", "SWE", 
"SYC", "SYR", "TCD", "THA", "TJK", "TTO", "TUN", "TUR", "UKR", 
"URY", "USA", "VNM", "ZAF", "ZMB"), Continent = structure(c(3L, 
2L, 6L, 2L, 5L, 3L, 2L, 3L, 2L, 3L, 2L, 4L, 3L, 3L, 4L, 6L, 6L, 
4L, 1L, 1L, 4L, 3L, 6L, 2L, 1L, 1L, 1L, 6L, 1L, 4L, 3L, 3L, 1L, 
3L, 1L, 6L, 1L, 3L, 3L, 1L, 3L, 5L, 3L, 1L, 3L, 2L, 1L, 1L, 1L, 
3L, 6L, 3L, 3L, 2L, 2L, 3L, 2L, 3L, 2L, 3L, 4L, 2L, 2L, 2L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 3L, 3L, 3L, 1L, 1L, 4L, 
1L, 3L, 3L, 2L, 1L, 1L, 1L, 2L, 1L, 4L, 3L, 3L, 2L, 5L, 2L, 2L, 
4L, 6L, 2L, 3L, 3L, 2L, 3L, 3L, 2L, 1L, 2L, 1L, 4L, 3L, 3L, 3L, 
3L, 1L, 2L, 1L, 2L, 2L, 4L, 1L, 2L, 3L, 6L, 4L, 2L, 1L, 1L), levels = c("Africa", 
"Asia", "Europe", "North America", "Oceania", "South America"
), class = "factor"), log_total_deaths_per_million = c(7.14517957334583, 
5.51666945712612, 7.96268245052562, 8.05704135351535, 6.83514372509745, 
7.83228795255029, 6.90726515889291, 7.98822260566744, 5.14861013330701, 
8.64751910196815, 6.95015363039875, 7.6297775329487, 8.53024188569712, 
6.61541705010521, 7.43695368477318, 7.51273605212519, 8.08975881654283, 
7.6522987486255, 6.97027645414495, 3.00835230491009, 7.24680490556415, 
7.39148243340391, 8.06245453732848, 4.44835261984536, 4.25867185564378, 
2.69644984303589, 4.17675369846282, 7.91987060378204, 5.25336184074617, 
7.50008826037499, 7.32871702487983, 7.64913484913657, 5.1276595234134, 
7.37928649087916, 5.03201184552246, 7.60137434818512, 5.41036845035541, 
7.84859929666797, 7.71477519325648, 4.11721437631285, 7.62994122367463, 
6.85840640876554, 7.86300361247569, 4.85597559585221, 8.14271528238069, 
8.42844590861355, 4.9234275341884, 4.43155462182308, 4.69372121044537, 
8.21599971634834, 7.38241368293539, 8.44172734392078, 8.50008182343079, 
6.37658578147253, 5.93053550396008, 7.53707195436871, 7.41295953241003, 
6.21218316063569, 7.20399909488331, 8.10421180673984, 7.1468351695947, 
7.13193749070183, 6.40126358350027, 6.89080645571083, 4.65679442560723, 
5.03977329583958, 5.20540131852172, 6.54174402992356, 6.40030893899961, 
4.48993889186828, 7.59793907304635, 4.01537350235111, 6.85108121841244, 
6.6510937231183, 5.72841654894787, 8.175756693213, 7.3422359997599, 
8.30244157907528, 6.07569999142584, 3.87446650670151, 7.8736118740934, 
3.49301662675331, 7.42102850492459, 8.3505010957726, 6.51038630852537, 
4.22310417130816, 6.70217287413362, 4.88001015042657, 7.00201945737222, 
7.37672650047835, 3.56274917696972, 7.17678802882614, 6.96108464915987, 
5.97595743088023, 6.5492314841142, 6.91898894442494, 4.86749598817746, 
7.5822235905929, 8.780734608921, 6.35960154995015, 8.01192675337012, 
7.90811028272797, 5.54524384852477, 8.15793605935459, 7.92785704669004, 
5.57948828738416, 4.73463582462489, 5.84827812288232, 2.67587130273798, 
6.50364724962591, 7.87389960937892, 8.23159002321146, 8.44469647433975, 
7.83586785665906, 7.38115999297662, 4.96255787586308, 2.39297409272173, 
6.17675876449841, 2.53043754003599, 7.96113516712754, 7.77538083887501, 
7.08035809477059, 7.92609488909099, 7.7133092915014, 8.14330756105566, 
6.08686335934797, 7.44596997418451, 5.31453514457087), log_wealth_per_capita = c(-3.75898035360504, 
-2.30513018407809, -5.15826474719596, -4.13704891468614, -1.01815206669121, 
-1.56998235269109, -4.63158176044283, -1.18050664725151, -5.2270293779777, 
-3.4695614743071, -2.55643252841621, -3.30866733261863, -3.79008962183494, 
-4.04530785241544, -5.04430577861233, -4.91974126137638, -4.2520217105767, 
-2.89272421693947, -4.68474649927825, -7.92285291901668, -1.27905696134074, 
-0.614474094883125, -3.26474959140575, -2.94887236699916, -6.48256023935423, 
-7.5666038756891, -7.25859957831427, -4.46477625706788, -5.7859018934777, 
-3.43352741677342, -2.5013673515235, -1.56489315157883, -6.31647917483157, 
-1.18541971461973, -5.14110219738108, -4.44117978341142, -4.35986153060899, 
-1.7200350530719, -2.8384891497519, -6.2716115443935, -1.88859060820926, 
-4.53978745885536, -1.42309330171415, -4.89232991805667, -1.4537706667511, 
-4.45613846126653, -6.79811831800763, -7.11218217128348, -4.68824594167466, 
-2.40801457277519, -4.8745396859623, -2.98084579253421, -3.07468943312031, 
-4.47821640025086, -4.70001102996997, -1.73184554135212, -4.10271593112113, 
-1.30912002570409, -1.95269182439728, -1.58547855882824, -4.2276029333948, 
-4.08318652004516, -1.53290984434818, -3.6936200969551, -5.06516163946559, 
-5.74974884455749, -5.68925590637949, -1.68871303977341, -2.35561281223366, 
-5.44495224256278, -2.91323997827936, -6.11029672207666, -4.54655264066805, 
-4.08646388905808, -7.07601986150314, -3.05933449608398, -0.723129242676512, 
-2.80938485340546, -4.68640604945897, -6.89095712714412, -3.50788258121201, 
-6.92556251317859, -2.19411235662953, -2.98369142842271, -5.55221071457427, 
-7.7634924031241, -3.05625388797155, -6.95272293617992, -4.07220443835686, 
-4.58367105990774, -4.87696387678156, -1.16571436245702, -1.38575808421678, 
-6.02149477878732, -1.3740669528581, -3.44658647343914, -5.83599304580156, 
-3.499200966496, -4.35443174428065, -4.78934795119787, -3.2533381999935, 
-2.04128340377559, -2.07273121905011, -3.4953591405128, -3.81441211796923, 
-2.93881687051817, -6.02998268532188, -1.24521086128058, -7.95558745543141, 
-3.76923203445355, -3.75622774643608, -2.96645530217171, -2.45787631881079, 
-1.32880245983023, -3.41916126243044, -7.22385160271581, -7.56655989697871, 
-3.93796775546548, -6.0919169937804, -3.47608347554203, -4.32895976893165, 
-4.0212869307674, -4.44617158748751, -3.12670371412107, -0.964967847085259, 
-4.70477623876113, -4.1761629901758, -6.76433802721084)), row.names = c(1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 
16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 
29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 39L, 40L, 41L, 42L, 
43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 52L, 54L, 55L, 56L, 
57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 65L, 66L, 67L, 68L, 69L, 
70L, 71L, 72L, 73L, 74L, 75L, 76L, 77L, 78L, 79L, 80L, 81L, 82L, 
83L, 84L, 85L, 86L, 87L, 88L, 89L, 90L, 91L, 92L, 93L, 94L, 95L, 
96L, 97L, 98L, 99L, 100L, 101L, 102L, 103L, 104L, 105L, 106L, 
107L, 108L, 109L, 110L, 111L, 112L, 113L, 114L, 115L, 116L, 117L, 
118L, 119L, 120L, 121L, 122L, 123L, 124L, 125L, 126L, 127L, 128L, 
129L, 130L), na.action = structure(c(`38` = 38L, `53` = 53L), class = "omit"), class = "data.frame")

Solution

  • You need to include the faceting variable in all datasets you'd like to facet by. Assuming your coefficients are in the same order as levels of Continent, you can just do:

    beta_mean$Continent <- levels(merged_data$Continent)
    

    Then your existing ggplot2 code gives: