I have the following dataset which produces a grouped bar plot:
library(ggplot2)
library(dplyr)
expand.grid(gender=c("M","F"),
education=c("HS","College","Advanced"),
value = sample(1:20,8, replace = T)) %>%
ggplot(aes(x = education, y = value, fill = gender))+
geom_col(position = position_dodge())
But instead of having a legend I want the labels to be on the x axis like this:
Is this possible?
Thanks
as camille already mentioned in a comment, you can use facet_wrap
expand.grid(gender=c("M","F"),
education=c("HS","College","Advanced"),
value = sample(1:20,8, replace = T)) %>%
ggplot(aes(x = gender, y = value, fill = gender))+
geom_col(position = position_dodge()) +
facet_wrap(~education)
The resulting plot looks like this:
If you want to remove the legend, just add theme(legend.position="none")
Related
I have a dataset that has the variables "SEXO" (M or F) and "Class" (0 or 1). I want to create a bar plot using ggplot2 that shows, for each sex, the distribution of Class as a percentage. I was able to get the plot, but I can't seem to get the labels working on the bars itself. I don't want to change the labels on the axis, I just want to get the % shown on the plot for each SEXO.
This is the code I have been using:
ggplot(data = df, aes(x = SEXO, fill = Class)) + geom_bar(position = 'fill')
I also attach an image of the plot produced by the code:
This would be the ideal outcome:
Here an example using the mtcars dataset where you can calculate the percentage per group and use these to place in your bars using label with geom_text like this:
library(ggplot2)
library(dplyr)
mtcars %>%
group_by(am, vs) %>%
summarise(cnt = n()) %>%
mutate(perc = round(cnt/sum(cnt), 2)) %>%
ggplot(aes(x = factor(vs), fill = factor(am), y = perc)) +
geom_col(position = 'fill') +
geom_text(aes(label = paste0(perc*100,"%"), y = perc), position = position_stack(vjust = 0.5), size = 3) +
labs(fill = 'Class', x = 'vs') +
scale_y_continuous(limits = c(0,1))
#> `summarise()` has grouped output by 'am'. You can override using the `.groups`
#> argument.
Created on 2022-11-02 with reprex v2.0.2
In respect to the below code I can produce a stacked bar chart as shown by the first graph.
library(ggplot2)
vehicle<- sample(rep(c("Cars","Cycles","Motobike"),times=c(20,50,30)))
team<-sample(rep(c("TeamA","TeamB"),times=c(50,50)))
df<-data.frame(team,vehicle, stringsAsFactors = FALSE)
ggplot(data = df, aes(x = as.factor (vehicle), fill =team)) +
geom_bar(mapping = aes(y = stat(count)/sum(..count..)*100),
position = "stack")
What I want to do is to produce a transformation within the geom_bar(mapping = aes(y = stat(count)/sum(..count..)*100),position = "stack") part that says if it is team B, then the count becomes a minus number. I want to do this so I can reproduce something like the 2nd graph.
Can anyone help amend the code to get the desired result?
Note: the second graph is created using the code below but I don't want to have to add two separate geom_bars because it means the % is incorrect on the y axis.
ggplot(data = df, aes(x = as.factor (vehicle), fill =team)) +
geom_bar(data = subset(df, team=="TeamA"),
mapping = aes(y = stat(count)/sum(..count..)*100),
position = "stack")+
geom_bar(data = subset(df, team=="TeamB"),
mapping = aes(y = - stat(count)/sum(..count..)*100),
position = "stack") +
labs(x = "", y="")
I think it's easier to prepare the data before you feed it into ggplot. I realize the numbers don't quite match up here but I'll let you deal with that.
library(tidyverse)
library(ggplot2)
vehicle<- sample(rep(c("Cars","Cycles","Motobike"),times=c(20,50,30)))
team<-sample(rep(c("TeamA","TeamB"),times=c(50,50)))
df<-data.frame(team,vehicle, stringsAsFactors = FALSE) %>%
group_by(team, vehicle) %>%
summarize(count = n()) %>%
mutate(newcount = if_else(team == 'TeamA', count, -count))
ggplot(data = df, aes(x = as.factor(vehicle), y = newcount, fill =team)) +
geom_bar(position = "stack", stat ='identity')
I managed to do it by using an ifelse directly in the function which achieved what I was after.
set.seed (105)
vehicle<- sample(rep(c("Cars","Cycles","Motorbike"),times=c(20,50,30)))
team<-sample(rep(c("TeamA","TeamB"),times=c(50,50)))
df<-data.frame(team,vehicle, stringsAsFactors = FALSE)
ggplot(data = df, aes(x = as.factor (vehicle), fill =team,
y= ifelse(test = team == "TeamB",
yes = -1/nrow(df)*100, no = 1/nrow(df)*100)))+
geom_bar(stat="identity")
Having a dataframe like this one:
From a dataframe like this one:
data <- data.frame(year = c(2010,2011,2012,2010,2011,2012),
name = c("stock1","stock1","stock1","stock2","stock2","stock2"),
value = c(0,3,1,4,1,3))
I would like to create a plot and I use this:
library(ggplot2)
ggplot(data=data, xName="year", groupName="name", brewerPalette="Blues")
but I can't receive the plot. Anything wrong in the call?
I think you need something like this:
library(ggplot2)
library(dplyr)
library(RColorBrewer)
df %>%
group_by(name) %>%
ggplot(aes(year,value,fill=name))+
geom_col()+
scale_fill_brewer(palette = "Blues")
If you want a grouped bar plot (as I guessed from your code), this code may be helpful:
ggplot(data = data, aes(x = as.factor(year), y = value, fill = name)) +
geom_bar(stat = "identity", position = position_dodge(0.8), width = 0.7) +
scale_fill_brewer(palette = "Blues")
I have a faceted ggplot that is all but done. I cannot seem to get the fill aesthetic to be descending for each group in the dodged plot and across facets. The idea is to look at the plot and quickly recognise the top three categories within each group on the y-axis - and that the colors will be order different for each group. Here is some code to get a representative graph.
library(tidyverse)
set.seed(123)
#using crossing from purrr
df <- crossing(
mean = 1:8,
cats = sample(letters[1:3], 8, T),
gender = c('Male', 'Female')) %>%
mutate(vary_x = sample(seq(1,3,.1),nrow(.), T))
df %>%
ggplot(aes(mean, vary_x, fill = cats))+
geom_bar(stat = 'identity',
position = 'dodge') +
facet_grid(.~gender) +
coord_flip()
Something like this maybe:
df %>%
ggplot(aes(mean, reorder(vary_x,mean), fill = cats))+
geom_bar(stat = 'identity',
position = 'dodge') +
facet_grid(.~gender) +
coord_flip()
I've got a data frame with two categorical variables called verified and procedure.
I'd like to make a bar chart with procedure on the x-axis, and the corresponding percentages rather than counts on the y-axis. Furthermore, I'd like for verified to be the fill of the bars.
The problem's that when I've tried using the fill argument it hasn't worked. My current code gets me bars that are all grey with a black line (despite the absence of a fill argument the black line seems to indicate the levels of verified???). Instead I'd like the levels to be in different colours.
Thanks!
starting point (df):
df <- data.frame(verified=c("small","large","small","small","large","small","small","large","small"),procedure=c(1,2,1,2,1,2,2,2,2))
current code:
library(dplyr)
library(gglot2)
df %>%
count(procedure,verified) %>%
mutate(prop = round((n / sum(n))*100),2) %>%
group_by(procedure) %>%
ggplot(aes(x = procedure, y = prop)) +
geom_bar(stat = "identity",colour="black")
just add fill = verified to your initial aes or within your geom_bar
# common elements
g_df <- df %>%
count(procedure, verified) %>%
mutate(prop = round((n / sum(n)) * 100), 2) %>%
group_by(procedure)
# fill added to initial aes
g1 <- ggplot(g_df, aes(x = procedure, y = prop, fill = verified)) +
geom_bar(stat = "identity", colour = "black")
# fill added to geom_bar
g2 <- ggplot(aes(x = procedure, y = prop)) +
geom_bar(aes(fill = verified), stat = "identity", colour = "black")
Both g1 and g2 produce the same plot below
As suggested by eipi10 in the comments to my answer, you could clean up the xaxis by making it a factor, a modification of their code below.
df %>%
count(procedure, verified) %>%
mutate(prop = n / sum(n)) %>%
ggplot(aes(x = factor(procedure), y = prop, fill = verified)) +
geom_bar(stat = "identity", colour = "black") +
labs(x = "procedure", y = "percent")
to produce