14

は 2 桁の週番号の形式yyyy-wwで週の日付データを持っています。までwwのデータ範囲。週数の規則は ISO 8601 であり、ウィキペディアの「週数」の記事でわかるように、1 年間で 53 週に達することもあります。たとえば、このシステムでは 2009 年は 53 週でした。この ISO 8601 カレンダーの週番号を参照してください。(他の年を参照してください。Wikipedia の記事によると、53 週目はかなりまれです。)2007-012010-30

基本的に、週の日付を読み込んでDateオブジェクトに変換し、これを別の列に保存したいdata.frame. テストとして、Dateオブジェクトを でyyyy-wwフォーマットに再変換しformat([Date-object], format = "%Y-%W"たところ、 でエラーが発生しました2009-53。その週は によって日付として解釈されませんR。(ISO 8601 標準で) 第 53 週を持たない他の年は のように正常に変換されますが、同様に (ISO 8601 標準で) 第 53 週を持たない2007-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 形式で週番号を受け入れるにはどうすればよいかということです。

注: この質問は、私が数時間苦労してきた問題を要約したものです。このようなさまざまな役立つ投稿を検索して見つけましたが、問題を解決するものはありませんでした。

4

1 に答える 1

14

このパッケージISOweekは、ISO 8601 スタイルの週番号を管理し、 のDateオブジェクトとの間で変換しますR。詳細については、を参照ISOweekしてください。上記の日付の例を続けると、最初にフォーマットを少し変更する必要があります。それらはyyyy-Www-wではなく形式yyyy-wwでなければなりません2009-W53-1。最後の桁は、週の識別に使用する曜日を識別します。この場合は月曜日です。週番号は 2 桁である必要があります。

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
于 2013-02-18T13:47:09.930 に答える