Конвертировать номер недели в дату

У меня есть фрейм данных в R с неделей года, которые я хотел бы преобразовать в дату. Я знаю, что должен выбрать год и день недели, поэтому я фиксирую эти значения в 2014 и 1. Преобразование этого в дату кажется простым:

as.Date(paste(2014,df$Week,1,sep=""),"%Y%U%u")

Но этот код работает только если неделя больше 9. Неделя 1 - 9 возвращает NA. Если я изменю неделю на 01,02,03... она все равно вернет NA.

Кто-нибудь видит, чего мне не хватает?

5 ответов

Решение

as.Date вызывает от 1 до 9 как NA, так как он ожидает две цифры для номера недели и не может правильно его проанализировать.

Чтобы исправить это, добавьте немного - чтобы разделить вещи:

as.Date(paste(2014, df$Week, 1, sep="-"), "%Y-%U-%u")

Альтернативное решение - использовать арифметику даты из lubridate пакет:

lubridate::ymd( "2014-01-01" ) + lubridate::weeks( df$Week - 1 )

-1 необходимо, потому что 2014-01-01 уже неделя 1. Другими словами, мы хотим:

  • df$Week == 1 сопоставить с 2014-01-01 (который ymd("2014-01-01") + weeks(1-1))
  • df$Week == 2 сопоставить с 2014-01-08 (который ymd("2014-01-01") + weeks(2-1))
  • и так далее.

Другой вариант с lubridate

lubridate::parse_date_time(paste(2014, df$Week, 'Mon', sep="/"),'Y/W/a')

Другой вариант - убедиться, что номера недель состоят из двух цифр, что можно сделать с помощью stringr::str_pad(), который добавит, чтобы убедиться, что pad="0" цифры:

      year <- 2015
week <- 1
as.Date(paste(year, week, "1", sep=""), "%Y%U%u")
#> [1] NA
as.Date(paste(year, stringr::str_pad(week,width=2, pad="0"), "1", sep=""), "%Y%U%u")
#> [1] "2015-01-05"
as.Date(paste(year, week, "1", sep="-"), "%Y-%U-%u")
#> [1] "2015-01-05"

Создано 2021-04-19 пакетом REPEX (v1.0.0)

It will be like using 2nd year = (week-52), 3rd year  = (week -104)...so on

for(i in 1:456548)
{
  if (train[i,2] > 0 & train[i,2] <53)
  {
    train["weekdate"] <- as.Date(paste(2016, train$week, 1, sep="-"), "%Y-%U-%u")
  }
  if (train[i,2] > 52 & train[i,2] <105)
  {
    train["weekdate"] <- as.Date(paste(2017, (train$week-52), 1, sep="-"), "%Y-%U-%u")
  }
  if (train[i,2] > 104 & train[i,2] <150)
  {
    train["weekdate"] <- as.Date(paste(2018, (train$week-104), 1, sep="-"), "%Y-%U-%u")
  }

}
Другие вопросы по тегам