想象一下,我有一个数据框,其中某些列代表日期或时间。使用这些列时,将它们格式化为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
方法在使用后消失。)
本质上是为as.character
类重写POSIXct
方法(出于不可思议的原因,对父类POSIXt
类的重写将不起作用:]]
as.character.POSIXct <- function(x) format(x, format='%Y-%m-%d %H:%M:%S%z')
这不是应该在较大的代码库中进行的操作,在较大的代码库中,全局效果可能会溢出到不期望的代码中!