This kind of thing is done using pivot_longer and pivot_wider.
library(tidyverse)
townRatingsCounts <- tibble::tribble(
~Municipality, ~`2002`, ~`2003`, ~`2004`, ~`2005`, ~`2006`, ~`2007`, ~`2008`,
"Acton", "Aaa", "Aaa", "Aa1", "Aa3", "Aaa", "Aa2", "Aa1",
"Arlington", "Baa", "Aa1", "Aa3", "Aaa", "Aa2", "Aaa", "Baa",
"Ashland", "A1", "Aa3", "Aa3", "Aaa", "Aa2", "Aa1", "Aaa"
)
townRatingsCounts %>%
pivot_longer(cols = starts_with("200")) %>%
group_by(Municipality, value) %>%
summarise(count = n()) %>%
ungroup() %>%
pivot_wider(names_from = "value", values_from = "count", values_fill = 0)
#> `summarise()` regrouping output by 'Municipality' (override with `.groups` argument)
#> # A tibble: 3 x 7
#> Municipality Aa1 Aa2 Aa3 Aaa Baa A1
#> <chr> <int> <int> <int> <int> <int> <int>
#> 1 Acton 2 1 1 3 0 0
#> 2 Arlington 1 1 1 2 2 0
#> 3 Ashland 1 1 2 2 0 1
Created on 2020-11-13 by the reprex package (v0.3.0)