[R] fixup for debug package and R2.4.0

Mark.Bravington at csiro.au Mark.Bravington at csiro.au
Sat Dec 2 02:10:46 CET 2006


A number of users have spotted a terminal problem with the 'debug' package under R2.4.0, along the lines of 

> mtrace(x)
> x()
Error in attr(value, "row.names") <- rlabs :
 row names must be 'character' or 'integer', not 'double' 

This arose from a bug in 'rbind.data.frame' in R2.4.0 itself. The bug is fixed in R2.4.0 patched, so the best solution is to install the patched version. This is painless, at least for Windows, since a binary version of R-patched is available on CRAN (I hadn't realized this).

If for reason you desperately don't want to install R-patched, the following *ugly* bit of code can be run after loading the 'debug' library [so you could put this in your '.First' function]:

Thanks to all who reported the problem

Mark Bravington
mark.bravington at csiro.au

mvbutils:::assign.to.base( 'rbind.data.frame', function (..., deparse.level = 1) 
{
    match.names <- function(clabs, nmi) {
        if (all(clabs == nmi)) 
            NULL
        else if (length(nmi) == length(clabs) && all(nii <- match(nmi, 
            clabs, 0))) {
            m <- pmatch(nmi, clabs, 0)
            if (any(m == 0)) 
                stop("names do not match previous names")
            m
        }
        else stop("names do not match previous names:\n\t", paste(nmi[nii == 
            0], collapse = ", "))
    }
    Make.row.names <- function(nmi, ri, ni, nrow) {
        if (nchar(nmi) > 0) {
            if (ni == 0) 
                character(0)
            else if (ni > 1) 
                paste(nmi, ri, sep = ".")
            else nmi
        }
        else if (nrow > 0 && identical(ri, 1:ni)) 
            as.integer(seq.int(from = nrow + 1, length = ni))
        else ri
    }
    allargs <- list(...)
    allargs <- allargs[sapply(allargs, length) > 0]
    n <- length(allargs)
    if (n == 0) 
        return(structure(list(), class = "data.frame", row.names = integer()))
    nms <- names(allargs)
    if (is.null(nms)) 
        nms <- character(length(allargs))
    cl <- NULL
    perm <- rows <- rlabs <- vector("list", n)
    nrow <- 0
    value <- clabs <- NULL
    all.levs <- list()
    for (i in 1:n) {
        xi <- allargs[[i]]
        nmi <- nms[i]
        if (is.matrix(xi)) 
            allargs[[i]] <- xi <- as.data.frame(xi)
        if (inherits(xi, "data.frame")) {
            if (is.null(cl)) 
                cl <- oldClass(xi)
            ri <- attr(xi, "row.names")
            ni <- length(ri)
            if (is.null(clabs)) 
                clabs <- names(xi)
            else {
                pi <- match.names(clabs, names(xi))
                if (!is.null(pi)) 
                  perm[[i]] <- pi
            }
            rows[[i]] <- seq.int(from = nrow + 1, length = ni)
            rlabs[[i]] <- Make.row.names(nmi, ri, ni, nrow)
            nrow <- nrow + ni
            if (is.null(value)) {
                value <- unclass(xi)
                nvar <- length(value)
                all.levs <- vector("list", nvar)
                has.dim <- logical(nvar)
                facCol <- logical(nvar)
                ordCol <- logical(nvar)
                for (j in 1:nvar) {
                  xj <- value[[j]]
                  if (!is.null(levels(xj))) {
                    all.levs[[j]] <- levels(xj)
                    facCol[j] <- TRUE
                  }
                  else facCol[j] <- is.factor(xj)
                  ordCol[j] <- is.ordered(xj)
                  has.dim[j] <- length(dim(xj)) == 2
                }
            }
            else for (j in 1:nvar) {
                xij <- xi[[j]]
                if (is.null(pi) || is.na(jj <- pi[[j]])) 
                  jj <- j
                if (facCol[jj]) {
                  if (length(lij <- levels(xij)) > 0) {
                    all.levs[[jj]] <- unique(c(all.levs[[jj]], 
                      lij))
                    ordCol[jj] <- ordCol[jj] & is.ordered(xij)
                  }
                  else if (is.character(xij)) 
                    all.levs[[jj]] <- unique(c(all.levs[[jj]], 
                      xij))
                }
            }
        }
        else if (is.list(xi)) {
            ni <- range(sapply(xi, length))
            if (ni[1] == ni[2]) 
                ni <- ni[1]
            else stop("invalid list argument: all variables should have the same length")
            rows[[i]] <- ri <- as.integer(seq.int(from = nrow + 
                1, length = ni))
            nrow <- nrow + ni
            rlabs[[i]] <- Make.row.names(nmi, ri, ni, nrow)
            if (length(nmi <- names(xi)) > 0) {
                if (is.null(clabs)) 
                  clabs <- nmi
                else {
                  tmp <- match.names(clabs, nmi)
                  if (!is.null(tmp)) 
                    perm[[i]] <- tmp
                }
            }
        }
        else if (length(xi) > 0) {
            rows[[i]] <- nrow <- nrow + 1
            rlabs[[i]] <- if (nchar(nmi) > 0) 
                nmi
            else as.integer(nrow)
        }
    }
    nvar <- length(clabs)
    if (nvar == 0) 
        nvar <- max(sapply(allargs, length))
    if (nvar == 0) 
        return(structure(list(), class = "data.frame", row.names = integer()))
    pseq <- 1:nvar
    if (is.null(value)) {
        value <- list()
        value[pseq] <- list(logical(nrow))
    }
    names(value) <- clabs
    for (j in 1:nvar) if (length(lij <- all.levs[[j]]) > 0) 
        value[[j]] <- factor(as.vector(value[[j]]), lij, ordered = ordCol[j])
    if (any(has.dim)) {
        rmax <- max(unlist(rows))
        for (i in (1:nvar)[has.dim]) if (!inherits(xi <- value[[i]], 
            "data.frame")) {
            dn <- dimnames(xi)
            rn <- dn[[1]]
            if (length(rn) > 0) 
                length(rn) <- rmax
            pi <- dim(xi)[2]
            length(xi) <- rmax * pi
            value[[i]] <- array(xi, c(rmax, pi), list(rn, dn[[2]]))
        }
    }
    for (i in 1:n) {
        xi <- unclass(allargs[[i]])
        if (!is.list(xi)) 
            if (length(xi) != nvar) 
                xi <- rep(xi, length.out = nvar)
        ri <- rows[[i]]
        pi <- perm[[i]]
        if (is.null(pi)) 
            pi <- pseq
        for (j in 1:nvar) {
            jj <- pi[j]
            xij <- xi[[j]]
            if (has.dim[jj]) {
                value[[jj]][ri, ] <- xij
                rownames(value[[jj]])[ri] <- rownames(xij)
            }
            else {
                value[[jj]][ri] <- if (is.factor(xij)) 
                  as.vector(xij)
                else xij
                if (!is.null(nm <- names(xij))) 
                  names(value[[jj]])[ri] <- nm
            }
        }
    }
    rlabs <- unlist(rlabs)
    if (any(duplicated(rlabs))) 
        rlabs <- make.unique(as.character(unlist(rlabs)), sep = "")
    if (is.null(cl)) {
        as.data.frame(value, row.names = rlabs)
    }
    else {
        class(value) <- cl
        attr(value, "row.names") <- rlabs
        value
    }
})




More information about the R-help mailing list