How to "uncount": expand counts into multiple rows

I've seen this on Stack Overflow but my google-fu is off today!

How do I convert a summarized table, with counts n of each observance, into an expanded table where there are n rows showing the same observance data? For plotting purposes, I'd like to show a separate geom_point for each, not just a bigger one...

# I want to convert counts into separate observation rows, i.e. "uncount"
library(tidyverse)
#> -- Attaching packages ---------------------------------------------------------------------------------- tidyverse 1.2.1 --
#> v ggplot2 2.2.1.9000     v purrr   0.2.4     
#> v tibble  1.4.2          v dplyr   0.7.4     
#> v tidyr   0.8.0          v stringr 1.3.0     
#> v readr   1.1.1          v forcats 0.3.0
#> Warning: package 'tibble' was built under R version 3.4.4
#> -- Conflicts ------------------------------------------------------------------------------------- tidyverse_conflicts() --
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag()    masks stats::lag()

source <- tibble::tribble(
  ~ Group, ~ Count,
  "A", 1L,
  "B", 5L,
  "C", 3L
)

desired_output <- tibble::tribble(
  ~ Group, ~ Count,
  "A", 1L,
  "B", 1L,
  "B", 1L,
  "B", 1L,
  "B", 1L,
  "B", 1L,
  "C", 1L,
  "C", 1L,
  "C", 1L
)

# test of desired output
test <-
  desired_output %>%
  group_by(Group) %>%
  tally() %>%
  rename(Count = n)

test == source
#>      Group Count
#> [1,]  TRUE  TRUE
#> [2,]  TRUE  TRUE
#> [3,]  TRUE  TRUE

The most recent version of tidyr has uncount(). You may need to play with it a bit to get exactly what you want.

library(tidyverse)

source <- tibble::tribble(
  ~ Group, ~ Count,
  "A", 1L,
  "B", 5L,
  "C", 3L
)

uncount(source, weights = Count, .remove = FALSE)
#> # A tibble: 9 x 2
#>   Group Count
#>   <chr> <int>
#> 1 A         1
#> 2 B         5
#> 3 B         5
#> 4 B         5
#> 5 B         5
#> 6 B         5
#> 7 C         3
#> 8 C         3
#> 9 C         3

Created on 2018-03-22 by the reprex package (v0.2.0).

6 Likes

Thanks! Nice and simple.