Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert R formula to text?

Tags:

r

r-formula

I have trouble working with formula as with text. What I'm trying to do is to concatenate the formula to the title of the graph. However, when I try to work with the formula as with text, I fail:

model <- lm(celkem ~ rok + mesic)
formula(model)
# celkem ~ rok + mesic

This is fine. Now I want to build string like "my text celkem ~ rok + mesic" - this is where the problem comes:

paste("my text", formula(model))
# [1] "my text ~"           "my text celkem"      "my text rok + mesic"

paste("my text", as.character(formula(model)))
# [1] "my text ~"           "my text celkem"      "my text rok + mesic"

paste("my text", toString(formula(model)))
# [1] "my text ~, celkem, rok + mesic"

Now I see there is a sprint function in package gtools, but I think this is such a basic thing that it deserves a solution within the default environment!!

like image 621
Tomas Avatar asked Feb 03 '13 09:02

Tomas


People also ask

How do I convert an object to a string in R?

Convert an Object to a String in R Programming – toString() Function. toString() function in R Language is used to convert an object into a single character string.

How do I convert a list to a string in R?

To convert the list to string in R, use the toString() function. The toString() is an inbuilt R function that converts An R Object To a Character String.


9 Answers

A short solution from the package formula.tools, as a function as.character.formula:

frm <- celkem ~ rok + mesic
Reduce(paste, deparse(frm))
# [1] "celkem ~ rok + mesic"

library(formula.tools)
as.character(frm)
# [1] "celkem ~ rok + mesic"

Reduce might be useful in case of long formulas:

frm <- formula(paste("y ~ ", paste0("x", 1:12, collapse = " + ")))

deparse(frm)
# [1] "y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + "
# [2] "    x12"                                                      
Reduce(paste, deparse(frm))
# [1] "y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 +      x12"

Which is because of width.cutoff = 60L in ?deparse.

like image 91
Julius Vainora Avatar answered Oct 02 '22 19:10

Julius Vainora


Try format :

paste("my text", format(frm))
## [1] "my text celkem ~ rok + mesic"
like image 43
G. Grothendieck Avatar answered Oct 01 '22 19:10

G. Grothendieck


Simplest solution covering everything:

f <- formula(model)
paste(deparse(f, width.cutoff = 500), collapse="")
like image 35
Tomas Avatar answered Sep 30 '22 19:09

Tomas


or as an alternative to Julius's version (note: your code was not self-contained)

celkem = 1
rok = 1
mesic = 1
model <- lm(celkem ~ rok + mesic)
paste("my model ", deparse(formula(model)))
like image 40
Dieter Menne Avatar answered Oct 03 '22 19:10

Dieter Menne


Another deparse-based solution is rlang::expr_text() (and rlang::quo_text()):

f <- Y ~ 1 + a + b + c + d + e + f + g + h + i +j + k + l + m + n + o + p + q + r + s + t + u
rlang::quo_text(f)
#> [1] "Y ~ 1 + a + b + c + d + e + f + g + h + i + j + k + l + m + n + \n    o + p + q + r + s + t + u"

They do have a width argument to avoid line breaks, but that is limited to 500 characters too. At least it's a single function that is most likely loaded already...

like image 37
jan-glx Avatar answered Sep 30 '22 19:09

jan-glx


The easiest way is this:

f = formula(model)
paste(f[2],f[3],sep='~')

done!

like image 25
TPArrow Avatar answered Sep 29 '22 19:09

TPArrow


Here a solution which use print.formula, it seems trick but it do the job in oneline and avoid the use of deparse and no need to use extra package. I just capture the output of the print formula, using capture.output

paste("my text",capture.output(print(formula(celkem ~ rok + mesic))))
[1] "my text celkem ~ rok + mesic"

In case of long formula:

 ff <- formula(paste("y ~ ", paste0("x", 1:12, collapse = " + ")))
 paste("my text",paste(capture.output(print(ff)), collapse= ' '))

 "my text y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 +      x12"
like image 22
agstudy Avatar answered Oct 03 '22 19:10

agstudy


Then add gsub to remove white spaces

gsub("  ", "", paste(format(frm), collapse = ""))
like image 28
Ross D Avatar answered Oct 02 '22 19:10

Ross D


Was optimizing some functions today. A few approaches that have not been mentioned so far.

f <- Y ~ 1 + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u
bench::mark(
  expression = as.character(as.expression(f)),
  deparse = deparse(f, width.cutoff = 500L),
  deparse1 = deparse1(f),
  tools = formula.tools:::as.character.formula(f),
  stringi = stringi::stri_c(f),
  I = as.character(I(f)),
  as = as(f, "character"),
  txt = gettext(f),
  txtf = gettextf(f),
  sub = sub("", "", f),
  chr = as.character(f),
  str = substring(f, 1L),
  paste = paste0(f),
)[c(1, 3, 5, 7)]

#> # A tibble: 13 x 3
#>    expression   median mem_alloc
#>    <bch:expr> <bch:tm> <bch:byt>
#>  1 expression   15.4us        0B
#>  2 deparse        31us        0B
#>  3 deparse1       34us        0B
#>  4 tools        58.7us    1.74MB
#>  5 stringi        67us    3.09KB
#>  6 I            64.1us        0B
#>  7 as          100.5us  521.61KB
#>  8 txt          83.4us        0B
#>  9 txtf         85.8us    3.12KB
#> 10 sub          64.6us        0B
#> 11 chr            60us        0B
#> 12 str          62.8us        0B
#> 13 paste        63.5us        0B
like image 25
Donald Seinen Avatar answered Oct 02 '22 19:10

Donald Seinen