is there any way to create an animation (gganimate) with ranges as transition times?

Jos*_*rah 0 r ggplot2 gganimate

Is there any way to make gganimate work for transition times that are ranges of years? In my data I have three time points, two of which are ranges as shown below.

data:

Year   rate   group
2012-2014   7   Other CT, White 
2015-2017   11  Other CT, White 
2018    3   Fairfield, Black    
2018    2   Fairfield, Hispanic
Run Code Online (Sandbox Code Playgroud)

here's an example of the code for the ggplot that I'd like to animate

data %>% ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {frame_time}") +
  transition_time(Year)
Run Code Online (Sandbox Code Playgroud)

when I enter the transition time as "Year" I get an error because my Year variable is a character to accommodate the ranges. This is the error I get:

Error: time data must either be integer, numeric, POSIXct, Date, difftime, orhms
Run Code Online (Sandbox Code Playgroud)

is there anything I can do to bypass this error and continue with the ranges as they are?

Jon*_*ing 6

我建议您transition_manual将年份与类别一样对待(失去平稳的过渡),或者将年份范围转换为数字。

library(tidyverse); library(gganimate)
df1 <- tribble(~Year, ~rate, ~group,
               "2012-2014", 7, "grp1",
               "2015-2017", 11, "grp1",
               "2018", 3, "grp1")
Run Code Online (Sandbox Code Playgroud)

第一种方法,将Year保持原样:

df1 %>% 
  ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {current_frame}") +
  transition_manual(Year)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

第二种方法,将年份转换为数字。在这种情况下,我只使用了第一年,但是您也可以将值分配给平均年,或者添加范围内每年的值的行。

df1 %>% 
  mutate(Year_numeric = parse_number(Year)) %>%
  ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {round(frame_time)}") +
  transition_time(Year_numeric)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

最后,如果要表示给定级别上的所有范围年份,则可以为所有组成年份创建行。但这需要一些肘部润滑脂:

df1 %>% 
  # For ranged years, find how many in range:
  mutate(year_num = 1 + if_else(Year %>% str_detect("-"), 
                            str_sub(Year, start = 6) %>% as.numeric() - 
                              str_sub(Year, end = 4) %>% as.numeric(), 
                            0)) %>%
  # ... and use that to make a row for each year in the range
  tidyr::uncount(year_num) %>%
  group_by(Year) %>%
  mutate(Year2 = str_sub(Year, end = 4) %>% as.numeric() + 
                 row_number() - 1) %>%
  ungroup() %>%

# FYI at this point it looks like:
# A tibble: 7 x 4
#  Year       rate group Year2
#  <chr>     <dbl> <chr> <dbl>
#1 2012-2014     7 grp1   2012
#2 2012-2014     7 grp1   2013
#3 2012-2014     7 grp1   2014
#4 2015-2017    11 grp1   2015
#5 2015-2017    11 grp1   2016
#6 2015-2017    11 grp1   2017
#7 2018          3 grp1   2018

ggplot(aes(y = rate, x = group)) +
  geom_col() +
  coord_flip() +
  labs(title = "Year: {round(frame_time)}") +
  transition_time(Year2)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明