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

时间:2013-04-15 15:58:58

标签: java r statistics chi-squared

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

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

我可以通过将两个矩阵读入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?

感谢您的帮助......

6 个答案:

答案 0 :(得分:12)

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

<小时/>

命令行&amp;脚本

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

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

chisq.test(obs, exp)

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

您可以将参数传递给Rscripts并使用commandArgs()函数或各种包(例如optparsegetopt)解析它们。请参阅this thread for more information

在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. Link to JRI
  2. Recommended Eclipse plugin to set up JRI

答案 1 :(得分:2)

查看此页面JRI

描述自己的网站:

  

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

答案 2 :(得分: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

您可以在here

中获取技术详情

答案 3 :(得分: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

答案 4 :(得分:0)

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

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

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

2&amp; 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's Statistics Lib&amp; How to calculate PValue from ChiSquare。也许你可以在没有R的情况下生活:)

答案 5 :(得分:0)

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

这不是一个完整的清单,而是我在5分钟内搜索到的。