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

2

10

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.

Boche answered 3/3, 2011 at 12:15 Comment(3)
Can anyone give a good reason why such a limit would exist in a modern program?Gillead
@David This, is what I thought, too. Especially, why is it hardcoded, and not, for example, changeable in the options??Boche
That smacks of there being a statically sized array, char s[500] which seems lame. Perhaps there's a good reason....Gillead
P
7

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)
Pongid answered 3/3, 2011 at 12:50 Comment(3)
That sounds interesting. I tried to play around with deparse, too. But got a contextstack overflow at line 2. But I will try your version immediately.Boche
This code works on my machine, too. But there is an issue in my real program that still produces this error. But, I am on my way of finding it...Boche
Ahh, I forgot to get rid of the expression( after deparsing. Now everything works like a charm!Boche
W
0

Update:

From Base Version 2.15.0 the as.character now has this behaviour

as.character breaks lines in language objects at 500 characters, and inserts newlines.

To get the package version use:

packageVersion("base")

Cheers

Wellheeled answered 13/9, 2017 at 7:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.