Reputation: 313
I have a dataset like below
City<-c("X","Y","Z","X","Z","X","Y")
House_Unit_Id<-c("H1","H2","H3","H4","H5","H6","H7")
Adult<-c(50,100,60,40,50,80,60)
Child<-c(40,0,40,20,50,20,30)
Baby<-c(10,0,0,40,0,0,10)
data<-data.frame(City,House_Unit_Id,Adult,Child,Baby)
City House_Unit_Id Adult Child Baby
X H1 50 40 10
Y H2 100 0 0
Z H3 60 40 0
X H4 40 20 40
Z H5 50 50 0
X H6 80 20 0
Y H7 60 30 10
I need a percentage column stack chart like below
I tried the below code but the required output is not appearing as a percentage stack bar chart.
Chart <- plot_ly(data,x = ~City, y = ~Adult, type = 'bar',name= 'Adult') %>%
add_trace(y = ~Child, name = 'Child') %>%
add_trace(y = ~Baby, name = 'Baby') %>%
layout(yaxis = list(title = 'Percentage (%)'),barmode = "stack")
I could not find any answers for this type of chart for plotly package in R. Can anyone please help me with this?
Upvotes: 3
Views: 16124
Reputation: 136
The following code gives you the plot you describe, with the total number of type (Adult/Children/Baby) in each City in the hovertext (If you also want it on the plot itself you can try add_annotations)
City<-c("X","Y","Z","X","Z","X","Y")
House_Unit_Id<-c("H1","H2","H3","H4","H5","H6","H7")
Adult<-c(50,100,60,40,50,80,60)
Child<-c(40,0,40,20,50,20,30)
Baby<-c(10,0,0,40,0,0,10)
data<-data.frame(City,House_Unit_Id,Adult,Child,Baby)
library(plyr)
# Changing the data frame before plotting ... there is propably an easier way to do this!
newdata <- ldply(3:5,function(n){tempdata <- data[,c(1,n)]
colnames(tempdata)[2] <- "Number"
tempdata$type <- colnames(data[n])
return(tempdata)})
newdata <- ddply(newdata,.(City,type),summarize,Number=sum(Number))
# Total for each city
datatotal <- ddply(newdata,~City,summarize,n=sum(Number))
# Merge the data frames together
newdata <- merge(newdata,datatotal)
# Calc the percentages
newdata$perc <- newdata$Number/newdata$n
plot_ly(newdata,x = ~City, y = ~perc*100, type = 'bar',color = ~type,text=~Number,hoverinfo = 'text') %>%
layout(yaxis = list(title = 'Percentage (%)'),barmode = "stack")
Upvotes: 4
Reputation: 18681
Since you want stacked percentage barplots across "City" not "House_Unit_Id", there are two things you can do. Either use the proportions you now have and create a combination of stacked and grouped barplot, where you are stacking by House_Unit_Id and grouping by City. Currently, I don't think the plotly package (correct me if I am wrong) is capable of doing this. You can use ggplot to do this.
However, if you really want to only compare percentages across City, you should aggregate the counts in Adult, Child and Baby with something like this:
newData = aggregate(. ~ City, data = data, FUN = sum)
Then calculate the proportions by City. After that, you can plot the percentages as stacked bars for each City.
Chart <- plot_ly(newData, x = ~City, y = ~Adult, type = 'bar', name= 'Adult') %>%
add_trace(y = ~Child, name = 'Child') %>%
add_trace(y = ~Baby, name = 'Baby') %>%
layout(yaxis = list(title = 'Percentage (%)'), barmode = "stack")
This will work if you aggregate your counts data by City and calculate the proportions for each City.
Upvotes: 1