我有周数据,表格yyyy-ww中ww的周数是两位数.数据跨越2007-01到2010-30.周计数会议是ISO 8601,正如您在维基百科的"周数"文章中所看到的,偶尔会在一年内达到53周.例如,2009年该系统有53周,请参阅此ISO 8601日历中的周数.(见其他年份;根据维基百科的文章,第53周相当罕见.)
基本上我想阅读周日期,将其转换为Date对象并将其保存到一个单独的列中data.frame.作为测试,我将Date对象重新转换为yyyy-ww格式format([Date-object], format = "%Y-%W",并在此处抛出错误2009-53.那个星期没有被解释为日期R.这是非常奇怪的,因为没有第53周(在ISO 8601标准中)的2007-53其他年份被转换为罚款,例如,而其他年份也没有第53周(在ISO 8601标准中)也失败,例如2008-53
以下最小示例演示了该问题.
最小的例子:
dates <- c("2009-50", "2009-51", "2009-52", "2009-53", "2010-01", "2010-02")
as.Date(x = paste(dates, 1), format = "%Y-%W %w")
# [1] "2009-12-14" "2009-12-21" "2009-12-28" NA "2010-01-04"
# [6] "2010-01-11"
other.dates <- c("2007-53", "2008-53", "2009-53", "2010-53")
as.Date(x = paste(other.dates, 1), format = "%Y-%W %w")
# [1] "2007-12-31" NA NA NA
Run Code Online (Sandbox Code Playgroud)
问题是,我如何R接受ISO 8601格式的周数?
注意:这个问题总结了我几个小时以来一直在努力解决的问题.我搜索并找到了各种有用的帖子,比如这个,但都没有解决问题.
dyn*_*amo 11
该软件包ISOweek管理ISO 8601样式周编号,转换为和来自Date对象R.了解ISOweek更多.继续上面的示例日期,我们首先需要稍微修改格式.它们必须是形式yyyy-Www-w而不是yyyy-ww,即2009-W53-1.最后一位数字标识用于识别周的星期几,在这种情况下,它是星期一.周数必须是两位数.
library(ISOweek)
dates <- c("2009-50", "2009-51", "2009-52", "2009-53", "2010-01", "2010-02")
other.dates <- c("2007-53", "2008-53", "2009-53", "2010-53")
dates <- sub("(\\d{4}-)(\\d{2})", "\\1W\\2-1", dates)
other.dates <- sub("(\\d{4}-)(\\d{2})", "\\1W\\2-1", other.dates)
## Check:
dates
# [1] "2009-W50-1" "2009-W51-1" "2009-W52-1" "2009-W53-1" "2010-W01-1"
# [6] "2010-W02-1"
(iso.date <- ISOweek2date(dates)) # deal correctly
# [1] "2009-12-07" "2009-12-14" "2009-12-21" "2009-12-28" "2010-01-04"
# [6] "2010-01-11"
(iso.other.date <- ISOweek2date(other.dates)) # also deals with this
# [1] "2007-12-31" "2008-12-29" "2009-12-28" "2011-01-03"
## Check that back-conversion works:
all(date2ISOweek(iso.date) == dates)
# [1] TRUE
## This does not work for the others, since the 53rd week of
## e.g. 2008 is back-converted to the first week of 2009, in
## line with the ISO 6801 standard.
date2ISOweek(iso.other.date) == other.dates
# [1] FALSE FALSE TRUE FALSE
Run Code Online (Sandbox Code Playgroud)