62

我无法像使用文本一样使用公式。我想要做的是将公式连接到图表的标题。但是,当我尝试将公式与文本一起使用时,我失败了:

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

这可以。现在我想像这样构建字符串"my text celkem ~ rok + mesic"- 这就是问题所在:

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"

sprint现在我看到package 中有一个函数gtools,但我认为这是一个基本的东西,值得在默认环境中解决!

4

10 回答 10

47

包中的一个简短解决方案formula.tools,作为一个函数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在长公式的情况下可能很有用:

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"

这是因为width.cutoff = 60L?deparse.

于 2013-02-03T10:04:17.443 回答
33

尝试format

paste("my text", format(frm))
## [1] "my text celkem ~ rok + mesic"
于 2013-02-03T14:17:11.733 回答
16

涵盖所有内容的最简单解决方案:

f <- formula(model)
paste(deparse(f, width.cutoff = 500), collapse="")
于 2013-02-03T09:58:27.777 回答
12

或作为 Julius 版本的替代品(注意:您的代码不是独立的)

celkem = 1
rok = 1
mesic = 1
model <- lm(celkem ~ rok + mesic)
paste("my model ", deparse(formula(model)))
于 2013-02-03T10:06:27.407 回答
8

最简单的方法是这样的:

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

完毕!

于 2017-04-18T10:39:01.170 回答
8

引入了 R 4.0.0(2020-04-24 发布)deparse1,它从不将结果拆分为多个字符串:

f <- y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + 
     p + q + r + s + t + u + v + w + x + y + z
deparse(f)
# [1] "y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + " "    p + q + r + s + t + u + v + w + x + y + z"                   
deparse1(f)
# [1] "y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z"



但是,它仍然有一个width.cutoff参数(默认(最大值)500:),之后引入换行符,但行分隔collapse(默认:) " "not \n,留下额外的空白(即使有collapse = "")(gsub如果需要,请使用删除它们,请参阅Ross D's答案):

> f <- rlang::parse_expr( paste0("y~", paste0(rep(letters, 20), collapse="+")))
> deparse1(f, collapse = "")
[1] "y ~ a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u +     v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p +     q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k +     l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + a + b + c + d + e + f +     g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z"

要在 R < 4.0.0 中使用backports(推荐)或复制它的实现:

#  Part of the R package, https://www.R-project.org
#
#  Copyright (C) 1995-2019 The R Core Team
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  A copy of the GNU General Public License is available at
#  https://www.R-project.org/Licenses/

deparse1 <- function (expr, collapse = " ", width.cutoff = 500L, ...) 
    paste(deparse(expr, width.cutoff, ...), collapse = collapse)

于 2020-07-16T08:23:36.270 回答
2

这是一个使用的解决方案print.formula,它看起来很巧妙,但它可以在单行中完成工作并且避免使用deparse并且不需要使用额外的包。我只是捕获打印公式的输出,使用capture.output

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

如果是长公式:

 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"
于 2013-02-03T12:05:32.497 回答
2

另一个deparse基于 - 的解决方案是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"

他们确实有一个宽度参数来避免换行,但也限制为 500 个字符。至少它是一个很可能已经加载的函数......

于 2019-07-13T16:39:29.887 回答
1

然后添加 gsub 删除空格

gsub("  ", "", paste(format(frm), collapse = ""))
于 2015-07-01T05:35:15.647 回答
0

今天优化了一些功能。到目前为止还没有提到的一些方法。

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
于 2022-02-10T18:55:51.607 回答