Search code examples
rmethodsdispatch

R c() "combine-function", set class not by first input


I find myself writing some ugly code to set class of combined objects. Is there a simpler/faster way to do it? Below an example of my issue:

#some S3 class vector
y = structure(c(1577833200, 1577836800, 1577840400, 1577844000, 1577847600
), class = c("POSIXct", "POSIXt"), tzone = "")

#correct class
class(y)

#I want to front pad the vector with missing values, maybe sometimes append something else

#[1], correct class but only because y is first
x_right_class = c(y,NA)
class(x_right_class)

#[2] drops "POSIXct", "POSIXt" class because NA does not have that class
x_wrong_class = c(NA,y)
class(x_wrong_class)

#[3] this one works but is tedious, and looks ugly, maybe also slow
x_also_right_class = c(y[NA_integer_],y)


#is there a simpler/faster way, I can have the c()-function to behave like [1] (and not 2) without doing [3]
#simpler for better looking code, faster to avoid unnecessary reallocation of large vectors. I guess one time is inevitable.

update: by answers/comments it seems possible to tweak c() into a new function rc() "reverse combine" that dispatches on the n'th object. this function might need some extra safety checks I guess, but seems nice to have.

rc = function(...,dispath_by=NULL) {
  l = list(...)
  if(is.null(dispath_by)) dispath_by= length(l)
  class(l[[1]]) = class(l[[dispath_by]])
  do.call(c,l)
}

x_also_right_class = rc(NA, y)

x_also_right_class = rc(NA, y,NA,dispath_by=2)


Solution

  • convert NA to POSIXct

    x_wrong_class = c(as.POSIXct(NA),y)
    class(x_wrong_class)
    #[1] "POSIXct" "POSIXt"
    

    If the class if y is unknown we can do something like this :

    add_value <- NA
    class(add_value) <- class(y)
    c(add_value, y)