Skip to content

robustness -- as.data.table(table(NULL)) gives wrong error #4179

@MichaelChirico

Description

@MichaelChirico
as.data.table(table(NULL))
# Error in (function (..., sorted = TRUE, unique = FALSE)  : 
#   attempt to set an attribute on NULL

with full traceback():

5: (function (..., sorted = TRUE, unique = FALSE) 
   {
       l = list(...)
       if (isFALSE(getOption("datatable.CJ.names", TRUE))) {
           if (is.null(vnames <- names(l))) 
               vnames = paste0("V", seq_len(length(l)))
           else if (any(tt <- vnames == "")) 
               vnames[tt] = paste0("V", which(tt))
       }
       else {
           vnames = name_dots(...)$vnames
           if (any(tt <- vnames == "")) 
               vnames[tt] = paste0("V", which(tt))
       }
       dups = FALSE
       for (i in seq_along(l)) {
           y = l[[i]]
           if (!length(y)) 
               next
           if (sorted) {
               if (!is.atomic(y)) 
                   stop("'sorted' is TRUE but element ", i, " is non-atomic, which can't be sorted; try setting sorted = FALSE")
               o = forderv(y, retGrp = TRUE)
               thisdups = attr(o, "maxgrpn", exact = TRUE) > 1L
               if (thisdups) {
                   dups = TRUE
                   if (length(o)) 
                     l[[i]] = if (unique) 
                       y[o[attr(o, "starts", exact = TRUE)]]
                     else y[o]
                   else if (unique) 
                     l[[i]] = y[attr(o, "starts", exact = TRUE)]
               }
               else {
                   if (length(o)) 
                     l[[i]] = y[o]
               }
           }
           else {
               if (unique) 
                   l[[i]] = unique(y)
           }
       }
       nrow = prod(vapply_1i(l, length))
       if (nrow > .Machine$integer.max) 
           stop(gettextf("Cross product of elements provided to CJ() would result in %.0f rows which exceeds .Machine$integer.max == %d", 
               nrow, .Machine$integer.max, domain = "R-data.table"))
       l = .Call(Ccj, l)
       setDT(l)
       l = setalloccol(l)
       setnames(l, vnames)
       if (sorted) {
           if (!dups) 
               setattr(l, "sorted", names(l))
           else setkey(l)
       }
       l
   })(V1 = NULL, sorted = FALSE)
4: do.call(CJ, c(val, sorted = FALSE))
3: data.table(do.call(CJ, c(val, sorted = FALSE)), N = as.vector(x), 
       key = key)
2: as.data.table.table(table(NULL))
1: as.data.table(table(NULL))

Probably we should return data.table(NULL) here.

Use case: edge case of a code that was returning proper tables the rest of the time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions