dplyr - compare grouped variables to a subset of grouped variables

Viewed 49

Let's say I have a table of purchases in a long format. It looks something like:

purchases = data.frame(
    Item = c("Bike", "Bike", "Bike", "Bike", "Car", "Car", "Car", "Car"),
    Variable = c("Age", "Age", "Price", "Price", "Age", "Age", "Price", "Price"),
    Value = c("New", "Used", "Full", "Discount", "New", "Used", "Discount", "Discount")
)

I want to see the distribution of Value grouped by Item and Variable. So I could say "Of all Bikes sold, 50% were used" or "All Cars were sold at a discount."

The ideal output would be a table that looks like this:

enter image description here

I can get the count in dplyr doing something like this:

purchases %>% group_by(Item, Variable, Value) %>%
    summarise(Total = n())

I would then went to divide each of those values by their respective groupings of just Item and Variable. I can think of some long answers where I conditionally add corresponding counts in another variable, but I was hoping to find an easy way to do it through dplyr. Another way to describe it might be performing calculations on one level up of a grouping.

1 Answers
library(tidyverse)
purchases %>%
  count(Item, Variable, Value) %>%
  group_by(Item, Variable) %>%
  mutate(pct = n / sum(n)) %>%
  ungroup()

# A tibble: 7 x 5
  Item  Variable Value        n     pct
  <fct> <fct>    <fct>    <int>   <dbl>
1 Bike  Age      New          1     0.5
2 Bike  Age      Used         1     0.5
3 Bike  Price    Discount     1     0.5
4 Bike  Price    Full         1     0.5
5 Car   Age      New          1     0.5
6 Car   Age      Used         1     0.5
7 Car   Price    Discount     2     1 
Related