从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之间有很多来回的情况,它肯定比调用多个脚本更好。
- 链接到JRI 。
- 推荐的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连接。