在ggplot2中绘制时间序列,并在CDC周内明确订购

时间:2017-05-08 20:21:35

标签: ggplot2 time-series

我有一个这样的数据框('示例')。

        n CDCWeek Year Week
25.512324 2011-39 2011   39
26.363035  2011-4 2011    4
25.510500 2011-40 2011   40
25.810663 2011-41 2011   41
25.875451 2011-42 2011   42
25.860873 2011-43 2011   43
25.374876 2011-44 2011   44
25.292944 2011-45 2011   45
24.810807 2011-46 2011   46
24.793090 2011-47 2011   47
22.285000 2011-48 2011   48
23.015480 2011-49 2011   49
26.296376  2011-5 2011    5
22.074581 2011-50 2011   50
22.209183 2011-51 2011   51
22.270705 2011-52 2011   52
25.391377  2011-6 2011    6
25.225481  2011-7 2011    7
24.678918  2011-8 2011    8
24.382214  2011-9 2011    9

我想将此作为时间序列与CDCWeek'作为X轴和' n'作为Y使用此代码。

ggplot(Example, aes(CDCWeek, n, group=1)) + geom_line()

我遇到的问题是它没有以正确的顺序绘制CDCWeek。 CDCWeek是一年后的一周(1到52或53,取决于年份)。它按照数据框中显示的顺序绘制,2011-39后跟2011-4等。我理解为什么会发生这种情况,但无论如何迫使ggplot2使用正确的周数顺序?

编辑:我不能只使用“周”。变量,因为实际数据集涵盖了很多年。

谢谢

4 个答案:

答案 0 :(得分:0)

将年份和周转换为dplyr的日期:

df <- df %>% 
      mutate(date=paste(Year, Week, 1, sep="-") %>% 
                  as.Date(., "%Y-%U-%u"))

ggplot(df, aes(date, n, group=1)) + 
    geom_line() + 
    scale_x_date(date_breaks="8 week", date_labels = "%Y-%U")

enter image description here

答案 1 :(得分:0)

一种选择是使用您已有的年份和周期变量,但按年份分面。我稍微更改了数据中的Year变量以表明我的情况。

Example$Year = rep(2011:2014, each = 5)

ggplot(Example, aes(x = Week, y = n)) + 
  geom_line() + 
  facet_grid(Year~., scales = "free_x")
  #facet_grid(.~Year, scales = "free_x")

这具有能够跨年比较的额外优势。如果你将最后一行切换到我已注释掉的选项,那么facet将是水平的。

enter image description here

另一种选择是按年度分组作为因素水平,并将它们全部包括在同一个数字中。

ggplot(Example, aes(x = Week, y = n)) + 
  geom_line(aes(group = Year, color = factor(Year))) 

enter image description here

答案 2 :(得分:0)

事实证明我只需要正确订购Example $ CDCWeek,然后ggplot会正确地绘制它。

1)按正确的顺序放置数据库。

Example <- Example[order(Example$Year, Example$Week), ]

2)重置rownames。

row.names(Example) <- NULL

3)使用rownames

中的观察编号创建一个新变量
Example$Obs <- as.numeric(rownames(Example))

4)根据观察号

将CDCWeeks变量命令为一个因子
Example$CDCWeek  <-  factor(Example$CDCWeek, levels=Example$CDCWeek[order(Example$Obs)], ordered=TRUE)

5)图表

ggplot(Example, aes(CDCWeek, n, group=1)) + geom_line()

非常感谢大家的帮助!

答案 3 :(得分:0)

aweek::get_date仅允许您使用年份和Epiweek获得每周日期。

在这里,我创建了一个带有一系列日期(link)的reprex,使用lubridate::epiweek提取了Epiweek,将周日定义为aweek::set_week_start,定义了周日,总结了每周值,并创建了带有aweek::get_date的新日期向量,并绘制它们。

library(tidyverse)
library(lubridate)
library(aweek)

data_ts <- tibble(date=seq(ymd('2012-04-07'),
                           ymd('2014-03-22'), 
                           by = '1 day')) %>% 
  mutate(value = rnorm(n(),mean = 5),
         #using aweek
         epidate=date2week(date,week_start = 7),
         #using lubridate
         epiweek=epiweek(date),
         dayw=wday(date,label = T,abbr = F),
         month=month(date,label = F,abbr = F),
         year=year(date)) %>% 
  print()
#> # A tibble: 715 x 7
#>    date       value epidate    epiweek dayw      month  year
#>    <date>     <dbl> <aweek>      <dbl> <ord>     <dbl> <dbl>
#>  1 2012-04-07  3.54 2012-W14-7      14 sábado        4  2012
#>  2 2012-04-08  5.79 2012-W15-1      15 domingo       4  2012
#>  3 2012-04-09  4.50 2012-W15-2      15 lunes         4  2012
#>  4 2012-04-10  5.44 2012-W15-3      15 martes        4  2012
#>  5 2012-04-11  5.13 2012-W15-4      15 miércoles     4  2012
#>  6 2012-04-12  4.87 2012-W15-5      15 jueves        4  2012
#>  7 2012-04-13  3.28 2012-W15-6      15 viernes       4  2012
#>  8 2012-04-14  5.72 2012-W15-7      15 sábado        4  2012
#>  9 2012-04-15  6.91 2012-W16-1      16 domingo       4  2012
#> 10 2012-04-16  4.58 2012-W16-2      16 lunes         4  2012
#> # ... with 705 more rows

#CORE: Here you set the start of the week!
set_week_start(7) #sunday
get_week_start()
#> [1] 7

data_ts_w <- data_ts %>% 
  group_by(year,epiweek) %>% 
  summarise(sum_week_value=sum(value)) %>% 
  ungroup() %>% 
  #using aweek
  mutate(epi_date=get_date(week = epiweek,year = year),
         wik_date=date2week(epi_date)
         ) %>% 
  print()
#> # A tibble: 104 x 5
#>     year epiweek sum_week_value epi_date   wik_date  
#>    <dbl>   <dbl>          <dbl> <date>     <aweek>   
#>  1  2012       1          11.0  2012-01-01 2012-W01-1
#>  2  2012      14           3.54 2012-04-01 2012-W14-1
#>  3  2012      15          34.7  2012-04-08 2012-W15-1
#>  4  2012      16          35.1  2012-04-15 2012-W16-1
#>  5  2012      17          34.5  2012-04-22 2012-W17-1
#>  6  2012      18          34.7  2012-04-29 2012-W18-1
#>  7  2012      19          36.5  2012-05-06 2012-W19-1
#>  8  2012      20          32.1  2012-05-13 2012-W20-1
#>  9  2012      21          35.4  2012-05-20 2012-W21-1
#> 10  2012      22          37.5  2012-05-27 2012-W22-1
#> # ... with 94 more rows

#you can use get_date output with ggplot
data_ts_w %>% 
  slice(-(1:3)) %>% 
  ggplot(aes(epi_date, sum_week_value)) + 
  geom_line() + 
  scale_x_date(date_breaks="5 week", date_labels = "%Y-%U") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  labs(title = "Weekly time serie",
       x="Time (Year - CDC epidemiological week)",
       y="Sum of weekly values")

ggsave("figure/000-timeserie-week.png",height = 3,width = 10)

reprex package(v0.3.0)

创建于2019-08-12

enter image description here