У меня есть фрейм данных, который выглядит так:
data <- data.frame(PROG_START = c("Tuesday, October 1, 2019", "1682294400"))
> print(data)
PROG_START
1 Tuesday, October 1, 2019
2 1682294400
Как видите, столбец PROG_START содержит даты в двух разных форматах (метка времени UTX и день недели, месяц, день, год). Я хотел бы стандартизировать значения в этом столбце, чтобы формат всех дат был день-месяц-год.
Я просмотрел стек и не добился особых успехов в поиске решения. Я нашел один полезный пост, который побудил меня разработать следующее:
data1 <- data %>%
mutate(Dates = case_when(str_detect(PROG_START, '\\d{10}\\.\\d{3}') ~ PROG_START, TRUE ~ NA_character_ )) %>%
mutate(Dates = as.POSIXct(as.numeric(PROG_START), origin = '1970-01-01', tz = 'UTC')) %>%
mutate(PROG_START = anytime(PROG_START)) %>% mutate(PROG_START = coalesce(PROG_START, Dates)) %>% select(-Dates)
Это успешно преобразовало большую часть временных меток UTX, однако у меньшинства был указан неправильный год. Например, 1682294400 был приписан 1682 году вместо 2023. Это также превратило все другие форматированные даты (например, вторник, 1 октября 2019 года) в NA.
Затем я обновил приведенный выше код до следующего:
data1 <- data %>%
mutate(PROG_START = case_when(
str_detect(PROG_START, '\\d{10}\\.\\d{3}') ~ as.POSIXct(as.numeric(PROG_START), origin = '1970-01-01', tz = 'UTC'),
TRUE ~ dmy(PROG_START)
)) %>%
mutate(PROG_START = format(PROG_START, "%d-%m-%Y"))
Однако это превратило все в NA. Не знаю, как поступить в данный момент. Я ценю помощь! Спасибо!
Недавно мне пришлось сделать что-то подобное: вот решение, которое проверяет значения, которые не являются NA и не содержат запятую, поэтому оно должно влиять только на временные метки UTX.
Поскольку столбец состоит из символов, нам нужно преобразовать значение в целое число, чтобы можно было преобразовать его в дату, и, наконец, в символ.
Определенно есть решение с большей производительностью, но оно работает.
for (i in 1:nrow(data)) {
if (!is.na(data$PROG_START[i]) && !grepl(",", data$PROG_START[i])) {
data$PROG_START[i] <- format(as.POSIXct(as.numeric(data$PROG_START[i]), origin = '1970-01-01', tz = 'UTC'), "%A, %B %d, %Y")
}
}
Обновлено: Изменено содержимое format() в соответствии с вашим примером.
fn <- function(dd){
a <- lubridate::as_datetime(suppressWarnings(as.numeric(dd)))
a[idx] <- lubridate::parse_date_time(dd[idx <- is.na(a)], "ABdY")
a
}
fn(data$PROG_START)
[1] "2019-10-01 UTC" "2023-04-24 UTC"
Спасибо, Мэтт. Ваш ответ в некоторой степени сработал - годы в выводе все еще были немного неправильными. В данном случае решение Оньямбу сработало безупречно. Спасибо за помощь!