Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lubridate create interval operator %--% throws "'origin' must be supplied" error on NA

Tags:

r

na

lubridate

The Lubridate %--% interval operator throws an error for certain configurations of NA and not-NA. In particular, why does the fourth call to %--% below return an error? Is this a bug?

> library(lubridate)

> c(ymd("1980-10-14"), ymd("1980-10-14")) %--% c(ymd("1981-10-14"), ymd("1982-10-14"))
[1] 1980-10-14 10:00:00 AEST--1981-10-14 10:00:00 AEST
[2] 1980-10-14 10:00:00 AEST--1982-10-14 10:00:00 AEST

> c(ymd("1980-10-14"), NA) %--% c(ymd("1981-10-14"), ymd("1982-10-14"))
[1] 1980-10-14 10:00:00 AEST--1981-10-14 10:00:00 AEST
[2] NA--NA                                           

> c(NA, NA) %--% c(ymd("1980-10-14"), ymd("1982-10-14"))
[1] NA--NA NA--NA

> c(NA, ymd("1980-10-14")) %--% c(ymd("1981-10-14"), ymd("1982-10-14"))
Error in as.POSIXct.numeric(start) : 'origin' must be supplied

Note that

> NA %--% ymd("1981-10-14")
[1] NA--NA

> ymd("1981-10-14") %--% NA
[1] 1981-10-14 UTC--NA
like image 563
asnr Avatar asked Oct 26 '25 08:10

asnr


2 Answers

The anomaly is occurring in the fourth example because the c function returns a numeric class vector when the first argument is NA. On the other hand, it returns a POSIXct object when the first argument is a valid call to `ymd:

library(lubridate)
  c(NA, ymd("1980-10-14"))
#[1]        NA 340329600

 class( c(NA, ymd("1980-10-14")) )
#[1] "numeric"
 library(lubridate)
  class( c( ymd("1980-10-14"))  )
#[1] "POSIXct" "POSIXt" 
  class( c( ymd("1980-10-14"), NA) )
#[1] "POSIXct" "POSIXt" 

This may also explain the other anomalies as well. It may take some tinkering with code that is above my pay grade.

> getAnywhere(c.POSIXct)
2 differing objects matching ‘c.POSIXct’ were found
in the following places
  package:base
  registered S3 method for c from namespace base
  namespace:base
  namespace:lubridate
Use [] to view one of them
like image 106
IRTFM Avatar answered Oct 28 '25 22:10

IRTFM


This is because c(NA,thing) is not treated like c(thing,NA):

> is.POSIXct(c(NA, ymd("1980-01-01")))
[1] FALSE
> is.POSIXct(c(ymd("1980-01-01"),NA))
[1] TRUE

In the first case, base::c is used because the first argument is NA. In the second case, c.POSIXct is called because the first argument is POSIXct. So in the first case, everything gets reduced down to a numeric vector.

Possible workaround solution is not to construct vectors like that:

> c(NA, ymd("1980-10-14")) %--% c(ymd("1981-10-14"), ymd("1982-10-14"))
Error in as.POSIXct.numeric(start) : 'origin' must be supplied

but to use ymd to construct vectors of the right type by feeding it a vector with the NAs in:

> ymd(c(NA, "1980-10-14")) %--% ymd(c("1981-10-14","1982-10-14"))
[1] NA--NA                         1980-10-14 UTC--1982-10-14 UTC

Note the code for the %--% operator can be seen by typing interval - its just an alias for that.

Still odd that NA %--% ymd() is NA-NA yet ymd() %--% NA has a valid start... Another bug possibly.

like image 33
Spacedman Avatar answered Oct 28 '25 23:10

Spacedman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!