1
votes

I have three dataframes that I can not really rbind or cbind. They share the column ´Pop.Name´, where population names are stored. Population names are common among the three dfs.

I'm trying to use ggplot2 to count (stat="bin") the number of cases of each population in each dataframe, and to plot it so that I have a different bar for each df and every population. Basically I want to compare side to side the count data of each population as is the dfs where treatments in a single df and I were using geom_bar(position="dodge").

To plot one of the df alone I'm using:

plt<- ggplot(df1, aes(x=Pop.Name)) + theme_bw() # plot by pop
plt<- plt + geom_bar()

How can I add the other two dfs to the same plot? I'm sure it is very simple and I'm missing something, but can't figure out what. I tried:

plot1 <- ggplot(df1, aes(x=Pop.Name)) + 
    geom_bar() +
    geom_bar(data = df2)

And many others, but I either get errors or only one bar per popupation. I'm terribly sorry if this is a duplicate, but I think it isn't. However, my question is very similar to this: ggplot stacked bar plot from 2 separate data frames, but I can not rbind or cbind the dataframes (at least not in a straight forwards way and each one is huge).

Thanks

Some toy data:

df1<-structure(list(Pop.Name = c(1, 2, 3, 4, 3, 2, 1, 2, 3, 4), Loc = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 3L, 3L, 3L, 3L), .Label = c("a", "c", "d" ), class = "factor"), BP = c(10, 10, 10, 10, 50, 21, 33, 8, 8, 8)), .Names = c("Pop.Name", "Loc", "BP"), row.names = c(NA, -10L), class = "data.frame")

df2<-structure(list(Pop.Name = c(3, 2, 3, 4, 3, 2, 1), A = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 3L), .Label = c("x", "y", "z" ), class = "factor"), C = c(11, 11, 11, 10, 50, 21, 3)), .Names = c("Pop.Name", "A", "C"), row.names = c(NA, -7L), class = "data.frame")
1

1 Answers

0
votes

Here is an option:

df.list <- list(a=df1, b=df2)
dat <- stack(lapply(df.list, `[[`, "Pop.Name"))
ggplot(dat, aes(x=values, fill=ind)) + geom_bar(position="dodge")

First we put our data frames in a list, then we extract just the Pop.Name column with [[ and lapply, and finally we stack them back into a data frame containing just the source data frame label and the Pop.Name. This produces:

enter image description here

Note that Pop.Names cannot be factor, for this to work. Data:

df1 <- data.frame(Pop.Name=sample(letters, 50, rep=T), stringsAsFactors=F)
df2 <- data.frame(Pop.Name=sample(letters, 50, rep=T), stringsAsFactors=F)

EDIT: hadn't noticed you posted data, but this works with your data as is.