Coding in R: Pivot Painlessly. A quick guide to pivot_longer and... | by Rebecca O’Dwyer | Towards Data Science

I can’t gather or spread. I have some kind of mental block and can’t remember which one is which. I almost always use the wrong one, end up with some weird tibble and slam my laptop shut in frustration. Therefore, I thank the R Gods for the recently released pivot_wider and pivot_longer. I find them infinitely more intuitive and can now pivot with ease.
To demonstrate the tidyverse’s new pivot functions, I am using the 2019 NYC Squirrel Census data set from R4DS Online Learning Community’s 29 October 2019 #TidyTuesday challenge.
library(tidyverse)# Load NYC Squirrel Census data setsquirrel <- read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-10-29/nyc_squirrels.csv")
I am interested in the activities of the squirrels, specifically which coloured squirrels are the friendliest. The useful variables are approaches, indifferent and runs_from. These are logical so convert them to numeric. Also make primary_fur_color a factor.
squirrel_tidy <- squirrel %>%   select(primary_fur_color, approaches, indifferent, runs_from) %>%   mutate(primary_fur_color = fct_explicit_na(primary_fur_color, "Unknown")) %>%   mutate_if(is_logical, ~as.numeric(.))
To find the percentage of squirrels of each colour that approached, were indifferent to, or ran from their squirrel spotter, I use group_by and summarise_if with mean.
friendly <- squirrel_tidy %>%   group_by(primary_fur_color) %>%   summarise_if(is.numeric, ~mean(.))## # A tibble: 4 x 4##   primary_fur_color approaches indifferent runs_from##   <fct>                  <dbl>       <dbl>     <dbl>## 1 Black                 0.0583       0.427     0.311## 2 Cinnamon              0.112        0.462     0.222## 3 Gray                  0.0510       0.493     0.223## 4 Unknown               0.0364       0.182     0.145
Now the data is in wide format and is ready for pivoting to long format. Use pivot_longer to move the activity columns (approaches, indifferent and runs_from) into a single column, called activity. The values from those columns will be moved into a single column called pct_activity.
friendly_long <- friendly %>%   pivot_longer(cols = c("approaches", "indifferent", "runs_from"),                names_to = "activity",                values_to = "pct_activity")## # A tibble: 5 x 3##   primary_fur_color activity    pct_activity##   <fct>             <chr>              <dbl>## 1 Black             approaches        0.0583## 2 Black             indifferent       0.427 ## 3 Black             runs_from         0.311 ## 4 Cinnamon          approaches        0.112 ## 5 Cinnamon          indifferent       0.462
Et voila! Tidy data, perfect for plotting with ggplot.
To pivot from long to wide format, perhaps because you are going to do some modelling, so need the features in columns, use pivot_wider.
friendly_wide <- friendly_long %>%   pivot_wider(names_from = "activity",               values_from = "pct_activity")## # A tibble: 4 x 4##   primary_fur_color approaches indifferent runs_from##   <fct>                  <dbl>       <dbl>     <dbl>## 1 Black                 0.0583       0.427     0.311## 2 Cinnamon              0.112        0.462     0.222## 3 Gray                  0.0510       0.493     0.223## 4 Unknown               0.0364       0.182     0.145
Plotting pct_activity versus primary_fur_color, faceted by activity reveals that cinnamon squirrels are the most likely to approach (scroll to bottom for code).
pivot_longer takes multiple columns and turns them into two columns, creating a tidy data format. pivot_wider is the opposite.
pivot_longer needs four inputs:
data.cols = selected columns to be turned into two columns.names_to = name for newly created column where the observations will be the names of all the columns you have selected.values_to = name for newly created column with all the values in it
data.
cols = selected columns to be turned into two columns.
names_to = name for newly created column where the observations will be the names of all the columns you have selected.
values_to = name for newly created column with all the values in it
pivot_wider needs three inputs:
data.names_from = name of column who’s observations will become the new column names.values_from = name of column who’s observations will become the new column observations.
data.
names_from = name of column who’s observations will become the new column names.
values_from = name of column who’s observations will become the new column observations.
squirrel_plot_theme <- theme_minimal() +  theme(axis.title.x = element_text(size = 10),        axis.title.y = element_text(size = 10),        plot.title = element_text(size = 14, face = "bold", family = "mono"),        plot.subtitle = element_text(size = 10, face = "bold", family = "mono"),        plot.caption = element_text(size = 10, face = "italic", hjust = 0))# Create caption to correctly source all plotssquirrel_caption <- "Data from Squirrel Census 2019"# Create colour palettesquirrel_pal <- wes_palette("IsleofDogs1", 6, type = "continuous")friendly_plot <- friendly_long %>%   group_by(primary_fur_color) %>%   ggplot()+  geom_col(aes(x = activity, y = pct_activity, fill = primary_fur_color)) +  facet_wrap(~primary_fur_color) +  squirrel_plot_theme +  scale_fill_manual(values = c(squirrel_pal[4], squirrel_pal[2],                                 squirrel_pal[6], squirrel_pal[3]), name = "") +  scale_y_continuous(labels = percent_format(accuracy = 1), limits = c(-0.05, 0.5)) +  theme(axis.text.x = element_text(angle = 0),         panel.grid.minor = element_blank(),        legend.position = "none") +  labs(title = "Cinnamon squirrels are the friendliest",       subtitle = "Percentage of squirrels reported as approaching, being indifferent to or running from their squirrel spotter\n",       x = "",       y = "",       caption = squirrel_caption)