Дата реструктуризации в R - PullRequest
       1

Дата реструктуризации в R

2 голосов
/ 17 февраля 2020

У меня есть такой набор данных:

 CODE    NAME    DATE      HOUR
  1       Ab    01-01-19     1
  1       Ab    02-01-19     2
  1       Ab    03-01-19     3
  1       Ab    04-01-19     4
  2       Xy    01-JAN-19    1
  2       Xy    02-JAN-19    2
  2       Xy    03-JAN-19    3
  2       Xy    04-JAN-19    4

Фактический набор данных намного больше. Я хочу конвертировать все ДАТЫ в формате 01-ЯНВ-19. Я пробовал с:

a <- as.Date(df$DATE, format = "%d-%b-%y")
b <- as.Date(df$DATE, format = "%d-%m-%y")
a[is.na(a)] <- b[!is.na(b)]
df$ <- a

Но это требует времени и дает результат в формате 2019-01-01. Даже я пытался с:

df$DATE <- format(as.Date(df$DATE, format = c("%d-%b-%y", "%d-%m-%y")), "%d-%b-%y") 

Это дает желаемый результат, но он заполняет альтернативные значения NA в столбце DATE, например:

 CODE    NAME    DATE      HOUR
  1       Ab    01-JAN-19    1
  1       Ab    NA           2
  1       Ab    03-JAN-19    3
  1       Ab    NA           4
  2       Xy    NA           1
  2       Xy    02-JAN-19    2
  2       Xy    NA           3
  2       Xy    04-JAN-19    4

Я думаю, это из-за format = c("%d-%b-%y", "%d-%m-%y"). Как я могу преобразовать все ДАТЫ в формат 01-ЯНВ-19.

Ответы [ 4 ]

2 голосов
/ 17 февраля 2020

Как насчет:

df$DATE = format(lubridate::parse_date_time(df$DATE, c('dmy','dby')), '%d-%b-%Y')
1 голос
/ 17 февраля 2020

1) Используя входные данные, воспроизводимые в конце примечания, в toDate используйте аргумент tryFormats as.Date. as.Date предполагает, что все записи имеют одинаковый формат, поэтому lapply поверх ввода, чтобы применить его индивидуально к каждому элементу, а затем объединить полученный список обратно в вектор Date. Теперь используйте toDate для преобразования DATE в Date класс, затем отформатируйте его и преобразуйте в верхний регистр. Пакеты не используются.

toDate <- function(x, formats = c("%d-%m-%y", "%d-%b-%y")) {
  do.call("c", lapply(x, as.Date, tryFormats = formats))
}

transform(df, DATE = toupper(format(toDate(DATE), "%d-%b-%Y")))

2) Другой подход заключается в простом преобразовании тех записей, которые еще не в желаемом формате. Опять же, пакеты не используются.

ok <- grepl("[A-Z]", df$DATE)
transform(df, DATE = 
  replace(DATE, !ok, toupper(format(as.Date(DATE[!ok], "%d-%m-%y"), "%d-%b-%y")))

Примечание

Lines <- "CODE    NAME    DATE      HOUR
  1       Ab    01-01-19     1
  1       Ab    02-01-19     2
  1       Ab    03-01-19     3
  1       Ab    04-01-19     4
  2       Xy    01-JAN-19    1
  2       Xy    02-JAN-19    2
  2       Xy    03-JAN-19    3
  2       Xy    04-JAN-19    4"
df <- read.table(text = Lines, header = TRUE, as.is = TRUE)
0 голосов
/ 17 февраля 2020

Вы можете попробовать следующий базовый код R

df$DATE<- as.Date(z <- gsub("[A-Z]\\K([A-Z]+)","\\L\\1",df$DATE),
                  format = ifelse(grepl("[[:alpha:]]",z),"%d-%b-%y","%d-%m-%y"))

, такой что

> df
  CODE NAME       DATE HOUR
1    1   Ab 2019-01-01    1
2    1   Ab 2019-01-02    2
3    1   Ab 2019-01-03    3
4    1   Ab 2019-01-04    4
5    2   Xy 2019-01-01    1
6    2   Xy 2019-01-02    2
7    2   Xy 2019-01-03    3
8    2   Xy 2019-01-04    4
0 голосов
/ 17 февраля 2020

Привет, я бы попробовал что-то вроде этого

df$DATE = format(as.Date(df$DATE, format = ifelse(grepl(paste0(letters[1:26],collapse = '|'), df$DATE, ignore.case = TRUE), "%d-%b-%y", "%d-%m-%y")), format = "%d-%b-%y") 

Надеюсь, это поможет

Тест

# ifelse
format(as.Date(df$DATE, format = ifelse(grepl(paste0(letters[1:26],collapse = '|'), df$DATE, ignore.case = TRUE), "%d-%b-%y", "%d-%m-%y")), format = "%d-%b-%Y") 
[1] "01-Jan-2019" "02-Jan-2019" "03-Jan-2019" "04-Jan-2019" "01-Jan-2019"
[6] "02-Jan-2019" "03-Jan-2019" "04-Jan-2019"

# lubridate
format(lubridate::parse_date_time(df$DATE, c('dmy','dby')), '%d-%b-%Y')
[1] "01-Jan-2019" "02-Jan-2019" "03-Jan-2019" "04-Jan-2019" "01-Jan-2019"
[6] "02-Jan-2019" "03-Jan-2019" "04-Jan-2019"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...