如何根据现有日期创建一系列年-周字符串值?

How can I create a sequence of year-week string values based on existing dates?

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

例如:

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

我有两个数据框,其中的日期并不总是相同。因此,我想到的一个可能有效的解决方案是在任一数据框中找到最低的 yearWeek 值,并在任一数据框中找到最大的 yearWeek 值,然后使用这些创建一个序列两个值。请注意,这两个值可以存在于单个数据帧中,或者一个数据帧可以具有 lowest/earliest 值而另一个具有 highest/latest 值。

两个数据框如下所示:

  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

我一直在寻找解决方案, 几乎找到了,但还不完全是。

此解决方案存在的问题是:

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

像这样:

简而言之,我如何创建从最小日期值到最大日期值的年-周值序列(在本例中为 2018-31-2019-13 )?

我认为这对你有用

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"))

定义两个序列,然后限制到你想要的范围内:

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"

请注意,即使使用文本日期字符串,我们不希望删除的日期在这里也能正常工作,因为所有日期都是固定宽度的字符串,并且在必要时用零填充。因此,排序的工作方式与实际数字相同。

可以使用 stringr 包中的 str_pad 函数:

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)

这里有一个可能性,使用 strftime:

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