Измените формат POSIXct с ГГГГ-ММ-ДД на ММ-ДД-ГГГГ в R

#r #date #posixct

Вопрос:

Новый пользователь R здесь. Я импортирую xlxs с помощью функции read_xlsx. Две колонки я прочитал как дату, остальные как текст или цифры. После этого я не могу преобразовать столбец «EDD» из ГГГГ-ММ-ДД в ММ-ДД-ГГГГ. Str показывает POSIXct.

 MICAP <- read_xlsx("~/Copy of Joint MICAP Report 0700 CDT (004).xlsx", 
sheet = "OPEN ORDERS for MICAP Reporting", col_names = TRUE, , 
col_types = c("text", "text", "text", "text", "text", "text", 
"text", "text", "text", "text", "date", "numeric", "text", 
"date", "text", "text", "text", "text", "text"))
 

Когда я вызываю str(MICAP), моя колонка EDD (дата) отображается как POSIXct, но я не могу ее изменить.

Меня интересует только изменение EDD на ММ/ДД/ГГГГ

Комментарии:

1. POSIXt -переменные класса отображаются одним способом в R, и это с YYYY-MM-DD (и обычно, но не всегда HH:MM:SS с/без десятичных секунд на основе options("digits.secs") ). Если вы хотите, чтобы он отображался по-другому, вы можете либо (1) преобразовать его в строку с помощью format(vec, format="%m-%s-%Y") ; либо (2) сделать его супер-классом и использовать метод S3 R dispatch, чтобы изменить способ его отображения на консоли, и надеяться, что вы найдете все методы, необходимые для удовлетворения всех ваших потребностей.

2. @r2evans, опубликуйте в качестве ответа?

3. @JLGRIECO, еще одна мысль: изменение его на строку может быть проблематичным, если вы когда-либо захотите сделать с ним что-то похожее на числа ( diff , range , order / arrange и т. Д.), И слишком часто обоснование для этого заключается в том, как оно отображается в окончательном отчете/таблице. Если это так, то format ваш ответ, основанный на % строках -, найденных в ?strptime . Однако, если вы действительно хотите, чтобы это отображалось только на вашей консоли, я предлагаю либо (1) принять значение R по умолчанию и проработать это различие, либо (2) вам нужно будет достаточно освоиться с S3, чтобы понять, что я подразумеваю под «супер-классом».

Ответ №1:

Вот что я имею в виду, называя это супер-классом:

 format.myPOSIX <- function(x, tz = "", usetz = FALSE, ...) {
  dots <- list(...)
  fmt <- NA
  if ("format" %in% names(dots)) {
    fmt <- dots$format
    dots$format <- NULL
  }
  if (inherits(x, "Date")) {
    if (is.na(fmt)) fmt <- "%m/%d/%Y"
    func <- match.fun("format.Date")
  } else { # POSIXt
    if (is.na(fmt)) fmt <- "%m/%d/%Y %H:%M:%S"
    func <- match.fun("format.POSIXct")
  }
  do.call(func, c(list(x, tz = tz, usetz = usetz), format = fmt, dots))
}
print.myPOSIX <- function(x, tz = "", usetz = FALSE, ...) {
  print(format.myPOSIX(x, tz = tz, usetz = usetz))
}
 

Например, поскольку ваши данные недоступны.

 set.seed(42)

datevec <- sort(Sys.Date()   sample(20, size=3))
class(datevec) <- c("myPOSIX", class(datevec))
datevec
# [1] "10/23/2021" "10/27/2021" "11/08/2021"
diff(datevec)
# Time differences in days
# [1]  4 12

psxvec <- sort(Sys.time()   sample(2000, size=3))
class(psxvec) <- c("myPOSIX", class(psxvec))
psxvec
# [1] "10/22/2021 09:55:28" "10/22/2021 09:56:47" "10/22/2021 09:58:02"
diff(psxvec)
# Time differences in mins
# [1] 1.316667 1.250000
 

показывая, что печатный формат все "%m/%d/%Y" еще является числовым, операции все еще функционируют.

Это также должно работать в data.frame аналогичных структурах:

 data.frame(dt = datevec, psx = psxvec)
#           dt                 psx
# 1 10/23/2021 10/22/2021 09:58:02
# 2 10/27/2021 10/22/2021 09:59:21
# 3 11/08/2021 10/22/2021 10:00:36
tibble::tibble(dt = datevec, psx = psxvec)
# # A tibble: 3 x 2
#   dt         psx                
#   <date>     <dttm>             
# 1 2021-10-23 2021-10-22 09:58:02
# 2 2021-10-27 2021-10-22 09:59:21
# 3 2021-11-08 2021-10-22 10:00:36
data.table::data.table(dt = datevec, psx = psxvec)
#            dt                 psx
#     <myPOSIX>           <myPOSIX>
# 1: 10/23/2021 10/22/2021 09:58:02
# 2: 10/27/2021 10/22/2021 09:59:21
# 3: 11/08/2021 10/22/2021 10:00:36