sparrow
sparrow

Reputation: 1101

Why recycling chron class doesn't work in data.frame in R?

data.frame recycles shorter vectors to match the length of the data frame.

test1 = data.frame(x = 1:5, date = as.Date("2013-05-01"))
  x       date
1 1 2013-05-01
2 2 2013-05-01
3 3 2013-05-01
4 4 2013-05-01
5 5 2013-05-01

However, it does not seem to work with the chron class:

require(chron)
test2 = data.frame(x = 1:5, time = times("08:00:00"))

Error in data.frame(x = 1:5, time = times("08:00:00")) : 
arguments imply differing number of rows: 5, 1

There are workarounds, e.g. doing the recycling manually, like:

test3 = data.frame(x = 1:5, time = times(rep("08:00:00",5)))

But why doesn't the recycling work? Am I missing something here or is there a bug somewhere?

Upvotes: 1

Views: 82

Answers (1)

Peyton
Peyton

Reputation: 7396

The documentation for data.frame notes:

Objects passed to data.frame should have the same number of rows, but atomic vectors (see is.vector), factors and character vectors protected by I will be recycled a whole number of times if necessary (including as elements of list arguments).

If you look at the source for data.frame, you can actually see the check for is.vector.

So the question is, is your times object a vector? The answer's no:

is.vector(times("8:00:00"))
# [1] FALSE

Why is this? ?is.vector tells us a little more:

is.vector returns TRUE if x is a vector of the specified mode having no attributes other than names. It returns FALSE otherwise.

If you take a closer look at your times object, you can see that it does indeed have a non-names attribute:

str(times("8:00:00"))
# Class 'times'  atomic [1:1] 0.333
#  ..- attr(*, "format")= chr "h:m:s"

Interestingly, Date objects aren't vectors either, but data.frame makes an exception.

So, in the end, maybe the recycling rule is actually the recycling exception, at least in the case of data.frame. As you've already figured out though, a workaround is easy enough.

Upvotes: 2

Related Questions