Home > database >  How to plot data from two data frames together as a stacked bar chart in R?
How to plot data from two data frames together as a stacked bar chart in R?

Time:10-16

I have two dataframes called dbDateSubMSortNacional and dbDateSubMSortNacional, which contain a series of dates and values of covid infections for males and females in a certain region for the corresponding dates. I have plotted them individually as

contagiosH=barplot(dbDateSubHSortNacional$total[1:5], names.arg = dbDateSubHSortNacional$fecha[1:5], cex.names=0.759, , cex.axis=1, main = "Masculino", xlab="Fechas yy-mm-dd" , ylab="Número de contagios", col = rainbow(5), border = "white", ylim=c(0, 5000))
text(contagiosH, dbDateSubHSortNacional$total[1:5], dbDateSubHSortNacional$total[1:5])

contagiosM=barplot(dbDateSubMSortNacional$total[1:5], names.arg = dbDateSubMSortNacional$fecha[1:5], cex.names=0.759, , cex.axis=1, main = "Femenino", xlab="Fechas yy-mm-dd" , ylab="Número de contagios", col = rainbow(5), border = "white", ylim=c(0, 5000))
text(contagiosM, dbDateSubMSortNacional$total[1:5], dbDateSubMSortNacional$total[1:5])

I was wondering if it were possible to plot them as the graph in the attached figure. Graph to be emulated

I have managed to do it independently for a single dataframe called datosas

barplot(datos, beside=F, col=rainbow(5), legend.text = row.names(datos),
        args.legend=list(title ="RRSS preferidas", x="top", inset=c(0, -0.45)))

I have tried to merge both approaches as

barplot(dbDateSubMSortNacional$total[1:5], dbDateSubHSortNacional$total[1:5], names.arg = dbDateSubMSortNacional$fecha[1:5], cex.names=0.759, , cex.axis=1,  col = rainbow(5), border = "white", ylim=c(0, 4000))

Unfortunately, I get a single graph. Can someone please tell me how to achieve my goal?

EDIT: To generate a reproducible output, use

fecha <- c("2022-01-01","2022-01-02","2022-01-03", "2022-01-04", "2022-01-05", "2022-01-06", "2022-01-07")
total <- c(1, 3, 5, 7, 9, 11, 13)

dbDateSubMSortNacional <- data.frame(fecha, total);

total <- c(2, 4, 6, 8, 10, 12, 14)

dbDateSubHSortNacional <- data.frame(fecha, total);

Problem with the suggested solution by @jdobres:

Problem

Returns the error Error in cbind(total.2022 - 1 - 10, total.2022 - 1 - 11, total.2022 - : object 'total.2022' not found in

barplot(cbind(total.2022-01-10, total.2022-01-11, total.2022-01-04, total.2022-01-05, total.2022-01-12) ~ set, data = combined_wide, col = rainbow(5))

CodePudding user response:

A dplyr and ggplot solution, followed by a base R barplot option:


library(dplyr, warn = FALSE)
library(tidyr)
library(ggplot2)


df1 <- bind_rows(dbDateSubHSortNacional, dbDateSubMSortNacional)

ggplot(df1) 
  geom_col(aes(x = set, y = total, fill = fecha))


#get data into wide format:

df2 <-
  df1 |>
  pivot_wider(names_from = fecha, values_from = total)


barplot(cbind(`2022-01-10`, `2022-01-11`, `2022-01-04`,`2022-01-05`, `2022-01-12`, `2022-01-17`, `2021-12-19`)~set, 
        data = df2 , 
        xlim = c(0,1),
        width = 0.30,
        col = rainbow(7),
        xlab = "Sex",
        ylab = "Frequency",
        legend.text = colnames(df2)[-1],
        args.legend = list(x = "topright"))

Created on 2022-10-15 with enter image description here

You could also use ggplot2 to create a similar plot, without having to widen the data set:

library(ggplot2)

ggplot(data = subset(combined, !(fecha %in% c('Saturday', 'Sunday'))), aes(x = set, y = total, fill = fecha))  
  geom_col()

enter image description here

  • Related