2015-10-07 18 views
6

Vorrei creare un grafico a barre combinato in cui dati1 e dati2 sono impilati mentre tra dati1 e dati2 sono raggruppati in grafici R di base.Barplot raggruppato e impilato utilizzando la base R

Qualcosa di simile a disposizione:

enter image description here

data1 <- matrix(c(1:5, rep(1,5), rep(4,5)), ncol=5) 
data2 <- matrix(c(2:6, rep(2,5), rep(3,5)), ncol=5) 

# stacked bar 
barplot(data1) 
#grouped var 
barplot(data1, beside=TRUE) 

Qualsiasi idea di come posso fare questo? So che possiamo farlo usando differenti trame o sfaccettature, ma vorrei presentarle fianco a fianco in una trama unica.

+7

Forse qualcosa di simile: 'barplot (cbind (data1, data2), spazio = c (rep (0, ncol (data1)), 2, rep (0, ncol (data2)))) ' – WaltS

+2

@WaltS, dovresti postare come risposta. (ma cambia in 'ncol (data2) -1' per rimuovere l'avviso) – user20650

risposta

3

È possibile utilizzare l'argomento space di barplot al spostamento del secondo barplot:

# plot first barplot, using xlim to ensure there is enough space to plot the second one 
# (here the spaces are all 0, so the bars are grouped together) 
barplot(data1, space=0, xlim=c(-1, ncol(data1)+ncol(data2)+1), las=1) 
# plot second barplot (with add=TRUE so the bars appear on the same plot), 
# putting a space of 6 (the number of columns of data1 + 1) at the beginning, 
# to plot the "new" bars on the right of the first bars (the other spaces are 0): 
barplot(data2, space=c(ncol(data1)+1, rep(0, ncol(data2)-1)), las=1, add=TRUE) 

enter image description here

4

Puoi provare a utilizzare mfrow di tracciare due fianco a trame a fianco:

par(mfrow = c(1,2)) 
barplot(data1, ylim = c(0,13), xlab = "data1") 
barplot(data2, ylim = c(0,13), axes = FALSE, xlab = "data2") 

enter image description here

-2
library(gridExtra) 

data1 <- matrix(c(1:5, rep(1,5), rep(4,5)), ncol=5) 
data2 <- matrix(c(2:6, rep(2,5), rep(3,5)), ncol=5) 


# stacked bar 
plot1 <- barplot(data1) 
#grouped var 
plot2<- barplot(data1, beside=TRUE) 

grid.arrange(plot1, plot2, ncol=2) 
+2

Questo non sembra funzionare per me ... barplot è una funzione di tracciamento di base non griglia (dare anche un'occhiata agli oggetti trama1 e trama2) – user20650

+0

I dint capisco davvero. hai bisogno della griglia della bibliotecaExtra e grid.arrange metterà due grafici uno accanto all'altro – Bg1850

+2

Prova a eseguire il tuo codice ... non funzionerà ... riceverai un errore "... solo i grobs sono ammessi ...". barplot è una funzione di base r che non restituisce effettivamente la trama (ad esempio, come farebbe ggplot). – user20650

1

So che stai cercando una soluzione di base-R. È un peccato. ggplot2 offre grandi possibilità per questi compiti:

data3 = data.frame(data_nr = rep(c("data1","data2"), each=15), 
       cat_1 = rep(rep(letters[1:5], each=3),2), 
       cat_2 = rep(rep(LETTERS[1:3], 5),2), 
       height = c(1:5, rep(1,5), rep(4,5), 2:6, rep(2,5), rep(3,5))) 

ggplot(data3, aes(x=cat_1, y=height, fill=cat_2)) + 
geom_bar(stat="identity", position="stack") + 
facet_grid(~ data_nr) 

dà: enter image description here

mi viene in mente un (meno elegante) soluzione in pura base-R con un piccolo hack:

data12 = cbind(data1, rep(NA,3), data2) 
barplot(data12, space=0) 

dà: enter image description here

+1

So che ggplot2 è ottimo ma mi prefetto soluzioni di base che presenta alcuni vantaggi in quanto non è necessario fare affidamento sui pacchetti e sui loro aggiornamenti ecc ... Ho provato singolo trama (non a più sfaccettature) ma potrebbe non altrettanto bene. – jon

1

Ecco la funzione personalizzata in cui è possibile manipolare tra e all'interno di grafici di gruppo e può essere fatto con qualsiasi numero di dati che si desidera tracciare.

multistack.bar <- function(x=list(x), betweenspace = 2, withinspace=0, ...){ 
    # note that number of rows in each component matrix of the list 
    # should be equal 
    # if you have missing value use "NA", to make it complete 
    # number of column can differ 
    mylist <- x 
space = list() 
space[[1]] <- c(rep(withinspace,ncol(mylist[[1]])),betweenspace) 

for (i in 2:length(mylist)){ 
    if(i == length(mylist)){ 
    space[[i]] <- c(rep(withinspace,ncol(mylist[[i]])-1)) 
    } else{ 
    space[[i]] <- c(rep(withinspace,ncol(mylist[[i]])-1),betweenspace) 
    } 
    } 
    un.space <- c(unlist(space)) 
    newdata <- do.call("cbind", mylist) 
    barplot(newdata, space= un.space, ...) 
} 

Di seguito è riportato un esempio con tre set di dati. Nota che tutti i dati hanno lo stesso numero di righe ma la colonna è diversa. Dato che i valori delle righe sono impilati, dovrebbe essere lo stesso numero, ma è possibile rendere uguali le righe inserendo NA o 0 per il gruppo mancante.

data1 <- matrix(c(1:5, rep(1,5), rep(4,5)), ncol=5) 
data2 <- matrix(c(2:6, rep(2,5), rep(3,5)), ncol=5) 
data3 <- matrix(c(2:6, rep(2,5), rep(3,5)), ncol=5) 
data4 <- matrix(c(1:4, rep(1,4), rep(4,4)), ncol=4) 


mylist <- list(data1, data2, data3, data4) 

multistack.bar(mylist, betweenspace=3, withinspace=0.1, 
    col = c("pink", "blue", "purple"), xlab="groups", ylab="frequency", ylim = c(0, 16)) 

# you can decrease space between bars to 0 no space and between plots 
    multistack.bar(mylist, betweenspace=1, withinspace=0, 
    col = c("pink", "blue", "purple"), xlab="groups", ylab="frequency", 
    ylim = c(0, 16)) 


# now you can use any thing you want just make it elegant or useful. 
    legend(8, 14.8, c("A", "B", "C"), fill = c("pink", "blue", "purple"), ncol=3) 
    abline(h=4, lty =2, col= "red") 

enter image description here