[R] Recode

John Fox jfox at mcmaster.ca
Sat May 17 15:23:45 CEST 2008


Dear Raphael,

This is a bug in recode(): The problem is that recode() tries to figure
out whether it can convert the result to numeric, and the approach that
it uses is faulty when there are both numerals and other characters in
the recode target. 

I should say, as well, that I can't precisely duplicate your results: I
get NAs and a warning rather than an error. It's also odd that this
error didn't surface earlier.

I've attached a patched version of recode() that should work properly.
I need to test it more before updating the car package, but I'll do
that some time next week.

Thank you for bringing the problem to my attention.

John

------------- snip ----------

recode <-
function (var, recodes, as.factor.result, levels) 
{
    recode.list <- rev(strsplit(recodes, ";")[[1]])
    is.fac <- is.factor(var)
    if (missing(as.factor.result)) 
        as.factor.result <- is.fac
    if (is.fac) 
        var <- as.character(var)
    result <- var
    if (is.numeric(var)) {
        lo <- min(var, na.rm = TRUE)
        hi <- max(var, na.rm = TRUE)
    }
    for (term in recode.list) {
        if (0 < length(grep(":", term))) {
            range <- strsplit(strsplit(term, "=")[[1]][1], ":")
            low <- eval(parse(text = range[[1]][1]))
            high <- eval(parse(text = range[[1]][2]))
            target <- eval(parse(text = strsplit(term, "=")[[1]][2]))
            result[(var >= low) & (var <= high)] <- target
        }
        else if (0 < length(grep("else", term))) {
            target <- eval(parse(text = strsplit(term, "=")[[1]][2]))
            result[1:length(var)] <- target
        }
        else {
            set <- eval(parse(text = strsplit(term, "=")[[1]][1]))
            target <- eval(parse(text = strsplit(term, "=")[[1]][2]))
            for (val in set) {
                if (is.na(val)) 
                  result[is.na(var)] <- target
                else result[var == val] <- target
            }
        }
    }
    if (as.factor.result) {
        result <- if (!missing(levels)) 
            factor(result, levels = levels)
        else as.factor(result)
    }
    else if (!is.numeric(result)) {
        result.valid <- na.omit(result)
        save.warn <- options(warn=2)
        res <- try(if (length(result.valid) == length(grep("[0-9]",
result.valid))) 
            as.numeric(result), silent=TRUE)
        result <- if (class(res) == "try-error" || is.null(res)) result
else res
        options(save.warn)
    }
    result
}
 
-------------- snip ----------------

On Sat, 17 May 2008 08:14:35 -0300
 "Raphael Saldanha" <saldanha.plangeo at gmail.com> wrote:
> Hi!
> 
> Using recode in cars package, I tryed to use the following:
> 
> recode(data$nrcomp, "lo:5='0 to 5'; 5:hi='bigger than 5'")
> 
> I got:
> 
> Erro em parse(text = strsplit(term, "=")[[1]][2]) :
>   unexpected end of input in "'0 to 5"
> 
> When I try only numbers, or only text, it's ok, but when I try to
> combine
> numbers and text, I got a error...
> 
> Any help?
> 
> -- 
> 
> Raphael Saldanha
> Brazil
> saldanha.plangeo at gmail.com

--------------------------------
John Fox, Professor
Department of Sociology
McMaster University
Hamilton, Ontario, Canada
http://socserv.mcmaster.ca/jfox/



More information about the R-help mailing list