0
votes

I have a dataset that I want to summarize by calculating the ratio of 2 columns. However, I also need to calculate this ratio by different ‘cuts’ of my data set. i.e, ratio of the overall data, ratio by year, ratio by type, etc.
I will also need to put each ratio calculation in a bar chart.

What I want to know is whether I can plot all these bar charts without having to create a separate summary grouping dataset first.

For example, right now, before I send it to ggplot, I use group_by/summarize to my data first to calculate the ratio. Then I send it to ggplot.

Chart1 <- data %>% group_by(cut1) %>% summarise(ratio=sum(column1)/sum(column2))
ggplot(Chart1, aes(x=cut1, y=ratio)) + geom_bar(stat='identity', fill = "tomato2")

for chart 2 and chart 3, I do the same thing again

Chart2 <- data %>% group_by(cut2) %>% summarise(ratio=sum(column1)/sum(column2))
ggplot(Chart2, aes(x=cut2, y=ratio)) + geom_bar(stat='identity', fill = "tomato2")
Chart3 <- data %>% group_by(cut3) %>% summarise(ratio=sum(column1)/sum(column2))
ggplot(Chart3, aes(x=cut3, y=ratio)) + geom_bar(stat='identity', fill = "tomato2")

Is there another way to do this? Initially, I was thinking there would be a way that I can just create the ratio once and then I can use it over many times (similar to a calculated field in excel pivot tables). Is there something better than the above method?

Also, if summarizing each ratio separately is the best way, how do I do a facet chart? For example, I may want to do a facet of ratio to cut 1 and cut 2

edit: more info with example using created data:

c1 <- c('a','a','a', 'b','b', 'b', 'c','c','c')
c2 <- c('aa','aa','aa', 'bb','bb', 'bb', 'cc','cc','cc')
v1 <-c(1,2,3,4,5,6,7,8,9)
v2<-c(9,8,7,6,5,4,3,2,1)
mydata <-data.frame(c1,c2,v1,v2)

Chart1 <- mydata %>% group_by(c1) %>% summarise(ratio=sum(v1)/sum(v2))
ggplot(Chart1, aes(x=c1, y=ratio)) + geom_bar(stat='identity', fill = "tomato2") + theme(axis.text.x=element_text(angle=90))

The outcome I want is to understand how to best summarize data before plotting it. Do I need to summarize each calculation by each grouping seperatly, or is there an easier way? for the example above, if I wanted to calculate ratio and group it by c1, and then create another ratio chart and group by c2, and then another by c3....do I need to do 3 different aggregations.

1
can we see the data and the expected output? - Sada93
If each of your ‘cuts’ is just grouping by a particular column, and those columns all contain the same type (or can be coerced to the same type), I think you could gather those columns, let x = value, and facet by the key. - Joe
@Sada93 edited my post with an example, if that helps. Joe, not gonna lie. I'm still new to R so not too familiar with your suggestion, but will defn look into it and try to understand it. - semidevil
@semidevil, I’ll type it up what I’m thinking will work right now, and post it in a few minutes if no one else has answered by then. - Joe

1 Answers

0
votes

Does this accomplish what you want?

library(tidyverse)

c1 <- c('a','a','a', 'b','b', 'b', 'c','c','c')
c2 <- c('aa','aa','aa', 'bb','bb', 'bb', 'cc','cc','cc')
v1 <-c(1,2,3,4,5,6,7,8,9)
v2<-c(9,8,7,6,5,4,3,2,1)
mydata <-data.frame(c1,c2,v1,v2)

Chart1 <- mydata %>% 
  gather(key = 'cuts', value = 'categories', -(v1:v2)) %>% 
  group_by(cuts, categories) %>% 
  summarise(ratio=sum(v1)/sum(v2))

# This lets you facet them onto the same chart, 
#   but that doesn't really make sense,
#   since the cuts will have different x axes
ggplot(Chart1, aes(x=categories, y=ratio)) + 
  geom_bar(stat='identity', fill = "tomato2") +
  facet_grid(cuts~.) +
  theme(axis.text.x=element_text(angle=90))

# This lets you make each plot separately
Chart1 %>% 
  filter(cuts == 'c1') %>% 
  ggplot(aes(x=categories, y=ratio)) + 
  geom_bar(stat='identity', fill = "tomato2") +
  theme(axis.text.x=element_text(angle=90))

# Use a for loop to save all of the plots to files
for(i in 1:(length(mydata)-2)){
  p <- 
    Chart1 %>% 
    filter(cuts == names(mydata)[[i]]) %>% 
    ggplot(aes(x=categories, y=ratio)) + 
    geom_bar(stat='identity', fill = "tomato2") +
    theme(axis.text.x=element_text(angle=90))


  ggsave(paste0("myPlot",i,".png"), plot = p)
}

Only thing that I wasn't sure about, is how to facet the different cuts if they don't have the same values on the x-axis. If you just want to stack them on top of each other, you could use the gridExtra package:

library(gridExtra)

plot1 <- Chart1 %>% 
  filter(cuts == 'c1') %>% 
  ggplot(aes(x=categories, y=ratio)) + 
  geom_bar(stat='identity', fill = "tomato2") +
  theme(axis.text.x=element_text(angle=90))

plot2 <- Chart1 %>% 
  filter(cuts == 'c2') %>% 
  ggplot(aes(x=categories, y=ratio)) + 
  geom_bar(stat='identity', fill = "tomato2") +
  theme(axis.text.x=element_text(angle=90))

grid.arrange(plot1, plot2, ncol=1, nrow = 2)