Skip to content

all.equal.tbl_df throws an error when tbl_df objects have columns of mode "list" #107

@BillDunlap

Description

@BillDunlap

There is a problem in coming up with a canonical row order for tbl_df's containing lists,
at least if the list is in the first column. It would be simplest if base::order() did something
reasonable for lists.

T <- tibble::data_frame(A=list(1,c("b","a"),c(pi,exp(1),-1)), B=13:11)
all.equal(T, T) # expect TRUE
Error in (function (..., na.last = TRUE, decreasing = FALSE, method = c("shell", :
unimplemented type 'list' in 'listgreater'
all.equal(T, T, ignore_row_order = FALSE) # expect TRUE
[1] TRUE
packageVersion("tibble")
[1] ‘1.0.12’
version$version.string
[1] "R version 3.3.0 (2016-05-03)"

While you are messing around with this, it would be good to use the idiom
do.call(order, unname(frame))
instead
do.call(order, frame)
as the latter gives an error if the frame has a column with the name of an argument
to order. E.g.,

U <- data_frame(method=c("old","new"), time=c(4.5, 2.3))
all.equal(U, U)
Error in match.arg(method) : 'arg' must be of length 1

The following code in the ignore_row_order part of all.equal.tbl_df
fixes both problems. I don't know if there are any other unorderable
types allowed as columns of tbl_df objects.

if (ignore_row_order) {
    patch_for_order <- function(tbl_df) {
        for (i in seq_len(ncol(tbl_df))) {
            if (is.list(tbl_df[[i]])) {
                tbl_df[[i]] <- paste(collapse = "\n", deparse(tbl_df[[i]]))
            }
        }
        unname(tbl_df)
    }
    target <- target[do.call(order, patch_for_order(target)), ]
    current <- current[do.call(order, patch_for_order(current)), ]
}

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