Question

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)

Was it helpful?

Solution

(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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top