如何基于现有日期创建年份-星期字符串值序列?

时间:2019-04-24 09:45:13

标签: r sequence

我正在绘制从2018年到2019年的每周数据,而我的X轴上的刻度线表示当时的年份。

例如:

2018-50, 2018-51, 2018-52, 2018-53, 2019-01, 2019-02, 2019-03

我有两个数据框,但是两个数据框中的日期并不总是相同。因此,我想到的一种解决方案可能会起作用,即在任一数据帧中找到最低的yearWeek值,并在任一数据帧中找到最大的yearWeek值,然后使用这些值创建一个序列两个值。请注意,这两个值都可能存在于单个数据帧中,或者一个数据帧可能具有最低/最早的值,而另一个数据最高/最新的值。

两个数据框都看起来像这样:

  week yearWeek      month  day       date
1   31  2018-31 2018-08-01  Wed 2018-08-01
2   31  2018-31 2018-08-01  Thu 2018-08-02
3   31  2018-31 2018-08-01  Fri 2018-08-03
4   31  2018-31 2018-08-01  Sat 2018-08-04
5   32  2018-32 2018-08-01  Sun 2018-08-05
6   32  2018-32 2018-08-01  Mon 2018-08-06

我一直在寻找解决方案,this answer差不多在那儿了,但还不够。

此解决方案的问题是:

  • 单位数星期数字前没有0;和
  • 例如,尽管指定了seq(31:53),但输出却从1开始(我知道为什么会这样);和
  • 似乎没有一种方法可以使用这种方法在53处停止计数(2018年我想包括一个(短)第53周)并从2019-01开始恢复。

我希望能够将X轴范围设置为2018-31(2018年第31周)到2019-13(2019年第13周)。

类似这样的东西:

enter image description here

简而言之,如何创建从最小日期值到最大日期值(在这种情况下为2018-31-2019-13)之间的年周值序列?

4 个答案:

答案 0 :(得分:1)

我认为这对您有用

x1 <- c(31:53)
x2 <- sprintf("%02d", c(1:13))
paste(c(rep(2018, length(x1)), rep(2019, length(x2))), c(x1, x2), sep = "-")

# [1] "2018-31" "2018-32" "2018-33" "2018-34" "2018-35" "2018-36" "2018-37" 
#     "2018-38" "2018-39" "2018-40" "2018-41" "2018-42" "2018-43" "2018-44" 
#     "2018-45" "2018-46" "2018-47" "2018-48" "2018-49" "2018-50" "2018-51" 
#     "2018-52" "2018-53" "2019-01" "2019-02" "2019-03" "2019-04" "2019-05" 
# "2019-06" "2019-07" "2019-08" "2019-09" "2019-10" "2019-11" "2019-12" "2019-13"

对于更新后的问题,我们可以做

#rbind both the dataset
df <- rbind(df1, df2)

#convert them to date
df$Date <- as.Date(df$date)

#Generate a sequence from min date to maximum date, format them 
# to year-week combination and select only the unique ones
unique(format(seq(min(df$Date), max(df$Date), by = "day"), "%Y-%W"))

答案 1 :(得分:0)

定义两个序列,然后将其限制为所需的范围:

years <- c("2018", "2019")
months <- sprintf("%02d", c(1:52))

result <- apply(expand.grid(years, months), 1, function(x) paste(x,collapse="-"))
result <- result[result >= "2018-31" & result <= "2019-13"]
result

 [1] "2019-01" "2019-02" "2019-03" "2019-04" "2019-05" "2019-06" "2019-07"
 [8] "2019-08" "2019-09" "2019-10" "2019-11" "2019-12" "2019-13" "2018-31"
[15] "2018-32" "2018-33" "2018-34" "2018-35" "2018-36" "2018-37" "2018-38"
[22] "2018-39" "2018-40" "2018-41" "2018-42" "2018-43" "2018-44" "2018-45"
[29] "2018-46" "2018-47" "2018-48" "2018-49" "2018-50" "2018-51" "2018-52"

请注意,即使在使用文本日期字符串的情况下,也不需要修剪日期,因为所有日期都是固定宽度的字符串,并且在必要时保留零填充。因此,排序工作与对实际数字进行排序一样。

答案 2 :(得分:0)

有可能使用str_pad包中的stringr函数:

weeks <- str_pad(41:65 %% 53 + 1, 2, "left", "0")
years <- ifelse(41:65 <= 52, "2018", "2019")
paste(years, weeks, sep = "-")
     [1] "2018-42" "2018-43" "2018-44" "2018-45" "2018-46" "2018-47" "2018-48" "2018-49" "2018-50" "2018-51" "2018-52" "2018-53" "2019-01" "2019-02" "2019-03" "2019-04" "2019-05" "2019-06" "2019-07" "2019-08" "2019-09"
[22] "2019-10" "2019-11" "2019-12" "2019-13"

正如我从其他两个答案中学到的,sprintf提供了str_pad的基本替代方案。因此,您也可以使用

weeks <- sprintf("%02d", 41:65 %% 53 + 1)

答案 3 :(得分:0)

有可能使用strftime

weeks <- seq(from = ISOdate(2018,12,10), to = ISOdate(2019,4,1), by="week")
strftime(weeks,format="%Y-%W")