Site icon R-bloggers

Animating Data Transformations: Part II

[This article was first published on R Tutorials – Omni Analytics Group, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

In our previous series on Animating Data Transformations, we showed you how to use gganimate to construct an animation which illustrates the process of going between tall and wide representations of data. Today, we will show the same procedure for constructing an animation of the unnest() function.

The unnest() function takes a tibble containing a list column and converts it to a tibble such that each element in the list comprises a single row. Think of it as “unpacking” the list column into a more standard vector column in R.

We will create a toy dataset using the sleep data, and ensure that it contains a list column:

library(tidyverse)
library(gganimate)

sleep_data <- sleep %>%
    mutate(group = rep(1:4, each = 5),
           ID = rep(1:4, each = 5)) %>%
    select(id = ID, group, data = extra)

sleep_data
# A tibble: 20 x 3
      id group  data
   <int> <int> <dbl>
 1     1     1   0.7
 2     1     1  -1.6
 3     1     1  -0.2
 4     1     1  -1.2
 5     1     1  -0.1
...

You can see that we have a 20 row by 3 column tibble in R. Next, we perform the following routine in order to nest the data column into a new nesteddata column:

sleep_nested <- sleep_data %>%
    group_by(group) %>%
    summarise(id = id[1], nesteddata = list(data))

sleep_nested
# A tibble: 4 x 3
  group    id nesteddata
  <int> <int> <list>    
1     1     1 <dbl [5]> 
2     2     2 <dbl [5]> 
3     3     3 <dbl [5]> 
4     4     4 <dbl [5]>

Next, we perform a similar routine to the previous blog and combine the two datasets into one dataset which will be used to build the animation:

longDat <- function(x) {
    names(x) %>%
        rbind(x) %>%
        setNames(seq_len(ncol(x))) %>%
        mutate(row = row_number()) %>%
        tidyr::gather(column, value, -row) %>%
        mutate(column = as.integer(column)) %>%
        ungroup() %>%
        arrange(column, row)
}

long_tables <- map(list(sleep_nested, sleep_data), longDat)

nested_table <- long_tables[[1]] %>% 
    mutate(tstep = "a",
           value = sapply(value, paste, collapse = ", "))

unnested_table <- long_tables[[2]] %>% 
    mutate(tstep = "b")

both_tables <- bind_rows(nested_table, unnested_table)

both_tables$celltype[both_tables$column == 1] <- c("header", rep("id", 4), "header", rep("id", 20))
both_tables$celltype[both_tables$column == 2] <- c("header", rep(1:4, each = 1), "header", rep(1:4, each = 5))
both_tables$celltype[both_tables$column == 3] <- c("header", rep("nesteddata", 4), "header", rep("data", 20))

both_tables
# A tibble: 78 x 5
     row column value tstep celltype
   <int>  <int> <chr> <chr> <chr>   
 1     1      1 group a     header  
 2     2      1 1     a     id      
 3     3      1 2     a     id      
 4     4      1 3     a     id      
 5     5      1 4     a     id      
 6     1      2 id    a     header  
 7     2      2 1     a     1       
 8     3      2 2     a     2       
 9     4      2 3     a     3       
10     5      2 4     a     4       
# … with 68 more rows

From this, we can produce static versions of the two images which will form the basis for the animation:

base_plot <- ggplot(both_tables, aes(column, -row, fill = celltype)) +
    geom_tile(color = "black") + 
    theme_void() +
    scale_fill_manual(values = c("#247ba0","#70c1b3","#b2dbbf","turquoise2", "#ead2ac", "grey60", "mistyrose3", "#ffae63"),
                      name = "",
                      labels = c("Group 1", "Group 2", "Group 3", "Group 4", "Data", "Header", "ID", "Nested Data"))

base_plot + 
    facet_wrap(~tstep)
The static plot that will be used to generate the animation

Finally, we use gganimate to build the final animation!

p1 <- base_plot +
    transition_states(
        states            = tstep,
        transition_length = 1,
        state_length      = 1
    ) +
    enter_fade() +
    exit_fade() +
    ease_aes('sine-in-out')

p1_animate <- animate(p1, height = 800, width = 600, fps = 20, duration = 10)
anim_save("unnest_animate.gif")

And there you have it! We hope this was helpful both in learning how to produce data transformation animations, and in terms of learning the unnest() operation itself. If you have any requests for more data transformation animations, please let us know, and be on the look out for future posts in this series!

The post Animating Data Transformations: Part II appeared first on Omni Analytics Group.

To leave a comment for the author, please follow the link and comment on their blog: R Tutorials – Omni Analytics Group.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.