53-я неделя года в R?
У меня есть данные с датой в форме 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
Вопрос в том, как мне получить R
, чтобы принимать номера недель в формате ISO 8601?
Примечание. Этот вопрос суммирует проблему, с которой я боролся в течение нескольких часов. Я искал и нашел различные полезные сообщения, такие как этот, но никто не решил проблему.
Ответы
Ответ 1
Пакет ISOweek
управляет нумерациями стилей стиля ISO 8601, преобразуя их в объекты Date
и 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