Grouped and stacked barplot using base R

随声附和 提交于 2021-02-07 13:00:26

问题


I would like to create a combination bar plot where within data1 and data2 are stacked while between data1 and data2 are grouped in base R graphics.

Something like this in arrangement:

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)

Any idea how can I do this? I know we can do this using different plots or facets but I would like to present them side by side in a single plot.


回答1:


You can use the argument space of barplot to shift the second 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)




回答2:


You can try using mfrow to plot two plots side by side:

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




回答3:


I know you're looking for a base-R solution. That's a pitty. ggplot2 offers great possibilities for such tasks:

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)

gives:

I can think of a (less elegant) solution in pure base-R using a little hack:

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

gives:




回答4:


Here is custom function where you can manipulate between and within group plots and can be done with any number of the data you want to plot.

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, ...)
 }

The following is example with three dataset. Note all data has same number of rows but the column is different. As the row values are stacked, should be same number but one can make the rows equal by putting NA or 0 for the group that is missing.

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")




回答5:


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)


来源:https://stackoverflow.com/questions/32997632/grouped-and-stacked-barplot-using-base-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!