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

时间:2014-06-05 11:50:03

标签: r reshape2 posixct

将数据框融化为t.wide会更改列" time" (类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" 

奇怪的是,如果显式调用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"

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

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"

任何人都可以解释这种行为吗?

1 个答案:

答案 0 :(得分:6)

更新

我在git repo Issue #50上将其打开为hadley/reshape2


更新:已修复

此问题在reshape2的{​​{3}} fixed development version

谢谢 @ 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,...

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

  

实际的自动打印由文件print.c中的PrintValueEnv完成。如果要打印的对象设置了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"

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

  

要注意的一件事是,如果您将属性从一个对象复制到另一个对象,您可以(联合国)设置&#34;类&#34;属性等也需要复制对象和S4位。有一个宏/函数DUPLICATE_ATTRIB可以自动执行此操作。