Ferroao
Ferroao

Reputation: 3044

stack bars in plot without preserving label order

ggplot preserves the order of stacked bars according to labels:

d <- read.table(text='Day Location Length Amount
            1 2 3 1
            1 1 4 2
            3 3 3 2
            3 2 5 1',header=T)

d$Amount<-as.factor(d$Amount) # in real world is not numeric

ggplot(d, aes(x = Day, y = Length)) + 
  geom_bar(aes(fill = Amount), stat = "identity")

What I desired is something similar as the result of the plot without the as.factor line. That is: that the greater bars are always on top. However, I cannot do that with my data because I have categories, not numbers.

Similar post: https://www.researchgate.net/post/R_ggplot2_Reorder_stacked_plot

Solution can come in other R package

Note: data.frame is only demonstrative.

enter image description here

Upvotes: 0

Views: 2363

Answers (1)

Ferroao
Ferroao

Reputation: 3044

I came up with this solution:

(1) First, sort data.frame by column of values in decreasing order

(2) Then duplicate column of values, as factor.

(3) In ggplot group by new factor (values)

d <- read.table(text='Day Length Amount
                1 3 1
                1 4 2
                3 3 2
                3 5 1',header=T)

d$Amount<-as.factor(d$Amount) 

d <- d[order(d$Length, decreasing = TRUE),] # (1)

d$LengthFactor<-factor(d$Length, levels= unique(d$Length) ) # (2)

ggplot(d)+
  geom_bar(aes(x=Day, y=Length, group=LengthFactor, fill=Amount), # (3)
           stat="identity", color="white") 

enter image description here

{
library(data.table)
sam<-data.frame(population=c(rep("PRO",8),rep("SOM",4)),
                allele=c("alele1","alele2","alele3","alele4",rep("alele5",2),
                            rep("alele3",2),"alele2","alele3","alele3","alele2"), 
                frequency=rep(c(10,5,4,6,7,16),2) #,rep(1,6)))
)

sam <- setDT(sam)[, .(frequencySum=sum(frequency)), by=.(population,allele)]

sam <- sam[order(sam$frequency, decreasing = TRUE),] # (1)

# (2)
sam$frequency<-factor(sam$frequency, levels = unique(sam$frequency) )

library(ggplot2)
ggplot(sam)+
  geom_bar(aes(x=population, y=frequencySum, group=frequency, fill=allele), # (3)
           stat="identity", color="white") 
} 

enter image description here

Upvotes: 1

Related Questions