3

我在 JAVA 中有两个 4*4 矩阵,其中一个矩阵保存观察到的计数,另一个保存预期计数。

我需要一种自动方法来计算这两个矩阵之间的卡方统计量的 p 值;但是,据我所知,JAVA 没有这样的功能。

我可以通过将两个矩阵作为 .csv 文件格式读入 R 来计算卡方及其 p 值,然后使用 chisq.test 函数,如下所示:

obs<-read.csv("obs.csv")
exp<-read.csv("exp.csv")
chisq.test(obs,exp)

其中 .csv 文件的格式如下:

A, C, G, T
A, 197.136, 124.32, 63.492, 59.052
C, 124.32, 78.4, 40.04, 37.24
G, 63.492, 40.04, 20.449, 19.019
T, 59.052, 37.24, 19.019, 17.689

给定这些命令,R 将给出以下格式的输出:

X-squared = 20.6236, df = 9, p-value = 0.01443

其中包括我正在寻找的 p 值。

有谁知道自动化以下过程的有效方法:

1) 将我的矩阵从 JAVA 输出到 .csv 文件 2) 将 .csv 文件上传到 R 3) 将 .csv 文件上的 chisq.test 调用到 R 4) 将输出的 p 值返回到 JAVA?

谢谢你的帮助....

4

6 回答 6

12

有(至少)两种方法可以解决这个问题。


命令行和脚本

您可以使用Rscript.exe. 例如,在您的脚本中,您将拥有:

# Parse arguments.
# ...
# ...

chisq.test(obs, exp)

与其在 Java 中创建 CSV 并让 R 读取它们,不如将它们直接传递给 R。我认为不需要创建 CSV 并以这种方式传递数据,除非你的矩阵非常大。您可以传递的命令行参数的大小有限制(我认为因操作系统而异)。

您可以将参数传递到 Rscripts 并使用commandArgs()函数或各种包(例如optparsegetopt)解析它们。有关更多信息,请参阅此线程

在 Java 中有几种从命令行调用和读取的方法。我对此知之甚少,无法给你建议,但谷歌搜索会给你一个结果。从命令行调用脚本是这样完成的:

Rscript my_script.R

日本研究所

JRI 让您可以直接从 Java 与 R 对话。这是一个示例,说明如何将双精度数组传递给 R 并让 R 对其求和(现在是 Java):

// Start R session.
Rengine re = new Rengine (new String [] {"--vanilla"}, false, null);

// Check if the session is working.
if (!re.waitForR()) {
    return;
}

re.assign("x", new double[] {1.5, 2.5, 3.5});
REXP result = re.eval("(sum(x))");
System.out.println(result.asDouble());
re.end();

这里的功能assign()与在 R 中执行此操作相同:

x <- c(1.5, 2.5, 3.5)

您应该能够弄清楚如何扩展它以使用矩阵。


我认为JRI一开始是相当困难的。因此,如果您想快速完成此操作,命令行选项可能是最好的。我想说的是,一旦你设置了 JRI 方法,它就不会那么混乱了。而且,如果您遇到在 R 和 Java 之间来回频繁的情况,那肯定比调用多个脚本要好。

  1. 链接到 JRI
  2. 推荐 Eclipse 插件来设置 JRI
于 2013-04-15T16:32:41.183 回答
2

检查此页面JRI

描述形成他们的网站:

JRI 是一个 Java/R 接口,它允许在 Java 应用程序中作为单线程运行 R。基本上,它将 R 动态库加载到 Java 中,并为 R 功能提供 Java API。它支持对 R 函数的简单调用和完整运行的 REPL。

于 2013-04-15T16:02:00.633 回答
1

RCaller 2.2 可以做你想做的事。假设在您的问题中给出了频率矩阵。可以使用以下代码计算并返回结果 p.value 和 df 变量:

double[][] data = new double[][]{
        {197.136, 124.32, 63.492, 59.052},
        {124.32, 78.4, 40.04, 37.24},
        {63.492, 40.04, 20.449, 19.019},
        {59.052, 37.24, 19.019, 17.689}
        };
    RCaller caller = new RCaller();
    Globals.detect_current_rscript();
    caller.setRscriptExecutable(Globals.Rscript_current);
    RCode code = new RCode();

    code.addDoubleMatrix("mydata", data);
    code.addRCode("result <- chisq.test(mydata)");
    code.addRCode("mylist <- list(pval = result$p.value, df=result$parameter)");

    caller.setRCode(code);
    caller.runAndReturnResult("mylist");

    double pvalue = caller.getParser().getAsDoubleArray("pval")[0];
    double df = caller.getParser().getAsDoubleArray("df")[0];
    System.out.println("Pvalue is : "+pvalue);
    System.out.println("Df is : "+df);

输出是:

Pvalue is : 1.0
Df is : 9.0

你可以在这里获得技术细节

于 2014-04-14T11:02:52.450 回答
1

Rserve 是另一种将数据从 Java 获取到 R 并返回的方法。它是一个将 R 脚本作为字符串输入的服务器。您可以使用 Java 中的一些字符串解析和转换将矩阵转换为可以输入到 R 中的字符串。

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;


public class RtestScript {

private String emailTestScript = "open <- c('O', 'O', 'N', 'N', 'O', 'O', 'N', 'N', 'N', 'O', " +
        " 'O', 'N', 'N', 'O', 'O', 'N', 'N', 'N', 'O');" +
        "testgroup <- c('A', 'A', 'A','A','A','A','A','A','A','A', 'B'," +
        "'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B');" +
        "emailTest <- data.frame(open, testgroup);" +
        "emailTable<- table(emailTest$open, emailTest$testgroup);" +
        "emailResults<- prop.test(emailTable, correct=FALSE);" +
        "print(emailResults$p.value);";

public void executeRscript() {
    try {
        //Make sure to type in library(Rserve); Rserve() in Rstudio before running this
        RConnection testConnection = new RConnection();

        REXP testExpression = testConnection.eval(emailTestScript);
        System.out.println("P value: " + testExpression.asString());
    } catch(Exception e) {
        e.printStackTrace();
    }
}
}

这是有关 Rserve 的更多信息。顺便说一句,这也是 Tableau 与 R 以及它们的 R 连接进行通信的方式。

https://cran.r-project.org/web/packages/Rserve/index.html

于 2015-12-24T01:17:28.483 回答
0

我建议简单地使用一个为您进行 ChiSquare 测试的 Java 库。有足够的:

这不是一个完整的列表,而是我在 5 分钟的搜索中找到的。

于 2013-06-06T07:46:17.660 回答
0

1) 将我的矩阵从 JAVA 输出到 .csv 文件中

使用任何 CSV 库,我会推荐http://opencsv.sourceforge.net/

2) 将 .csv 文件上传到 R 3) 将 .csv 文件上的 chisq.test 调用到 R

2 & 3 几乎一样,你最好创建参数化脚本以在 R 中运行。

obs<-read.csv(args[1])
exp<-read.csv(args[2])
chisq.test(obs,exp)

所以你可以运行

RScript your_script.r path_to_csv1 path_to_csv2, 

并为 csv 文件使用唯一名称,例如:

UUID.randomUUID().toString().replace("-","")

然后你使用

Runtime.getRuntime().exec(command, environments, dataDir);

4) 将输出的 p 值返回到 JAVA?如果您使用 getRuntime().exec() 调用 R,则只能读取 R 的输出。

我还建议查看Apache 的 Statistics Lib & How to calculate PValue from ChiSquare。也许你可以完全没有 R :)

于 2013-06-06T06:41:50.690 回答