Search code examples
rexpressioncharactermaxlength

Is there a way to get around the 500 character limit when coercing expressions to characters using as.character?


I am currently writing a small package that is supposed to fit multinomial processing tree models (for not needed background info a web page and a pdf).

What it does is the following: It reads a model (i.e., formulas) from a file and converts them (via parse) to expressions. Later, some of the variables in these expressions are exchanged by other variables from another file (i.e., model restrictions are applied). Therefore, the model is back transformed to characters (via as.character) and the exchange is done via gsub.
The problem: If a single expression is longer than 500 characters, transforming them back via as.character truncates them to 500 characters (or so).
?as.character gives:

as.character truncates components of language objects to 500 characters (was about 70 before 1.3.1).

Here an example:

text1 <- paste(rep(LETTERS, 10), collapse = " + ")
nchar(text1)
[1] 1037

expr1 <- parse(text = text1)
text2 <- as.character(expr1)
[1] 504

The question: Can you get around this 500 character limitation?

I know we could get around this problem if we would apply the restrictions (i.e., exchange the variables) before we parse the model the first time. But, this would involve a lot of programming, as the whole thing is basically ready, and it would be great if we could get around this 500 character limitations another way.


Solution

  • You can, by doing ugly things with deparse and gsub:

    expr1 <- parse(text = text1)
    attributes(expr1) <- NULL
    (text3 <- paste(deparse(expr1), collapse=""))
    #rm whitespace etc
    (text3 <- gsub("\\)$", "", gsub("^expression\\(", "", 
            gsub("[[:space:]][[:space:]]+", " ", text3))))
    nchar(text3)
    

    More to the point of your application, you can use deparse to make strings out of formulas, and use this function:

    safeDeparse <- function(expr){
        ret <- paste(deparse(expr), collapse="")
        #rm whitespace
        gsub("[[:space:]][[:space:]]+", " ", ret)
    }
    

    to get around the stupid length limit that makes deparse add linebreaks and split a single expression into many strings, compare:

    (f <- formula(paste("X ~", paste(rep(letters, 10), collapse=" + "))))
    deparse(f)
    safeDeparse(f)