[我想找到一个很好的结构来在R中存储算术表达式。该表达式还可以具有sin
,cos
等数学函数。例如,我有一个(A*B)/(3*D) + cos(E)*F - sin(G)*mod(H)
形式的表达式,我想找到一种存储方式,以便以后提取表达式。将此视为函数调用,可以在其中发送要与每个变量(例如express(functions_1, variables_1, operators, functions_2, variables_2)
)一起使用的变量,函数和运算符的列表。现在,这些参数包含用于创建表达式的信息。一个示例调用为express (c(sin, cos), ("A", "C"), c("*", "+", "-"), c(mod, NULL), c("B", "D))
。这将导致表达式sin(A) * mod(B) + cos(C) - D
。如何存储此类表达式?如果您也可以提出一种更好的调用此函数的方法,那就太好了。
我不知道它是否可以解决您的请求,但这可以为您提供帮助:
setClass(
Class = "MyExpr",
contains = "expression"
)
setValidity("MyExpr",
method = function(object) {
if (length(object) > 1) return("Only one line of code !!!")
if ("diff" %in% all.names(object[[1]])) return("I don't want any difference")
if ("a" %in% all.vars(object[[1]])) return("Variable a ???? It is forbidden !!!")
})
MyExpr <- function(x) new("MyExpr",parse(text=x))
MyExpr是一个S4类,包含一个具有某些待定义有效性的表达式。
MyExpr("1+1")
An object of class "MyExpr"
expression(1 + 1)
MyExpr("1+diff(1:10)")
Error in validObject(.Object) :
invalid class “MyExpr” object: I don't want any difference
MyExpr("1+a")
Variable a ???? It is forbidden !!!
MyExpr("sin(1+h)")
An object of class "MyExpr"
expression(sin(1 + h))
然后,您可以将表达式的树检索到字符中,就像它被提交给R一样,类似于
getTree_rec <- function(x) {
lapply(as.list(x),function(z) if (is.call(z)) getTree_rec(z) else as.character(z))
}
setGeneric("getTree", def = function(object) standardGeneric("getTree"))
setMethod(f="getTree",
signature="MyExpr",
definition = function(object) getTree_rec(object[[1]]))
getTree(MyExpr("sin(1+h)"))
[[1]]
[1] "sin"
[[2]]
[[2]][[1]]
[1] "+"
[[2]][[2]]
[1] "1"
[[2]][[3]]
[1] "h"
注意:您也可以放置z
而不是as.character(z)
。我之所以输入as.character(z),仅是因为您告诉过您想在文件中写一些东西,以供其他语言阅读。