R中的第53周是什么意思?

14

我有一些以yyyy-ww的形式表示的周日期数据,其中ww是两位数的周数。这些数据跨越了2007-012010-30。周计数约定是ISO 8601,你可以在维基百科的“周数”文章中看到,有时一年会有53个星期。例如,按照这个系统,2009年有53个星期,请参见此ISO 8601日历中的周数。 (查看其他年份;根据维基百科文章,第53周非常罕见。)

基本上,我想读入周日期,将其转换为Date对象,并将其保存到data.frame的单独列中。作为测试,我通过format([Date-object], format ="%Y-%W"Date对象重新转换为yyyy-ww格式,但在 2009-53处出现错误。该周无法被R解释为日期。这非常奇怪,因为其他年份(ISO 8601标准中没有第53周)可以正常转换,如2007-53,而其他也没有第53周的年份则无法转换,例如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     

问题是,我如何让R接受ISO 8601格式的周数?

注意:这个问题总结了我几个小时来一直苦苦挣扎的问题。我已经搜索并找到了各种有用的帖子,例如这个,但都没有解决问题。


1
еҸҜиғҪжӣҙе…·иҜҙжҳҺжҖ§зҡ„жҳҜе°Ҷas.Date(x ="2009-01 01", format = "%Y-%W %w")дёҺISOweek2date("2009-W01-1")иҝӣиЎҢжҜ”иҫғпјҢдҪ иҝҳеә”иҜҘеј•з”Ёhelp(strptime)дёӯе…ідәҺ%Wзҡ„жқЎзӣ®гҖӮ - Roland
我不确定,但我记得很多R的日期处理实际上是由系统库处理的,这意味着这种问题(a)会因操作系统而异;(b)在Windows上可能特别棘手;(c)在R本身中难以修复(如下面的答案所示;ISOweek实现了自己的算法,因为Windows的系统库中缺少一些东西)。 - Ben Bolker
@BenBolker 这个行为在 help(strptime) 中有定义。 - Roland
1
是的,ISOweek 依赖于 %V,而这在 Windows 中并未实现。因此,这确实是一个 Windows 的问题。正如在 strptime 帮助文件中所写的那样。 - dynamo
1个回答

15

ISOweek管理 ISO 8601 格式的周数,可在R中将其转换为Date对象并进行相互转换。有关详细信息,请参见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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接