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")
Related
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")
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")
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 have the following dataset:
year <- as.factor(c(1999,2000,2001))
era <- c(0.4,0.6,0.7)
player_id <- as.factor(c(2,2,2))
df <- data.frame(year, era, player_id)
Using this data I created the following graph:
ggplot(data = df, aes(x = year, y=era, colour = player_id))+
geom_line() +
geom_text(aes(label = player_id), hjust=0.7)
Thing is however that I do now get a label at every datapoint. I only want to have a label at the end of each datapoint.
Any thoughts on what I should change to I get only one label?
If I understand correctly, you want label at end of data point. You could do this using directlabels library, as below:
library(ggplot2)
library(directlabels)
ggplot(data = df, aes(x = year, y=era, group = player_id, colour = player_id))+
geom_line() +
scale_colour_discrete(guide = 'none') +
scale_x_discrete(expand=c(0, 1)) +
geom_dl(aes(label = player_id), method = list(dl.combine("last.points"), cex = 0.8))
Output:
If I am understanding correctly what you want, then you can replace the geom_text(...) with geom_point()
I am trying to do a histogram zoomed on part of the data. My problem is that I would like to grup everything that is outside the range into last category "10+". Is it possible to do it using ggplot2?
Sample code:
x <- data.frame(runif(10000, 0, 15))
ggplot(x, aes(runif.10000..0..15.)) +
geom_histogram(aes(y = (..count..)/sum(..count..)), colour = "grey50", binwidth = 1) +
scale_y_continuous(labels = percent) +
coord_cartesian(xlim=c(0, 10)) +
scale_x_continuous(breaks = 0:10)
Here is how the histogram looks now:
How the histogram looks now
And here is how I would like it to look:
How the histogram should look
Probably it is possibile to do it by nesting ifelses, but as I have in my problem more cases is there a way for ggplot to do it?
You could use forcats and dplyr to efficiently categorize the values, aggregate the last "levels" and then compute the percentages before the plot. Something like this should work:
library(forcats)
library(dplyr)
library(ggplot2)
x <- data.frame(x = runif(10000, 0, 15))
x2 <- x %>%
mutate(x_grp = cut(x, breaks = c(seq(0,15,1)))) %>%
mutate(x_grp = fct_collapse(x_grp, other = levels(x_grp)[10:15])) %>%
group_by(x_grp) %>%
dplyr::summarize(count = n())
ggplot(x2, aes(x = x_grp, y = count/10000)) +
geom_bar(stat = "identity", colour = "grey50") +
scale_y_continuous(labels = percent)
However, the resulting graph is very different from your example, but I think it's correct, since we are building a uniform distribution: