melt.data.frame()更改POSIXct列的打印方式

Tob*_*ias 7 r posixct reshape2

将数据帧融合到整个范围会更改"时间"(类POSIXct)列的打印方式.

t.wide <- data.frame(product=letters[1:5], 
                     result=c(2, 4, 0, 0, 1), 
                     t1=as.POSIXct("2014-05-26") + seq(0, 10800, length.out=5),
                     t2=as.POSIXct("2014-05-27") + seq(0, 10800, length.out=5),
                     t3=as.POSIXct("2014-05-28") + seq(0, 10800, length.out=5))

library(reshape2)     
t.long <- melt(t.wide, measure.vars=c("t1", "t2", "t3"), value.name="time")
t.long$time
 [1] 1401055200 1401057900 1401060600 1401063300 1401066000 1401141600 1401144300
 [8] 1401147000 1401149700 1401152400 1401228000 1401230700 1401233400 1401236100
[15] 1401238800
attr(,"class")
[1] "POSIXct" "POSIXt" 
Run Code Online (Sandbox Code Playgroud)

奇怪的是,如果print()显式调用,则按预期打印对象(时间戳,而不是它们的数字表示).

print(t.long$time)
 [1] "2014-05-26 00:00:00 CEST" "2014-05-26 00:45:00 CEST" "2014-05-26 01:30:00 CEST"
 [4] "2014-05-26 02:15:00 CEST" "2014-05-26 03:00:00 CEST" "2014-05-27 00:00:00 CEST"
 [7] "2014-05-27 00:45:00 CEST" "2014-05-27 01:30:00 CEST" "2014-05-27 02:15:00 CEST"
[10] "2014-05-27 03:00:00 CEST" "2014-05-28 00:00:00 CEST" "2014-05-28 00:45:00 CEST"
[13] "2014-05-28 01:30:00 CEST" "2014-05-28 02:15:00 CEST" "2014-05-28 03:00:00 CEST"
Run Code Online (Sandbox Code Playgroud)

将属性设置为与之前相同的值会神奇地更改对象的打印方式.

attributes(t.long$time) <- attributes(t.long$time)
t.long$time
 [1] "2014-05-26 00:00:00 CEST" "2014-05-26 00:45:00 CEST" "2014-05-26 01:30:00 CEST"
 [4] "2014-05-26 02:15:00 CEST" "2014-05-26 03:00:00 CEST" "2014-05-27 00:00:00 CEST"
 [7] "2014-05-27 00:45:00 CEST" "2014-05-27 01:30:00 CEST" "2014-05-27 02:15:00 CEST"
[10] "2014-05-27 03:00:00 CEST" "2014-05-28 00:00:00 CEST" "2014-05-28 00:45:00 CEST"
[13] "2014-05-28 01:30:00 CEST" "2014-05-28 02:15:00 CEST" "2014-05-28 03:00:00 CEST"
Run Code Online (Sandbox Code Playgroud)

谁能解释这种行为?

Sim*_*lon 6

更新:

我在git repo hadley/reshape2上打开了这个问题#50.


更新:固定

此问题已在开发版本中得到修复. reshape2

谢谢@kevin-ushey!


我相信原因是因为无论出于什么原因重塑后R都不认为t.long$time有属性.由于某种原因,未设置向量的SEXP标头中的OBJECT标志(表示向量具有属性).将属性复制回它时,OBJECT标志被设置并调度正确的打印方法...

# No "OBJ" in SEXP header (the '[NAM(2),ATT]' part below)
 .Internal(inspect( t.long$time ) )
#@10359e548 14 REALSXP g0c6 [NAM(2),ATT] (len=15, tl=0) 1.40106e+09,...

# Now we have "OBJ" in the SEXP header indicating attributes
# So the print method for POSIXct get dispatched...
attributes(t.long$time) <- attributes(t.long$time)
 .Internal(inspect( t.long$time ) )
#@1118d7f50 14 REALSXP g0c6 [OBJ,NAM(2),ATT] (len=15, tl=0) 1.40106e+09,...
Run Code Online (Sandbox Code Playgroud)

来自R Internals文件......

实际的PrintValueEnv自动打印由文件print.c完成.如果要打印的对象设置了S4位并且打开了S4方法,则调用show来打印对象.否则,如果设置了对象位(因此对象具有"class"属性),则调用print来调度方法:对于没有类的对象,调用print.default的内部代码.

检查之间的区别..

print.default(t.long$time)
# [1] 1401058800 1401061500 1401064200 1401066900 1401069600 1401145200 1401147900 1401150600 1401153300 1401156000 1401231600 1401234300
#[13] 1401237000 1401239700 1401242400
#attr(,"class")
#[1] "POSIXct" "POSIXt" 
print.POSIXct(t.long$time)
# [1] "2014-05-26 00:00:00 BST" "2014-05-26 00:45:00 BST" "2014-05-26 01:30:00 BST" "2014-05-26 02:15:00 BST" "2014-05-26 03:00:00 BST"
# [6] "2014-05-27 00:00:00 BST" "2014-05-27 00:45:00 BST" "2014-05-27 01:30:00 BST" "2014-05-27 02:15:00 BST" "2014-05-27 03:00:00 BST"
#[11] "2014-05-28 00:00:00 BST" "2014-05-28 00:45:00 BST" "2014-05-28 01:30:00 BST" "2014-05-28 02:15:00 BST" "2014-05-28 03:00:00 BST"
Run Code Online (Sandbox Code Playgroud)

现在我只能推测,但也许这是由于一些内部代码reshape2并且与此警告有关.

需要注意的一件事是,如果将属性从一个对象复制到另一个对象,则可以(取消)设置"class"属性,因此也需要复制对象和S4位.有一个宏/函数DUPLICATE_ATTRIB可以自动执行此操作.