如何防止`...`在 deparse(substitute(x)) 中消失

Posted

技术标签:

【中文标题】如何防止`...`在 deparse(substitute(x)) 中消失【英文标题】:How to prevent `...` to disappear inside of deparse(substitute(x)) 【发布时间】:2022-01-12 13:43:18 【问题描述】:

短版

考虑这个函数:

my_fun <- function(x)
  deparse(substitute(x))

如果只添加一个变量名,为什么函数会删除`?见这里:

my_fun(`bad name`)
"bad name"
my_fun(`bad name` - 1)
"`bad name` - 1"

加长版

我编写了一个简单的函数,它接受一个数据框并使用选定的列进行一些转换。这是函数:

my_fun <- function(data, transform)
  transform <- deparse(substitute(transform))
  transform <- unlist(strsplit(transform, "\\+"))
  out <- do.call("cbind.data.frame", lapply(transform, function(transform_i)
    eval(parse(text= transform_i), data)
  ))
  names(out) <- transform
  return(out)

有了这个函数,我们可以做这样的事情:

# Create data.
df <- data.frame(matrix(rep(1:4, 2), ncol= 2))
names(df) <- c("good_name", "bad name")

# Transform data with function.
my_fun(df, sqrt(good_name) + sqrt(`bad name`) - 1)
  sqrt(good_name)   sqrt(`bad name`) - 1
1         1.000000             0.0000000
2         1.414214             0.4142136
3         1.732051             0.7320508
4         2.000000             1.0000000

但是,如果我们输入一个包含空格的名称,如下所示:my_fun(df, `bad name`)。我注意到deparse(substitute(transform)) 删除了 ` 如果我不进行任何转换。见这里:

my_fun <- function(data, transform)
  deparse(substitute(transform))

my_fun(df, `bad name`)
"bad name"
my_fun(df, `bad name` -1)
"`bad name` - 1"

如何防止deparse(substitute(transform)) 删除`?

我知道有很多方法可以像我的函数那样转换数据框。例如,我们可以在这里使用 with(df, `bad name` -1) 和 with(df, `bad name`)。但这不是问题。

【问题讨论】:

来自?deparse:反引号选项的默认值不是引用单个符号,而是仅引用复合表达式。这是避免破坏现有代码的折衷方案。看看substitute(`bad_name`) vs deparse(subsitutte(`bad_name`)) vs deparse(substitute(`bad_name`), backtick = T)。但是,当我运行 my_fun(df, `bad name`) 时,结果很好。 @DonaldSeinen 为长版本 my_fun 运行 my_fun(df, `bad name`) 会导致此错误:解析错误(文本 = 转换_i)::1:5 : 意外符号 1: 坏名 ^ 【参考方案1】:

来自帮助文件?default反引号选项的默认值不是引用单个符号,而是仅引用复合表达式。 This SO post 提示查看 ?Quotes 帮助文件 - 如果需要,我们可以使用反斜杠转义反引号。

在本例中,可以尝试将deparse 函数的反引号参数设置为TRUE。要比较不同的方法,以及如何分解组合,请考虑以下情况:

substitute(`bad name`)
#> `bad name`

deparse(substitute(`bad name`))
#> [1] "bad name"

deparse(substitute(`bad name`), backtick = T)
#> [1] "`bad name`"

# and see this fail:
substitute(`bad name)

# and this return
deparse(
  deparse(substitute(`bad name`))
)
#> "\"bad name\""

deparse(substitute(
  `deparse(substitute(bad name))`
))
#> [1] "deparse(substitute(bad name))"

deparse(substitute(
  `deparse(substitute(`bad name`))`
))
#> Error: unexpected symbol in:
#> "deparse(substitute(
#>  `deparse(substitute(`bad"
#> > ))
#> Error: unexpected ')' in ")"

# but
deparse(substitute(
  `deparse(substitute(\`bad name\`))`
))
#> [1] "deparse(substitute(`bad name`))"

如果打算强制使用角色名称,请查看 deparse1 以了解 R4.0.0(2020 年 4 月)及以后的情况。

【讨论】:

以上是关于如何防止`...`在 deparse(substitute(x)) 中消失的主要内容,如果未能解决你的问题,请参考以下文章

php Esconde o editor de texto de uma。 Para isso adicioneessafunçãoemfunctions.php e substi

R语言parse函数deparse函数expression函数实现字符串和表达式的转换实战

将多个小标题导出到 XLSX -- 使用 deparse(substitute()) 时的 sheetName 问题

R语言 qplot

定义 `(<-` 运算符时获取 x 的名称

增加字符串间距