从JAVA调用R以获得卡方统计和p值

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

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

我可以通过将两个矩阵读成R作为.csv文件格式来计算卡方和它的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?

谢谢你的帮助….

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


命令行和脚本

您可以使用Rscript.exe从命令行执行Rscript.exe 。 例如,在您的脚本中,您将拥有:

 # 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 <- c(1.5, 2.5, 3.5) 

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


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

  1. 链接到JRI 。
  2. 推荐的Eclipse插件来设置JRI 。

查看此页面JRI

描述自己的网站:

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

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

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

  • Apache公共数学: http : //commons.apache.org/proper/commons-math/
  • JSC: http : //www.jsc.nildram.co.uk/
  • JDistlib: http ://jdistlib.sourceforge.net/

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

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 

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

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

Interesting Posts