3

I'm trying to melt a data frame with chron class

library(chron)
x = data.frame(Index = as.chron(c(15657.00,15657.17)), Var1 = c(1,2), Var2 = c(9,8))
x
                Index Var1 Var2
1 (11/13/12 00:00:00)    1    9
2 (11/13/12 04:04:48)    2    8

y = melt(x,id.vars="Index")
Error in data.frame(ids, variable, value, stringsAsFactors = FALSE) : 
  arguments imply differing number of rows: 2, 4

I can trick with as.numeric() as follows:

x$Index= as.numeric(x$Index)
y = melt(x,id.vars="Index")
y$Index = as.chron(y$Index)
y
                Index variable value
1 (11/13/12 00:00:00)     Var1     1
2 (11/13/12 04:04:48)     Var1     2
3 (11/13/12 00:00:00)     Var2     9
4 (11/13/12 04:04:48)     Var2     8

But can it be simpler ? (I want to keep the chron class)

joran
  • 169,992
  • 32
  • 429
  • 468
fRed
  • 75
  • 1
  • 7
  • Why not simply create the data.frame without `as.chron` and then do: `transform(melt(x, "Index"), Index = as.chron(Index))`? – Arun Mar 26 '13 at 15:59
  • I get `Error in strptime(x, format, tz = tz) : invalid 'x' argument` when trying to reconstruct your data.frame. – Ista Mar 26 '13 at 15:59
  • @Ista, I've fixed the errors in the input data. Try again. – Arun Mar 26 '13 at 16:00
  • What is the problem with your solution? Maube I miss somethin, but you keep the chron class in your final result. – agstudy Mar 26 '13 at 16:10
  • the problem is that I want to reduce the amount of computation – fRed Mar 27 '13 at 08:09

2 Answers2

2

(1) I assume you issued this command before running the code shown:

library(reshape2)

In that case you could use the reshape package instead. It doesn't result in this problem:

library(reshape)

Other solutions are to

(2) use R's reshape function:

reshape(direction = "long", data = x, varying = list(2:3), v.names = "Var")

(3) or convert the chron column to numeric, use melt from the reshape2 package and then convert back:

library(reshape2)
xt <- transform(x, Index = as.numeric(Index))
transform(melt(xt, id = 1), Index = chron(Index))

ADDED additional solutions.

G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • Yes i'm working with reshape2 (and ggplot2, which depend on it).Your solution is practical and work... but it takes much time (a factor of ~10) – fRed Mar 27 '13 at 08:57
  • thank, the second solution fits to my purpose. 3rd solution short correction : `numeric` to `as.numeric`, else the error message `argument 'length' incorrect` – fRed Mar 29 '13 at 08:19
1

I'm not sure but I think this might be an "oversight" in chron (or possibly data.frame, but that seems unlikely).

The issue occurs when constructing the data frame in melt.data.frame in reshape2, which typically uses recycling, but that portion of data.frame:

for (j in seq_along(xi)) {
    xi1 <- xi[[j]]
    if (is.vector(xi1) || is.factor(xi1)) 
        xi[[j]] <- rep(xi1, length.out = nr)
    else if (is.character(xi1) && class(xi1) == "AsIs") 
        xi[[j]] <- structure(rep(xi1, length.out = nr), class = class(xi1))
    else if (inherits(xi1, "Date") || inherits(xi1, "POSIXct")) 
        xi[[j]] <- rep(xi1, length.out = nr)
    else {
        fixed <- FALSE
        break
    }

seems to go wrong, as the chron variable doesn't inherit either Date or POSIXct. This removes the error but alters the date times:

x = data.frame(Index = as.chron(c(15657.00,15657.17)), Var1 = c(1,2), Var2 = c(9,8))
class(x$Index) <- c(class(x$Index),'POSIXct')
y = melt(x,id.vars="Index")

Like I said, this sorta smells like a bug somewhere. My money would be on the need for chron to add POSIXct to the class vector, but I could be wrong. The obvious alternative would be to use POSIXct date times instead.

joran
  • 169,992
  • 32
  • 429
  • 468
  • Indeed, it gives no error messsage, but does not fix it. The dates have changed : `(11/13/12 00:00:00)` -> `"1970-01-01 05:20:57 CET"` – fRed Mar 27 '13 at 09:09
  • If you accept the fact that data frames have the odd behavior of recycling some classes but not others then the problem is in reshape2 for assuming otherwise. See my answer: http://stackoverflow.com/questions/15641538/melt-with-chron/15642452#15642452 – G. Grothendieck Mar 27 '13 at 11:51
  • @fRed So maybe the most expedient thing to do would be to use POSIXct date times, rather than chron? – joran Mar 27 '13 at 13:43
  • That could introduce potential time zone bugs that can't affect chron. – G. Grothendieck Mar 27 '13 at 15:56
  • @G.Grothendieck So we've circled back to this being a bug in reshape2? – joran Mar 27 '13 at 16:17