Преобразовать год / неделю в дату объекта
Строка содержит "YEAR WEEK", и я хочу преобразовать ее с parse_date_time()
к объекту даты, но я не могу заставить код работать:
parse_date_time(c("201510"), "YW")
Мне не нужно использовать lubridate, могут быть и другие пакеты.
1 ответ
Перед преобразованием год-неделя в дату вы должны указать день недели, но, что более важно, вы должны убедиться, какое из этих соглашений используется.
База R strptime()
Функция знает 3 определения для недели года (но поддерживает только 2 из них на входе) и 2 определения для номеров дня недели, см. ?strptime
:
Неделя года
Соглашение США: неделя года в виде десятичного числа (00–53) с использованием воскресенья в качестве первого дня 1 недели (и обычно с первым воскресением года в качестве дня 1 недели 1):
%U
Соглашение в Великобритании: неделя года в виде десятичного числа (00–53) с использованием понедельника в качестве первого дня недели (и обычно с первым понедельником года в качестве дня 1 недели 1):
%W
Определение ISO 8601: неделя года в виде десятичного числа (01–53), как определено в ISO 8601. Если неделя (начиная с понедельника), содержащая 1 января, имеет четыре или более дней в новом году, то она считается неделей 1. В противном случае это последняя неделя предыдущего года, а следующая неделя - неделя 1:
%V
который принят, но проигнорирован на входе.
Обратите внимание, что существует также недельный год (%G
а также%g
) который должен использоваться с%V
как это может отличаться от календарного года (%Y
а также%y
).
Числовой день недели
- День недели в виде десятичного числа (1–7, понедельник - 1):
%u
- День недели в виде десятичного числа (0–6, воскресенье - 0):
%w
- Интересно, что для случая нет формата воскресенье считается днем 1 недели.
Преобразование года-недели-дня с различными соглашениями
Если мы добавим день 1 к строке и используем разные форматы, мы получим
as.Date("2015101", "%Y%U%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%U%w")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%u")
# [1] "2015-03-09"
as.Date("2015101", "%Y%W%w")
# [1] "2015-03-09"
as.Date("2015101", "%G%V%u")
# [1] NA
Для форматов будних дней %u
а также %w
мы получаем тот же результат, потому что 1-й день - понедельник в обеих конвенциях (но будьте осторожны при работе с воскресеньями).
Для 2015 года определение США и Великобритании для недели года совпадает, но это не верно для всех лет, например, не для 2001, 2007 и 2018 годов:
as.Date("2018101", "%Y%U%u")
#[1] "2018-03-12"
as.Date("2018101", "%Y%W%u")
#[1] "2018-03-05"
Спецификаторы формата ISO 8601 не поддерживаются при вводе. Поэтому я создал ISOweek
пакет несколько лет назад:
ISOweek::ISOweek2date("2015-W10-1")
#[1] "2015-03-02"
Изменить: Использование четверга, чтобы связать неделю с месяцем
Как уже упоминалось выше, вам нужно указать день недели, чтобы получить полную календарную дату. Это также требуется, если даты должны быть агрегированы по месяцам позже.
Если день недели не указан и если предполагается, что даты будут агрегированы по месяцам позже, вы можете взять четверг каждой недели в качестве контрольного дня (по предложению djhurio). Это гарантирует, что вся неделя назначается месяцу, к которому относится большинство дней недели.
Например, если взять воскресенье в качестве исходного дня
ISOweek::ISOweek2date("2015-W09-7")
[1] "2015-03-01"
что, следовательно, связывает всю неделю с месяцем марта, хотя только один день недели относится к марту, а остальные 6 дней относятся к февралю. Принимая четверг в качестве справочного дня, вернем дату в феврале:
ISOweek::ISOweek2date("2015-W09-4")
[1] "2015-02-26"
Да, пакет ISOweek делает это
ISOweek::ISOweek2date(isoWeek)
но по другому направлению проверь новее lubridate
пакет также
ISOweek::date2ISOweek(yourDate)
lubridate::isoweek(ymd(yourDate))