Search code examples
rdataframebit64

bit64 NA doesn't replicate in data.frame constructor


While constructing a data-frame, columns are replicated if lengths differ.

> data.frame(x = c(1,2), y = NA_integer_)
  x  y
1 1 NA
2 2 NA

However, when I try to do this with bit64::NA_integer64_, I get an error. Does anyone know what could be happening? rep() works if it is called separately on bit64::NA_integer64_.

> data.frame(x = c(1,2), y = bit64::NA_integer64_)
Error in data.frame(x = c(1, 2), y = bit64::NA_integer64_) : 
  arguments imply differing number of rows: 2, 1
> rep(bit64::NA_integer64_, 2)
integer64
[1] <NA> <NA>

Solution

  • data.frame will only recycle:

    • Vector with no attributes other than names
    • factor
    • AsIs character
    • Date
    • POSIXct

    tibble doesn't have this problem.

    tibble::tibble(x = c(1,2), y = bit64::NA_integer64_)
    #> # A tibble: 2 x 2
    #>       x       y
    #>   <dbl> <int64>
    #> 1     1      NA
    #> 2     2      NA
    

    Here is the relevant snippet from data.frame

    for (i in seq_len(n)[nrows < nr]) {
        xi <- vlist[[i]]
        if (nrows[i] > 0L && (nr%%nrows[i] == 0L)) {
            xi <- unclass(xi)
            fixed <- TRUE
            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) && inherits(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
                }
            }
            if (fixed) {
                vlist[[i]] <- xi
                next
            }
        }
        stop(gettextf("arguments imply differing number of rows: %s", 
            paste(unique(nrows), collapse = ", ")), domain = NA)
    }