How do you create a "nested" bar graph? - r

The last image in this blog post.
I have tried searching "nested bar graph" and "hierarchical bar graph", but they may not be the word for it.

Use ggplot and create separate layers:
library(ggplot2)
set.seed(1)
stupid <- data.frame(
group= LETTERS[1:5],
men = sample(1:10, 5),
women = sample(1:10, 5)
)
# Melt the data and calculate totals
mstupid <- melt(stupid, id.vars="group")
stupidTotal <- ddply(mstupid, .(group), summarize, value=sum(value))
ggplot() +
geom_bar(data=stupidTotal, aes(x=group, y=value), fill="grey50") +
geom_bar(data=mstupid, aes(x=group, y=value, fill=variable),
stat="identity", position="dodge") +
theme_bw()

Look for 'barNest' in package plotrix

Use this:
ggplot() +
geom_bar(data=stupidTotal, aes(x=group, y=value, fill="grey50"), stat="identity") +
geom_bar(data=mstupid, aes(x=group, y=value, fill=variable),
stat="identity", position="dodge") +
theme_bw()

Related

Change the scale of x axis in ggplot

I have a ggplot bar and don't know how to change the scale of the x axis. At the moment it looks like on the image below. However I'd like to reorder the scale of the x axis so that 21% bar is higher than the 7% bar. How could I get the % to the axis? Thanks in advance!
df= data.frame("number" = c(7,21), "name" = c("x","y"))
df
ggplot(df, aes(x=name, y=number)) +
geom_bar(stat="identity", fill = "blue") + xlab("Title") + ylab("Title") +
ggtitle("Title")
Use the prop.table function to in y variable in the geom plot.
ggplot(df, aes(x=name, y=100*prop.table(number))) +
geom_bar(stat="identity", fill = "blue") +
xlab("Stichprobe") + ylab("Paketmenge absolut") +
ggtitle("Menge total")
If you want to have the character, % in the y axis, you can add scale_y_continuous to the plot as below:
library(scales)
ggplot(df, aes(x=name, y=prop.table(number))) +
geom_bar(stat="identity", fill = "blue") +
xlab("Stichprobe") + ylab("Paketmenge absolut") +
ggtitle("Menge total") +
scale_y_continuous(labels=percent)
The only way I am able to duplicate the original plot is, as #sconfluentus noted, for the 7% and 21% to be character strings. As an aside the data frame column names need not be quoted.
df= data.frame(number = c('7%','21%'), name = c("x","y"))
df
ggplot(df, aes(x=name, y=number)) +
geom_bar(stat="identity", fill = "blue") + xlab("Title") + ylab("Title") +
ggtitle("Title")
Changing the numbers to c(0.07, 0.21) and adding, as #Mohanasundaram noted, scale_y_continuous(labels = scales::percent) corrects the situation:
To be pedantic using breaks = c(0.07, 0.21) creates nearly an exact duplicate. See also here.3
Hope this is helpful.
library(ggplot2)
library(scales)
df= data.frame(number = c(0.07,0.21), name = c("KG","MS"))
df
ggplot(df, aes(x=name, y=number)) +
geom_bar(stat="identity", fill = "blue") + xlab("Title") + ylab("Title") +
ggtitle("Title") + scale_y_continuous(labels = scales::percent, breaks = c(.07, .21)))

How to join plot layers from different dataset in one plot - ggplot2?

I have three dataset, they are three distinguished bird's assemblages and I'm trying to merge the test results in one plot together. Each one looks like this:
Exemple:
library(ggplot2)
beta1<-c(0.714286,0.625,0.72973,0.5625,0.733333,1,0.655172,0.92,0.769231,0.586207,0.724138,0.846154,
0.833333,0.76,1)
group<-rep(c("q0", "q1", "q2"), each = 5)
beta2<-c(1.714286,1.625,1.72973,1.5625,1.733333,1,1.655172,1.92,1.769231,1.586217,1.724138,1.846154,
1.833333,1.76,1)
dados1<-data.frame(beta1, group)
dados2<-data.frame(beta2, group)
p1<-ggplot(data=dados1, aes(x=group, y=beta1)) +
stat_summary(fun.y=mean, geom="line", aes(group=1)) +
stat_summary(fun.y=mean, geom="point")+ylim(0,2)
p2<-ggplot(data=dados2, aes(x=group, y=beta2)) +
stat_summary(fun.y=mean, geom="line", aes(group=1)) +
stat_summary(fun.y=mean, geom="point")+ylim(0,2)
the result that I need is like this:
plot_merged
I could do this:
ggplot() + stat_summary(fun.y=mean, geom="line", data=dados2, aes(x=group, y=beta2)) + stat_summary(fun.y=mean, geom="point", data=dados2, aes(x=group, y=beta2)) + stat_summary(fun.y=mean, geom="line", data=dados1, aes(x=group, y=beta1)) + stat_summary(fun.y=mean, geom="point", data=dados1, aes(x=group, y=beta1))+ylim(0,2)
but still not enough, because couldn't plot lines...
So I think this will approximately give what you want. We just combine the beta1 and beta2 in 1 data.frame and plot that:
dados1 <-data.frame(beta = beta1, group, id = "beta1")
dados2 <-data.frame(beta = beta2, group, id = "beta2")
df <- rbind(dados1, dados2)
ggplot(df, aes(group, beta, colour = id, group = id)) +
stat_summary(fun.y=mean, geom="line") +
stat_summary(fun.y=mean, geom="point") +
ylim(0,2)
In addition, I solve other question of mine: "If I want to do the same but with boxplot, how can I do this?"
I tried this:
1.Step - by teunbrand (answer above).
dados1 <-data.frame(beta = beta1, group, id = "beta1")
dados2 <-data.frame(beta = beta2, group, id = "beta2")
df <- rbind(dados1, dados2)
2.step:
ggplot(df, aes(group, beta, colour = id, facet_grid= id))+ geom_boxplot()
Plot
Thank you guys!

Is there a possibility to combine position_stack and nudge_x in a stacked bar chart in ggplot2?

I want to add labels to a stacked bar chart to achieve something like this:
The goal is simple: I need to show market shares and changes versus previous year in the same graph. In theory, I would just add "nudge_x=0.5," to geom_text in the code but I get the error: "Specify either position or nudge_x/nudge_y". Is it possible to use some workaround, maybe another package? Thanks a lot in advance!
Code:
DashboardCategoryText <- c("Total Market","Small Bites","Bars","Total Market","Small Bites","Bars","Total Market","Small Bites","Bars")
Manufacturer <- c("Ferrero","Ferrero","Ferrero","Rest","Rest","Rest","Kraft","Kraft","Kraft")
MAT <- c(-1,5,-7,6,8,10,-10,5,8)
Measure_MATCurrent <- c(500,700,200,1000,600,80,30,60,100)
data <- data.frame(DashboardCategoryText,Manufacturer,MAT,Measure_MATCurrent)
library(dplyr)
groupedresult <- group_by(data,DashboardCategoryText)
groupedresult <- summarize(groupedresult,SUM=sum(Measure_MATCurrent))
groupedresult <- as.data.frame(groupedresult)
data <- merge(data,groupedresult,by="DashboardCategoryText")
data$percent <- data$Measure_MATCurrent/data$SUM
library(ggplot2)
ggplot(data, aes(x=reorder(DashboardCategoryText, SUM), y=percent, fill=Manufacturer)) +
geom_bar(stat = "identity", width = .7, colour="black", lwd=0.1) +
geom_text(aes(label=ifelse(percent >= 0.005, paste0(sprintf("%.0f", percent*100),"%"),"")),
position=position_stack(vjust=0.5), colour="white") +
geom_text(aes(label=MAT,y=percent),
nudge_x=0.5,
position=position_stack(vjust=0.8),
colour="black") +
coord_flip() +
scale_y_continuous(labels = percent_format()) +
labs(y="", x="")
I have a somewhat 'hacky' solution where you essentially just change the geom_text data in the underlying ggplot object before you plot it.
p <- ggplot(data, aes(x=reorder(DashboardCategoryText, SUM), y=percent, fill=Manufacturer)) +
geom_bar(stat = "identity", width = .7, colour="black", lwd=0.1) +
geom_text(aes(label=ifelse(percent >= 0.005, paste0(sprintf("%.0f", percent*100),"%"),"")),
position=position_stack(vjust=0.5), colour="white") +
geom_text(aes(label=MAT,y=percent),
position=position_stack(vjust=.5),
colour="black") +
coord_flip() +
scale_y_continuous(labels = percent_format()) +
labs(y="", x="")
q <- ggplot_build(p) # get the ggplot data
q$data[[3]]$x <- q$data[[3]]$x + 0.5 # change it to adjust the x position of geom_text
plot(ggplot_gtable(q)) # plot everything

two barchart and one linechart in one plot

I would like to have two barcharts and one linechart in one plot using ggplot.
I checked the following code, but did not work
df1<- data.frame(x=c(1:5), y=c(10,20,30,24,44))
df2<- data.frame(x=c(1:5), y=c(9,25,22,24, 25))
df3<- data.frame(x=c(1:5), y=c(10,20,30,24,44))
ggplot()+
geom_bar(data=df1, aes(x=x, y=y), stat = "identity", position=position_dodge())+
geom_bar(data=df2, aes( y=y), stat="identity", position=position_dodge())+
geom_line(data=df3, aes(x=x, y=y))
Any help would be appreciated.
Abbas
For a start you need to be putting 'data =.., x=..etc' in ggplot and then + the geom_bars and lines.
http://www.cookbook-r.com/Graphs/Bar_and_line_graphs_(ggplot2)/
e.g.
ggplot(data=df1, aes(x=x, y=y)) +
geom_bar(stat = "identity", position=position_dodge())

In ggplot2, how to add text by group in facet_wrap?

Here is an example:
library(ggplot2)
set.seed(112)
df<-data.frame(g=sample(c("A", "B"), 100, T),
x=rnorm(100),
y=rnorm(100,2,3),
f=sample(c("i","ii"), 100, T))
ggplot(df, aes(x=x,y=y, colour=factor(g)))+
geom_point()+geom_smooth(method="lm", fill="NA")+facet_wrap(~f)
My question is how to add text like the second plot by group into the plot.
You can manually create another data.frame for your text and add the layer on the original plot.
df_text <- data.frame(g=rep(c("A", "B")), x=-2, y=c(9, 8, 9, 8),
f=rep(c("i", "ii"), each=2),
text=c("R=0.2", "R=-0.3", "R=-0.05", "R=0.2"))
ggplot(df, aes(x=x,y=y, colour=factor(g))) +
geom_point() + geom_smooth(method="lm", fill="NA") +
geom_text(data=df_text, aes(x=x, y=y, color=factor(g), label=text),
fontface="bold", hjust=0, size=5, show.legend=FALSE) +
facet_wrap(~f)
Another option is to calculate the correlations on the fly and use the underlying numeric values of the factor variable g to place the text so that the red and blue labels don't overlap. This reduces the amount of code needed and makes label placement a bit easier.
library(dplyr)
ggplot(df, aes(x=x, y=y, colour=g)) +
geom_point() +
geom_smooth(method="lm", fill=NA) + # Guessing you meant fill=NA here
#geom_smooth(method="lm", se=FALSE) # Better way to remove confidence bands
facet_wrap(~f) +
geom_text(data=df %>% group_by(g, f) %>% summarise(corr = cor(x,y)),
aes(label=paste0("R = ", round(corr,2)), y = 10 - as.numeric(g)),
x=-2, hjust=0, fontface="bold", size=5, show.legend=FALSE)

Resources