ggplot2 barplot con errorbars quando si usano barre impilate
Sto cercando di produrre un grafico a barre in pila con una barra di errore che rappresenta la variabilità totale per barra. Non voglio usare un grafico a barre schivato perché ho> 10 categorie per barra.
Di seguito ho alcuni dati di esempio per un esempio riproducibile:
scenario = c('A','A','A','A')
strategy = c('A','A','A','A')
decile = c(0,0,10,10)
asset = c('A','B','A','B')
lower = c(10,20,10, 15)
mean = c(30,50,60, 70)
upper = c(70,90,86,90)
data = data.frame(scenario, strategy, decile, asset, lower, mean, upper)
E una volta che abbiamo il datadf possiamo usare ggplot2 per creare una barra in pila in questo modo:
ggplot(wide, aes(x=decile, y=mean, fill=asset)) +
geom_bar(stat="identity") +
facet_grid(strategy~scenario) +
geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.25)
Tuttavia, le barre di errore prodotte sono per ogni singolo componente di ciascuna barra in pila:
Apprezzo questo risultato da me fornito lower, meane upperper ogni riga del df, ma anche quando ho sommato questi per decile non ho ottenuto i miei errorbars desiderati nella parte superiore di ogni pila di barre.
Qual è il codice ggplot2 corretto o, in alternativa, qual è la struttura dati corretta per abilitarlo?
Risposte
Penso che tu abbia ragione nel realizzare che devi manipolare i tuoi dati piuttosto che la tua trama. Non puoi davvero avere position_stackuna errorbar, quindi dovrai ricalcolare i valori medio, superiore e inferiore per le errorbar. Essenzialmente questo significa ottenere la somma cumulativa dei valori medi e spostare di conseguenza gli intervalli superiore e inferiore. Puoi farlo all'interno di un dplyrtubo.
Nota Penso che dovrai anche avere un position_dodgesulle barre di errore, poiché il loro intervallo si sovrappone anche se spostato in modo appropriato, il che li renderà più difficili da interpretare visivamente:
library(ggplot2)
library(dplyr)
data %>%
mutate(lower = lower - mean, upper = upper - mean) %>%
group_by(decile) %>%
arrange(rev(asset), by.group = TRUE) %>%
mutate(mean2 = cumsum(mean), lower = lower + mean2, upper = upper + mean2) %>%
ggplot(aes(x = decile, y = mean, fill = asset)) +
geom_bar(stat = "identity") +
facet_grid(strategy ~ scenario) +
geom_errorbar(aes(y = mean2, ymin = lower, ymax = upper), width = 2,
position = position_dodge(width = 2)) +
geom_point(aes(y = mean2), position = position_dodge(width = 2))
Se vuoi solo una barra di errore per decile, devi aggregare i valori in modo che non ci sia differenza tra assest come questo:
library(ggplot2)
library(dplyr)
#Code
data %>% group_by(scenario,decile) %>%
mutate(nlower=mean(lower),nupper=mean(upper)) %>%
ggplot(aes(x=factor(decile), y=mean, fill=asset,group=scenario)) +
geom_bar(stat="identity") +
facet_grid(strategy~scenario) +
geom_errorbar(aes(ymin = nlower, ymax = nupper), width = 0.25)
Produzione:
È un'altra cosa usare asset in quanto prenderà in considerazione ogni classe poiché hai valori diversi per ciascuna di esse:
#Code 2
data %>%
ggplot(aes(x=factor(decile), y=mean, fill=asset,group=scenario)) +
geom_bar(stat="identity") +
facet_grid(strategy~scenario) +
geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.25)
Produzione:
Nell'ultima versione, ogni asset ha la sua barra di errore, ma se vuoi vedere gli errori a livello globale, dovresti usare un approccio che aggreghi i limiti come è stato fatto con i valori medi o altra misura che desideri.