#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