【问题标题】:53rd week of the year in R?R 一年中的第 53 周?
【发布时间】:2013-02-02 23:22:57
【问题描述】:

我有yyyy-ww 形式的星期日期数据,其中ww 是两位数的星期数。数据范围 2007-012010-30。周计数约定是 ISO 8601,正如您在此处看到的 on Wikipedia's "Week number" article ,一年中偶尔会达到 53 周。例如,该系统在 2009 年有 53 周,请参阅 this ISO 8601 calendar 中的周数。 (参见其他年份;根据 Wikipedia 文章,第 53 周相当罕见。)

基本上我想读取周日期,将其转换为Date 对象并将其保存到data.frame 中的单独列中。作为测试,我通过format([Date-object], format = "%Y-%W"Date 对象重新转换为yyyy-ww 格式,这在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     

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

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

【问题讨论】:

  • as.Date(x ="2009-01 01", format = "%Y-%W %w")ISOweek2date("2009-W01-1") 进行比较可能更能说明问题,您还应该在help(strptime) 中引用%W 的条目。
  • 不确定,但我记得很多 R 的日期处理实际上是由系统库处理的,这意味着这类问题 (a) 会因操作系统而异; (b) 在 Windows 上可能特别狡猾; (c) 在 R 本身中很难修复(如下面的答案所示;ISOweek 实现了自己的算法,因为 Windows 的系统库中缺少东西)
  • @BenBolker 该行为在help(strptime)中定义。
  • 是的,ISOweek 依赖于%V,这在 Windows 中没有实现。所以这确实是一个 Windows 问题。正如strptime 帮助中所写。

标签: r date dayofweek


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2021-10-31
    • 2023-03-29
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多