我有很多类似的公式字符串:
str <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
有许多括号不需要在那里,(A*J - J*G)/Z
就足够了。 R中是否有功能或包可以解决这个问题?
我尝试了R表达式的函数以及as.formula
,但没有找到我需要的函数。
答案 0 :(得分:5)
我们可以使用R解析器来完成这项工作。诀窍是R知道何时需要基于解析树的括号,所以我们可以简单地从树中删除:
见:
simplify <- function(e)
{
if( mode(e) %in% c("name","numeric") ) return(e)
op <- as.character(e[[1]])
if( op == "(" ) return(simplify(e[[2]]))
if( op %in% c("+","-","*","/","^") ) return(call(op, simplify(e[[2]]), simplify(e[[3]])))
}
simplifytext <- function(s) deparse(simplify(parse(text=s)[[1]]))
输入:
str <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
str2 <- gsub("-", "/", gsub("*", "+", str, fixed=TRUE))
结果:
> str2
[1] "( (( A ) + J ) / (( J ) + G ) ) / Z "
> simplifytext(str)
[1] "(A * J - J * G)/Z"
> simplifytext(str2)
[1] "(A + J)/(J + G)/Z"
答案 1 :(得分:4)
以下是两种方法:
R解析
rmParen <- function(e) {
if (length(e) > 1) {
if (identical(e[[1]], as.symbol("("))) e <- e[[2]]
if (length(e) > 1) for (i in 1:length(e)) e[[i]] <- Recall(e[[i]])
}
e
}
s <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
rmParen(parse(text = s)[[1]])
最后一行返回:
(A * J - J * G)/Z
这适用于我尝试的所有情况,但您可能想要再测试一下。
如果您希望将字符串作为返回值,请使用deparse
中的deparse(rmParen(parse(text = s)[[1]]))
。请注意,deparse
具有width.cutoff
参数,默认情况下设置为60,但如果实际表达式超过该长度,则可以设置为更大。
<强> Ryacas 强>
library(Ryacas)
s <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
Simplify(s)
最后一行返回:
expression((A - G) * J/Z)
请注意,它实际上是调用计算的print方法,因此如果要保存它,请尝试yacas(Simplify(s))$text
或as.character(yacas(Simplify(s)))
。
ADDED:Ryacas解决方案。