簡體   English   中英

從JAVA調用R得到卡方統計和p值

[英]Call R from JAVA to get Chi-squared statistic and p-value

我在JAVA中有兩個4 * 4矩陣,其中一個矩陣包含觀察計數和其他預期計數。

我需要一種自動的方法來計算這兩個矩陣之間的卡方統計量的p值; 但是,就我所知,JAVA沒有這樣的功能。

我可以通過將兩個矩陣讀成R作為.csv文件格式,然后使用chisq.test函數計算卡方和p值,如下所示:

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()函數或使用各種包(例如optparsegetopt )解析它們。 有關更多信息,請參閱此主題

在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中,並為R功能提供Java API。 它支持對R函數的簡單調用和完整運行的REPL。

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

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庫。 有足夠的:

這不是一個完整的列表,但我在5分鍾的搜索中找到了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM