首页 文章

R一年中的第53周?

提问于
浏览
12

我有 yyyy-ww 形式的周日期数据,其中 ww 是两位数的周数 . 数据范围为 2007-012010-30 . 周计数 Session 是ISO 8601,你可以在这里看到on Wikipedia's "Week number" article,偶尔会在一年内达到53周 . 例如,2009年该系统有53周,请参阅this ISO 8601 calendar中的周数 . (见其他年份;根据维基百科的文章,第53周相当罕见 . )

基本上我想阅读周日期,将其转换为 Date 对象并将其保存到 data.frame 中的单独列 . 作为测试,我通过 format([Date-object], format = "%Y-%W"Date 对象重新转换为 yyyy-ww 格式,这在 2009-53 处引发了错误 . 该周未被 R 解释为日期 . 这是非常奇怪的,因为没有第53周(在ISO 8601标准中)的其他年份被转换为罚款,例如 2007-53 ,而其他年份也没有第53周(在ISO 8601标准中)也会失败,例如as 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格式的周数?

注意:这个问题总结了我几个小时以来一直在努力解决的问题 . 我搜索并找到各种有用的帖子,如this,但没有一个解决了问题 .

1 回答

  • 10

    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
    

相关问题