控制如何打印日期时间对象而不强迫角色?

时间:2014-06-20 23:15:45

标签: r datetime datetime-format

想象一下,我有一个数据框,其中一些列代表日期或时间。使用这些列时,将它们格式化为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")

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

格式(a.datetime,format ="%y-%m")    write.csv(data.frame(格式(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。

2 个答案:

答案 0 :(得分:0)

扩展我的评论的一些代码。 R是一种函数式语言,因此对向量(和列表实际上是向量)的操作不会改变向量,但会返回处理结果,而对于datatime对象,我们通常是字符向量。这是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对象使用起来很棘手,并且数据帧函数通常不能很好地使用它们,因为大多数(表现良好的)数据帧列都是原子向量而不是列表。

答案 1 :(得分:0)

令人讨厌的是,用于写数据的基本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')

这不是应该在较大的代码库中完成的工作,尽管全局效果可能会溢出到不期望的代码中!