reorder bar plot by fill in R - r

How to set this plot in ascending order? many thanks in advance.
library(ggplot2)
library(reshape2)
iris2 <- melt(iris, id.vars="Species"); iris2
ggplot(data=iris2, aes(x=Species, y=value, fill=variable))+
geom_bar(stat="identity", position="dodge")

You can use reorder to set the bars in ascending overall order :
iris2$variable <- reorder(iris2$variable, iris2$value)
ggplot(data=iris2, aes(x=Species, y=value, fill=variable))+
geom_bar(stat="identity", position="dodge")
Notice though that the ordering is the same for all 3 groups, which means that setosa has one bar "out of place".
It is possible, but a lot trickier, to get the bars in ascending order for every species.
library(tidyverse)
iris2 %>%
group_by(variable, Species) %>%
summarise(value = max(value)) %>%
mutate(xval = as.numeric(as.factor(Species))) %>%
group_by(Species) %>%
mutate(xval = 0.2 * order(value) - 0.5 + xval) %>%
ggplot(aes(x=xval, y=value, fill=variable))+
geom_col(position="dodge", width = 0.2) +
scale_x_continuous(breaks = 1:3, labels = unique(iris2$Species),
name = "Species")

Related

Is there an R function to normalize height in a pie chart?

I'm trying to compare two pie chart from ggplot2,but when I try to graph it because of the big difference in length of the dataset It look very small.
I wanted the piechart divided by a category and group by another.
df %>%
count(category,group) %>%
ggplot(aes(x="", y=n, fill=factor(group))) +
geom_bar(stat="identity", width=1) +
coord_polar("y", start=0) +
facet_wrap(~category)
I did the following to normalize their height.
Piechartdf <- df %>%
count(category,group)
Piechart <- Piechart %>%
mutate(proportion = case_when(
Type=="category1" ~ n/sum(Piechart[which(Piechart$Type == "category1"), 3]),
Type=="category2" ~ n/sum(Piechart[which(Piechart$Type == "category2"), 3])
))
Then in the first one, I just chance n for proportion, Is there an easier way to achieve this?
You may try
df %>%
count(category,group) %>%
group_by(category) %>%
mutate(n = n/sum(n)) %>%
ggplot(aes(x="", y=n, fill=factor(group), group = category)) +
geom_bar(stat="identity", width=1)+
coord_polar("y", start=0) +
facet_wrap(~category)

Order bars by difference between variables

My intention is to plot a barchart, with to variables visible:
"HH_FIN_EX", "ACT_IND_CON_EXP" but having them ordered by the variable diff, in ascending order. diff itself should not be included in chart
library(eurostat)
library(tidyverse)
#getting the data
data1 <- get_eurostat("nama_10_gdp",time_format = "num")
#filtering
data_1_4 <- data1 %>%
filter(time=="2016",
na_item %in% c("B1GQ", "P31_S14_S15", "P41"),
geo %in% c("BE","BG","CZ","DK","DE","EE","IE","EL","ES","FR","HR","IT","CY","LV","LT","LU","HU","MT","NL","AT","PL","PT","RO","SI","SK","FI","SE","UK"),
unit=="CP_MEUR")%>% select(-unit, -time)
#transformations and calculations
data_1_4 <- data_1_4 %>%
spread(na_item, values)%>%
na.omit() %>%
mutate(HH_FIN_EX = P31_S14_S15/B1GQ, ACT_IND_CON_EXP=P41/B1GQ, diff=ACT_IND_CON_EXP-HH_FIN_EX) %>%
gather(na_item, values, 2:7)%>%
filter(na_item %in% c("HH_FIN_EX", "ACT_IND_CON_EXP", "diff"))
#plotting
ggplot(data=data_1_4, aes(x=reorder(geo, values), y=values, fill=na_item))+
geom_bar(stat="identity", position=position_dodge(), colour="black")+
labs(title="", x="Countries", y="As percentage of GDP")
I appreciate any suggestions how to do this, as aes(x=reorder(geo, values[values=="diff"]) results in an error.
First of all, you shouldn't include diff (your result column) when using gather, it complicates things.
Change line gather(na_item, values, 2:7) to gather(na_item, values, 2:6).
You can use this code to calculate difference and order (using dplyr::arange) rows in descending order:
plotData <- data_1_4 %>%
spread(na_item, values) %>%
na.omit() %>%
mutate(HH_FIN_EX = P31_S14_S15 / B1GQ,
ACT_IND_CON_EXP = P41 / B1GQ,
diff = ACT_IND_CON_EXP - HH_FIN_EX) %>%
gather(na_item, values, 2:6) %>%
filter(na_item %in% c("HH_FIN_EX", "ACT_IND_CON_EXP")) %>%
arrange(desc(diff))
And plot it with:
ggplot(plotData, aes(geo, values, fill = na_item))+
geom_bar(stat = "identity", position = "dodge", color = "black") +
labs(x = "Countries",
y = "As percentage of GDP") +
scale_x_discrete(limits = plotData$geo)
You can explicitly figure out the order that you want -- this is stored in country_order below -- and force the factor geo to have its levels in that order. Then run ggplot after filtering out the diff variable. So replace your call to ggplot with the following:
country_order = (data_1_4 %>% filter(na_item == 'diff') %>% arrange(values))$geo
data_1_4$geo = factor(data_1_4$geo, country_order)
ggplot(data=filter(data_1_4, na_item != 'diff'), aes(x=geo, y=values, fill=na_item))+
geom_bar(stat="identity", position=position_dodge(), colour="black")+
labs(title="", x="Countries", y="As percentage of GDP")
Doing this, I get the plot below:
is this what you are looking for?
data_1_4 %>% mutate(Val = fct_reorder(geo, values, .desc = TRUE)) %>%
filter(na_item %in% c("HH_FIN_EX", "ACT_IND_CON_EXP")) %>%
ggplot(aes(x=Val, y=values, fill=na_item)) +
geom_bar(stat="identity", position=position_dodge(), colour="black") +
labs(title="", x="Countries", y="As percentage of GDP")

ggplot geom_boxplot and plotting last value with geom_point

I'm new to R. I was trying to plot the last value of each variable in a data frame on top of a boxplot. Without success I was trying:
ggplot(iris, aes(x=Species,y=Sepal.Length)) +
geom_boxplot() +
geom_point(iris, aes(x=unique(iris$Species), y=tail(iris,n=1)))
Thanks, Bill
One approach is
library(tidyverse)
iris1 <- iris %>%
group_by(Species) %>%
summarise(LastVal = last(Sepal.Length))
ggplot(iris, aes(x=Species,y=Sepal.Length)) +
geom_boxplot() +
geom_point(data = iris1, aes(x = Species, y = LastVal))

ggplot: position_dodge results in overlap?

I have the following workflow:
rm(list=ls())
data(mtcars)
attach(mtcars)
library(ggplot2)
library(plyr)
library(dplyr)
library(scales)
library(reshape2)
library(lazyeval)
my_func <- function(x, y) {
test<<-mtcars %>% group_by_(x, y) %>%
summarise(Freq = n()) %>%
mutate(Freq = Freq/sum(Freq))
test
}
my_func('gear', 'cyl')
ggplot(test, aes(x=gear, y=Freq))+
geom_bar(stat="identity", aes(fill=cyl), position=position_dodge(width=0.1))+
scale_y_continuous(labels=percent_format(), limits = c(0,1))
However, the resulting plot does not show the bars next to one another, but rather some on top of one another. What gives and how do I fix this?
You need to convert the cyl column to factor.
test$cyl <- as.factor(test$cyl)
ggplot(test, aes(x=gear, y=Freq))+
geom_bar(stat="identity", aes(fill=cyl), position=position_dodge(width=1))+
scale_y_continuous(labels=percent_format(), limits = c(0,1))

How to adjust ggplot graph regarding color and scale?

I have some difficulties to adjust a graph regarding color and scale:
Here some data:
#Table 1
date<-c("2015-08-07","2015-08-08","2015-08-09")
A<-c(7268.45,11212.46,12850.15)
B<-c(7009.32,5665.81,16492.11)
C<-c(3582.07,1793.50,5556.42)
D<-c(3653.33,2335.34,2007.50)
df<-data.frame(date,A,B,C,D)
#Table 2
date<-c("2015-08-07","2015-08-08","2015-08-09")
A<-c(7885,8202,11342)
B<-c(7857,8034,11518)
C<-c(3147,3768,4487)
D<-c(3084,3669,4456)
df1<-data.frame(date,A,B,C,D)
#Table 1 / Table 2
date<-c("2015-08-07","2015-08-08","2015-08-09")
A<-c(0.8921115,0.7052290,1.4318554)
B<-c(0.9218072,1.3670397,1.1329704)
C<-c(1.1382491,0.4759820,1.2383374)
D<-c(1.1846077,0.6365059,0.4505162)
df2<-data.frame(date,A,B,C,D)
#Plot:
library(ggplot2)
library(grid)
library(gridExtra)
library(dplyr)
library(tidyr)
df$df = "Table 1"
df1$df = "Table 2"
df2$df = "Table1 / Table2"
bind_rows(df, df1, df2) %>%
gather(variable, value, -c(date, df)) %>%
ggplot(aes(x=as.Date(date), y=value, group=variable)) +
geom_line(aes(colour = variable)) +
facet_wrap(~df, ncol = 1) +
scale_x_date() + xlab("")
As one can see the ratio between Table1 / Table2 is on the same scale as the graphs above. I would like to have Table1 / Table2 between 0 -2 Additionally I cant really differentiate the colors. Is there a way to make them bold or enhance there perceptibility?
You can set scales='free_y' within facet_wrap function to scale each of the facets separately.
For colouring, check out color brewer website. There you can find some color schemes which can be used within ggplot2.
I like the Set1 or Set3 colours a lot. Some example how to integrate are here
bind_rows(df, df1, df2) %>%
gather(variable, value, -c(date, df)) %>%
ggplot(aes(x=as.Date(date), y=value, group=variable)) +
geom_line(aes(colour = variable)) +
facet_wrap(~df, ncol = 1) +
scale_x_date() + xlab("") +
scale_color_brewer(palette='Set1')

Resources