我在JAVA中有两个4 * 4矩阵,其中一个矩阵包含观察计数和其他预期计数。

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

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

obs

exp

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?

谢谢你的帮助....

谢谢你的链接。 我正在向老师提交此代码。 这种方法是否意味着她需要将某些内容下载到她的计算机上以运行我的代码。 如果是这样,是否有一种不会强迫它的替代方案? 再次感谢!!

有(至少)两种方式来解决这个问题。

命令行和脚本

您可以使用Rscript.exe从命令行执行Rscripts。例如。在你的脚本中你会有:

# Parse arguments.
# ...
# ...
chisq.test(obs, exp)

您应该能够直接将它们传递给R而不是用Java创建CSV并让R读取它们。我不认为需要创建CSV并以这种方式传递数据,除非您的矩阵非常大。您可以传递的命令行参数的大小存在限制(我认为操作系统不同)。

您可以将参数传递给Rscripts并使用commandArgs()函数或使用各种包(例如optparse或getopt)解析它们。请参阅本主题以获取更多信息。

在Java中有几种从命令行调用和读取的方法。我不太了解它给你的建议,但一些谷歌搜索将给你一个结果。从命令行调用脚本是这样的:

Rscript my_script.R

JRI

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

您应该能够找出如何扩展它以使用矩阵。

我认为JRI在开始时非常困难。因此,如果您希望快速完成此操作,命令行选项可能是最佳选择。我会说,一旦你设置它,JRI方法就不那么混乱了。如果你有在R和Java之间有很多来回的情况,它肯定比调用多个脚本更好。

链接到JRI。

推荐的Eclipse插件来设置JRI。

哇,这非常有帮助! 非常感谢您的解释!

我得到错误:导入org.rosuda.JRI.REXP无法解析,导入org.rosuda.JRI.Rengine无法解析,Rengine无法解析为一个类型。 什么可能导致这个? 再次感谢...

我看到你已经提出了另一个问题。 如果您仍然无法进行设置,我建议您使用我在答案(最后一个链接)中建议的插件。 它解决了设置JRI的所有压力,这可能会非常困难。

查看此页面JRI

描述自己的网站:

JRI is a Java/R Interface, which allows to run R inside Java
applications as a single thread. Basically it loads R dynamic library
into Java and provides a Java API to R functionality. It supports both
simple calls to R functions and a full running REPL.

谢谢你的链接。 我正在向老师提交此代码。 这种方法是否意味着她需要将某些内容下载到她的计算机上以运行我的代码。 如果是这样,是否有一种不会强迫它的替代方案? 再次感谢!!

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

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;
public class RtestScript {
private String emailTestScript ="open 
" 'O', 'N', 'N', 'O', 'O', 'N', 'N', 'N', 'O');" +
"testgroup 
"'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B');" +
"emailTest 
"emailTable
"emailResults
"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

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 
code.addRCode("mylist 
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

您可以在此处获取技术细节

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

Apache公共数学:http://commons.apache.org/proper/commons-math/

JSC:http://www.jsc.nildram.co.uk/

JDistlib:http://jdistlib.sourceforge.net/

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

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

使用任何CSV图书馆,我建议http://opencsv.sourceforge.net/

2)将.csv文件上传到R中

3)将.csv文件中的chisq.test调用到R中

2和3非常相似,

您最好创建参数化脚本以在R中运行。

obs
exp
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和如何从ChiSquare计算PValue。也许你可以在没有R的情况下生活:)