我正在编写一些将数学函数定义转换为有效 R 代码的代码。因此,我使用 deparse(substitute))
来访问这些函数定义,以便将它们更改为有效的 R 代码。
例如我有函数 LN(x)^y
应该变成 log(x)^y
。我可以使用我的 to_r
函数的第一个版本来做到这一点:
to_r <- function(x) {
parse(text = gsub("LN", "log", deparse(substitute(x))))
}
to_r(LN(x)^y)
这返回 expression(log(x)^y)
这是我所期望的。
我还得到类似于 LN("x a")^y
的函数定义。为了处理那些我可以扩展我的功能:
to_r_2 <- function(x) {
parse(text = gsub(" ", "_", gsub("\"", "", gsub("LN", "log", deparse(substitute(x))))))
}
to_r_2(LN("x a")^y)
这会返回 expression(log(x_a)^y)
这很好。
但是,当我的输入变成类似 LN("x a")*2^y
时,这会失败:
parse(text = gsub(" ", "_", gsub("\"", "", gsub("LN", "log", deparse(substitute(LN("x a")*2^y))))))
Error in parse(text = gsub(" ", "_", gsub("\"", "", gsub("LN", "log", : :1:9: unexpected input 1: log(x_a)_ ^
原因是 deparse(substitute(LN("x a")*2^y))
在 *
周围引入了空格,然后我 gsub
那些带有下划线的空格,这是 parse
的问题。
有没有办法解决这个问题?
也许是 deparse(substitute))
的替代品?
(说的很明显:将 gsub("", "_", x)
替换为 gsub("", "", x)
是这不是一个真正的选择,因为变量名称变得不可读。例如,Reason one of Something
将变为 ReasononeofSomething
,它的可读性远低于尝试的 Reason_one_of_Something
。 )
最佳答案
这是一个辅助函数,用于将表达式中的任何字符值替换为符号(空格替换为下划线)
chr_to_sym <- function(x) {
if (is(x, "call")) {
as.call(do.call("c",lapply(as.list(x), chr_to_sym), quote=T))
} else if (is(x, "character")) {
as.symbol(gsub(" ","_", x))
} else {
x
}
}
然后我们可以在您的翻译功能中使用它
to_r <- function(x) {
expr <- substitute(x)
expr <- do.call("substitute", list(expr, list(LN=quote(log))))
as.expression(chr_to_sym(expr))
}
请注意,此版本直接使用表达式。它不做任何解析/字符串操作。这通常更安全。这适用于您提供的示例
to_r(LN(x)^y)
# expression(log(x)^y)
to_r(LN("x a")^y)
# expression(log(x_a)^y)
to_r(LN("x a")*2^y)
# expression(log(x_a) * 2^y)
关于r - 使用 `deparse(substitute))` (或替代方法)时如何处理空格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55167615/