Преобразуйте числовые даты Excel в R дат, но в некоторых строках указывается только год, например, «2018» вместо «43465» - PullRequest
0 голосов
/ 06 ноября 2019

Я читаю в файле Excel с одним столбцом, содержащим даты. В некоторых строках нет полных дат, но указывается только год, например, 2018. То, что я получаю в R, это

> df$date
[1]    NA    NA 43465 43465 43465 43465  2018    NA 43465 43465 43465 43465

Я хочу преобразовать эти строки в формат даты, который является полной датой,т.е. в моем примере только строки с 43465 и оставляют другие строки, как они есть, то есть NA должны оставаться NA и 2018 должны оставаться 2018.

Я знаю, что могуконвертируйте даты Excel следующим образом as.Date(df$date, origin="1899-12-30"), но следующие две идеи дают мне неправильный вывод

> as.Date(df$date, origin="1899-12-30")
[1] NA NA  "2018-12-31" "2018-12-31" "2018-12-31" "2018-12-31" "1905-07-10" NA "2018-12-31" "2018-12-31" "2018-12-31"
[12] "2018-12-31"

Конечно, "1905-07-10" не то, что я ожидал.

> ifelse(df$date == 2018, 2018, as.Date(df$date, origin="1899-12-30"))
[1]    NA    NA 17896 17896 17896 17896  2018    NA 17896 17896 17896 17896

Здесь неправильныйвывод очевиден.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

Опираясь на ответ @ Ronak, вы можете использовать регулярное выражение для определения четырехзначного числового числа, а затем дополнить его четырьмя завершающими нулями.

x <- c(NA,NA,43465,43465,43465,43465,2018,NA,43465,43465, 43465, 43465)
ifelse(grepl('^\\d{4}$', x, perl = TRUE), 
   as.integer(paste0(x, '0000')), 
   as.integer(format(as.Date(x, origin='1899-12-30'), '%Y%m%d')))
[1]  NA       NA 20181231 20181231 20181231 20181231 20180000       NA 20181231 20181231 20181231 20181231

Вы получите несколько предупреждающих сообщений, касающихся NAs, и если это вас беспокоит, вы можете добавить дополнительные ifelse для управления NA. Здесь мы используем логический тест grep, чтобы увидеть, есть ли только четыре числа (год), затем мы создаем целое число значений. Это позволяет вам по-прежнему использовать математические операторы, такие как >, <, == и т. Д., И сохранять всю информацию.

Вы можете изменить '0000' во время вызова paste0() наболее подходящий номер на основе данных или варианта использования.

0 голосов
/ 06 ноября 2019

Вектор не может иметь несколько классов. Вы можете иметь числовой или класс Date в них. Обходной путь - использовать класс символов, который является наиболее общим.

x <- c(NA,NA,43465,43465,43465,43465,2018,NA,43465,43465, 43465, 43465)
ifelse(x == 2018, "2018", as.character(as.Date(x, origin="1899-12-30")))

# [1] NA  NA   "2018-12-31" "2018-12-31" "2018-12-31" "2018-12-31" "2018"      
# [8] NA   "2018-12-31" "2018-12-31" "2018-12-31" "2018-12-31"

Однако список может иметь несколько классов, поэтому, если вы можете хранить данные в списке, мы можем использовать lapply

lapply(x, function(y) 
     if (y == 2018 | is.na(y)) y else as.Date(y, origin="1899-12-30"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...