6

我有许多类似于此的公式字符串:

str <- "( ((  A  ) *  J ) - ((  J  ) *  G  ) ) /  Z "

有很多括号不需要在那里,(A*J - J*G)/Z就足够了。R中是否有可以解决这个问题的函数或包?

我也尝试了 R 表达式的函数,as.formula但没有找到我需要的。

4

2 回答 2

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"
于 2013-06-21T19:04:15.113 回答
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

这在我尝试过的所有情况下都有效,但你可能想再测试一下。

如果你想要一个字符串作为返回值,那么使用deparseas in deparse(rmParen(parse(text = s)[[1]]))。请注意,deparse它的width.cutoff参数默认设置为 60,但如果实际表达式超过该长度,则可以将其设置为更大。

里亚卡斯

library(Ryacas)

s <- "( ((  A  ) *  J ) - ((  J  ) *  G  ) ) /  Z "
Simplify(s)

最后一行返回:

expression((A - G) * J/Z)

请注意,它实际上是调用计算的 print 方法,因此如果要保存它,请尝试使用yacas(Simplify(s))$textor as.character(yacas(Simplify(s)))

添加:Ryacas 解决方案。

于 2013-06-21T18:46:56.120 回答