我正在致力于将基于周的日期转换为基于月份的日期.
在检查我的工作时,我在我的数据中发现了以下问题,这是对简单调用的结果 as.Date()
as.Date("2016-50-4", format = "%Y-%U-%u") as.Date("2016-50-5", format = "%Y-%U-%u") as.Date("2016-50-6", format = "%Y-%U-%u") as.Date("2016-50-7", format = "%Y-%U-%u") # this is the problem
前面的代码生成前3行的正确日期:
"2016-12-15" "2016-12-16" "2016-12-17"
然而,最后一行代码可以追溯到1周:
"2016-12-11"
谁能解释一下这里发生了什么?
一年中的一周工作可能变得非常棘手.您可以尝试使用ISOweek
包转换日期:
# create date strings in the format given by the OP wd <- c("2016-50-4","2016-50-5","2016-50-6","2016-50-7", "2016-51-1", "2016-52-7") # convert to "normal" dates ISOweek::ISOweek2date(stringr::str_replace(wd, "-", "-W"))
结果
#[1] "2016-12-15" "2016-12-16" "2016-12-17" "2016-12-18" "2016-12-19" "2017-01-01"
是一流的Date
.
请注意,基于ISO周的日期格式在周数之前yyyy-Www-d
有一个大写W
.这需要将其与标准的基于月份的日期格式区分开来yyyy-mm-dd
.
因此,为了转换OP提供的日期字符串,ISOweek2date()
必须W
在第一个连字符之后插入一个连字符,这是-
通过-W
在每个字符串中替换第一个连字符来完成的.
另请注意,ISO周从星期一开始,一周的日期编号为1到7.属于ISO周的年份可能与日历年不同.这可以从上面的基于周的日期2016-W52-7
转换为的样本日期中看出2017-01-01
.
ISOweek
包裹早在2011年,%G
,%g
,%u
,和%V
格式规范并不适用于strptime()
在R的Windows版本这是恼人的,因为我已经准备每周的报告,包括周环周的比较.我花了几个小时找到一个解决方案来处理ISO周,ISO工作日和ISO年.最后,我最终创建了ISOweek
包并在CRAN上发布它.今天,该软件包仍然有其优点,因为上述格式在输入时被忽略(?strptime
详情请参见参考资料).
正如@lmo在评论中所说的那样,%u
工作日代表十进制数字(1-7,周一为1),并%U
代表星期几作为十进制数字(00-53),使用星期日作为第一天.因此,as.Date("2016-50-7", format = "%Y-%U-%u")
将导致"2016-12-11"
.
但是,如果应该给出"2016-12-18"
,那么你应该使用星期一作为开始日的周格式.根据文档,?strptime
您可以预期格式"%Y-%V-%u"
会给出正确的输出,其中%V
一年中的星期为十进制数(01-53),星期一为第一天.
不幸的是,它没有:
> as.Date("2016-50-7", format = "%Y-%V-%u") [1] "2016-01-18"
然而,在解释结束时,%V
sais "接受但忽略了输入"意味着它将无效.
您可以按如下方式规避此行为以获取正确的日期:
# create a vector of dates d <- c("2016-50-4","2016-50-5","2016-50-6","2016-50-7", "2016-51-1") # convert to the correct dates as.Date(paste0(substr(d,1,8), as.integer(substring(d,9))-1), "%Y-%U-%w") + 1
这使:
[1] "2016-12-15" "2016-12-16" "2016-12-17" "2016-12-18" "2016-12-19"