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

从JAVA调用R以获得卡方统计和p值,java,r,statistics,chi-squared,Java,R,Statistics,Chi Squared,我在JAVA中有两个4*4矩阵,其中一个矩阵包含观察到的计数,另一个包含预期计数 我需要一种自动化的方法来计算这两个矩阵之间的卡方统计的p值;然而,据我所知,JAVA没有这样的功能 我可以通过将两个矩阵读入R as.csv文件格式,然后使用chisq.test函数计算卡方及其p值,如下所示: obs<-read.csv("obs.csv") exp<-read.csv("exp.csv") chisq.test(obs,exp) A, C, G, T A, 197.136, 124

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

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

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

obs<-read.csv("obs.csv")
exp<-read.csv("exp.csv")
chisq.test(obs,exp)
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中

感谢您的帮助……

查看此页面

网站说明:

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

有(至少)两种方法可以做到这一点


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

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

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

您可以将参数传递到rscript中,并使用
commandArgs()
函数或各种包(例如或)对其进行解析。看

Java中有几种调用和读取命令行的方法。我对这方面的知识还不足以给你提供建议,但谷歌搜索一下会给你一个结果。从命令行调用脚本的操作如下:

Rscript my_script.R

JRI JRI允许您直接从Java与R对话。下面是一个示例,说明如何将一个双数组传递给R,并使R对其求和(现在是Java):

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

x <- c(1.5, 2.5, 3.5)
x1)将我的矩阵从JAVA输出到.csv文件

我建议你使用任何CSV图书馆

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

2和3 a基本相同, 您最好创建要在R中运行的参数化脚本

obs<-read.csv(args[1])
exp<-read.csv(args[2])
chisq.test(obs,exp)
并为csv文件使用唯一的名称,例如:

UUID.randomUUID().toString().replace("-","")
然后你用

Runtime.getRuntime().exec(command, environments, dataDir);
4) 将输出的p值返回到JAVA中? 如果使用getRuntime().exec()调用R,则只能读取R的输出


我还建议您看看&。也许你完全可以不使用R:)

我建议只使用一个Java库为你做一个ChiSquare测试。它们足够多了:

  • Apache commons数学:
  • JSC:
  • JDistlib:

这不是一个完整的列表,但我在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);

您可以在

中获得技术细节。Rserve是另一种将数据从Java传输到R和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();
    }
}
}
import org.rosuda.REngine.REXP;
导入org.rosuda.REngine.Rserve.r连接;
公共类RtestScript{

专用字符串emailTestScript="打开感谢链接。我正在将此代码提交给老师。这种方法是否意味着她需要下载一些东西到她的计算机上才能运行我的代码。如果是,是否有其他方法不强制执行此操作?再次感谢!!感谢链接。我正在将此代码提交给老师。这种方法是否意味着她需要下载一些东西g到她的计算机上运行我的代码。如果是这样的话,有没有其他方法可以不强制这样做?再次感谢!!我得到了错误:import org.rosuda.JRI.REXP无法解析,import org.rosuda.JRI.Rengine无法解析,Rengine无法解析为类型。知道是什么原因吗?再次感谢…我看到你已经打开了另一个问题关于这一点,我建议你使用我在回答(最后一个链接)中建议的插件。如果你在设置JRI时仍然有困难,它可以解决设置JRI的所有压力,这可能会非常困难。
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
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();
    }
}
}