对没有yacas的R中符号的算术运算

时间:2015-07-20 12:36:23

标签: r math rstudio symbolic-math equations

我的方程式定义为f<-"x^2"g<-"y^2"。我想获得像z<-(x^2)*(y^2)这样的方程式z。
'class(f)','class(g)'和'class(z)'值对我来说无关紧要。
我试过这个:

> f<-"x^2"
> g<-"y^2"
> z<-f*g

我得到了:

Error in f * g : non-numeric argument to binary operator<br/>

我尝试将f<-expression(f)g<-expression(g)相乘而没有结果。


我也试过了:

> f<-function(x) x^2
> g<-function(y) y^2
> z<-function(x,y) f*g
> z<-parse(text=z)

我得到了:

Error in as.character(x) : 
  cannot coerce type 'closure' to vector of type 'character'

使用paste(z)代替parse(z)

> paste(z)
Error in paste(z) : 
  cannot coerce type 'closure' to vector of type 'character'

有没有办法用R中的方程式进行符号算术而不使用像yacas这样的重型软件?

2 个答案:

答案 0 :(得分:4)

您对符号和函数的使用非常混乱。如果你想使用&#34;件&#34;语言对象,你会使用更像

的东西
public ASTNode getASTNodeFromMarker(IMarker marker) {
    IResource res = marker.getResource();
    if (res.getType() == IResource.FILE) {
        IFile f = (IFile)res;
        ICompilationUnit cu = (ICompilationUnit)JavaCore.create(f);
        CompilationUnit astRoot = getAstRoot(cu);
        int start = marker.getAttribute(IMarker.CHAR_START, 0);
        int end = marker.getAttribute(IMarker.CHAR_END, 0);
        NodeFinder nf = new NodeFinder(astRoot, start, end-start);
        return nf.getCoveringNode();
    }
    return null;
}

private CompilationUnit getAstRoot(ITypeRoot typeRoot) {
    CompilationUnit root = SharedASTProvider.getAST(typeRoot, SharedASTProvider.WAIT_YES, null);
    if (root == null) {
        ASTParser astParser = ASTParser.newParser(AST.JLS8);
        astParser.setSource(typeRoot);
        astParser.setResolveBindings(true);
        astParser.setStatementsRecovery(true);
        astParser.setBindingsRecovery(true);
        root = (CompilationUnit)astParser.createAST(null);
    }
    return root;  // may return null if no source available for typeRoot
}

如果您只是想要某种形式的功能组合,请确保将变量视为函数

f <- quote(x^2)
g <- quote(y^2)
z <- quote(f*g)
do.call("substitute", list(z, list(f=f, g=g)))
# x^2 * y^2

但这些只是构建R语言元素的方法。将这些视为代数操作是不明智的。 R不会尝试简化或类似的事情。

答案 1 :(得分:2)

您可以尝试以下方法:

f <- expression(x^2)
g <- expression(y^2)
z <- expression(eval(f) * eval(g))
#> eval(z,list(x = 1, y = 2))
#[1] 4
#...and here's another test, just to be sure:
#> identical(eval(z, list(x = 17, y = 21)), 17^2 * 21^2)
#[1] TRUE

或者你可以使用rSymPy包:

library(rSymPy)
x <- Var("x")
y <- Var("y")
sympy("f = x**2")
sympy("g = y**2")
sympy("z = f * g")
#> sympy("z")
#[1] "x**2*y**2"
#> sympy("z.subs([(x,3),(y,2)])")
#[1] "36" 

这第二个建议可能不太有吸引力,因为直接使用Python可能更容易。