繁体   English   中英

控制如何打印日期时间对象而不强制转换为字符?

[英]Controlling how a date-time object is printed without coercing to a character?

想象一下,我有一个数据框,其中一些列代表日期或时间。 使用这些列时,将它们格式化为POSIXlt对象(或其他明确的面向日期/时间的类)会很方便。

但是,当我在屏幕上显示这些列或将它们打印为 .csv 时,我得到了完整的 ISO8601 格式时间。 我意识到我可以将时间转换为格式化的字符向量,但我希望使用format(col, format="%m-%Y")或我想到的任何内容,但我并不热衷于更改对象的类只是为了打印。 R 中的其他对象具有与之关联的打印方法,我们不必显式强制它们。 有没有办法用我忽略的任何 R 对象的日期时间类来做到这一点?

编辑:

这是我希望实现的最小示例:

a.datetime = Sys.time()
a.datetime

显示:

2014-06-23 09:32:12

这是我在 CSV 中得到的格式

write.csv(data.frame(a.datetime), "example.csv")

正如我上面所描述的,我意识到我可以手动将其强制为具有所需格式的字符,例如:

format(a.datetime, format="%y-%m") write.csv(data.frame(format(a.datetime, format="%y-%m")), "example.csv")

这不是我想做的事情; 我正在寻找一种方法,让对象知道应该如何打印它,而用户不必同时应用该格式并将其强制应用于字符向量,如上所示。 (希望这可以通过更改类型来阐明我的意思,我指的是输出的类,而不是参数的类)。

我可以尝试定义如下这样的类,例如使用 S3 类,但它仍然不会使用指定的格式打印到 csv。

class(a.datetime) <- c("myclass", class(a.datetime))
attr(a.datetime, 'fmt') <- "%y-%m"
print.myclass <- function(x) print(format(x, format=attr(x,"fmt")))
print.csv(data.frame(a.datetime), "temp.csv")

仍然以完整的 ISO 8601 格式打印 csv。

一些代码来扩展我的评论。 R 是一种函数式语言,因此对向量(列表实际上是向量)的操作不会改变向量,但会返回一个处理过的结果,在数据时间对象的情况下,我们通常是一个字符向量。 以下是 POSIXlt 对象的一些视图:

x <- as.POSIXlt("2000-01-01")
x
#[1] "2000-01-01 PST"
x <- as.POSIXlt("2000-01-01 12:00:00")
x
#[1] "2000-01-01 12:00:00 PST"
 str(x)
# POSIXlt[1:1], format: "2000-01-01 12:00:00"
 mode(x)
#[1] "list"
 x[[1]]
#[1] 0
 x[[2]]
#[1] 0
 x[[3]]
#[1] 12
 x[[4]]
#[1] 1


 unlist(x)
#   sec    min   hour   mday    mon   year   wday   yday  isdst   zone gmtoff 
#   "0"    "0"   "12"    "1"    "0"  "100"    "6"    "0"    "0"  "PST"     NA 
 mode(x[[3]])
#[1] "numeric"
# x[[10]]; mode(x[[10]])
#[1] "PST"
#[1] "character"

请注意, unlist()进程将列表转换为字符向量。 在 R 中,只有列表可以具有混合模式,因此POSIXlt对象中的单个字符元素最终会将所有作为数值存储的元素强制转换为字符元素。 如上所述,POSIXlt 对象使用起来很棘手,并且数据帧函数通常与它们一起运行不佳,因为大多数(行为良好的)数据帧列是原子向量而不是列表。

非常烦人的是,用于写入数据的基本 R 函数没有参数让用户轻松调整日期时间格式。

不过,有一些方法可以解决。 当我想快速指定格式并且不需要担心副作用时,有时我会这样做:

# In bash
Rscript -e "x <- readRDS('foo.rds'); "\
        -e "as.character.POSIXct <- function(x) format(x, format='%Y-%m-%d %H:%M:%S%z'); " \
        -e "write.csv(x, 'foo.csv', row.names=FALSE)"

(我在 shell 命令中显示它只是为了强调您希望新的as.character.POSIXct方法在使用后消失。)

本质是覆盖POSIXct类的as.character方法(出于神秘的原因,覆盖父POSIXt类将不起作用):

as.character.POSIXct <- function(x)
  format(x, format='%Y-%m-%d %H:%M:%S%z')

但是,这不是应该在更大的代码库中完成的事情,因为全局影响可能会溢出到意想不到的代码中!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM