Java调用R函数,返回值是数据框时的解析方法

来源:互联网 发布:abb机器人软件下载 编辑:程序博客网 时间:2024/06/02 07:05

当Java调用的R函数是多个返回值如何处理?

今天试着写一个函数,传参一组数字,同时返回均值,标准差和样本量,并将他们转成数据框返回;

在Java中,将返回值转为RList对象,可以通过索引位置或字段名获取对应的值;

        //创建连接        RConnection rConnection = new RConnection();        //加载源文件        rConnection.eval("source('D:/11_Java_R.R')");//文件名不能带中文,报错:eval failed, request status: error code: 127        String vector = "c(1,3,5,7,9)";        //测试调用R中多返回值函数        /*         * R文件中的函数:         * getMean_SD_N<-function(x){              data.frame(mean=mean(x),sd=sd(x),N=length(x))            }            返回值是一个数据框              mean   sd        N              5      3.162278  5         */        //调用,        REXP eval = rConnection.eval("getMean_SD_N("+vector+")");        //返回值是一个数据框样式,觉得Map格式合适,没有这个方法        //试着转为RList对象较为合适,看源码实现了java.util.List接口        //源码:public class RList extends Vector implements List {}        RList asList = eval.asList();        //找源码方法        //获取所有的key?        String string = Arrays.toString(asList.keys());//[mean, sd, N]        //根据索引位置获取key?        String keyAt2 = asList.keyAt(0);//mean        //根据索引位置获取RList第0个元素        REXP at = asList.at(0);//org.rosuda.REngine.REXPDouble@4a553f[1]        double asDouble = at.asDouble();//5.0        //根据key获取均值        REXP rexp_mean = asList.at("mean");        double mean = rexp_mean.asDouble();//5.0        //根据key获取标准差sd        double sd = asList.at("sd").asDouble();//3.16227766        //根据key获取样本量N        int num = asList.at("N").asInteger();//5

附RList类部分源码文档,含以上用到的几个方法

package org.rosuda.REngine;// REngine library - Java client interface to R// Copyright (C) 2004,2007,2008 Simon Urbanekimport java.util.*;/** implementation of R-lists<br>    All lists (dotted-pair lists, language lists, expressions and vectors) are regarded as named generic vectors.     Note: This implementation has changed radically in Rserve 0.5!    This class inofficially implements the Map interface. Unfortunately a conflict in the Java iterface classes Map and List doesn't allow us to implement both officially. Most prominently the Map 'remove' method had to be renamed to removeByKey.    @version $Id$*/public class RList extends Vector implements List {    public Vector names;    /** constructs an empty list */    public RList() { super(); names=null; }    /** constructs an initialized, unnamed list     * @param contents - an array of {@link REXP}s to use as contents of this list */    public RList(REXP[] contents) {    super(contents.length);    int i=0;    while (i<contents.length)        super.add(contents[i++]);    names=null;    }    public RList(int initSize, boolean hasNames) {    super(initSize);    names=null;    if (hasNames) names=new Vector(initSize);    }    /** constructs an initialized, unnamed list     * @param contents - a {@link Collection} of {@link REXP}s to use as contents of this list */    public RList(Collection contents) {    super(contents);    names=null;    }    /** constructs an initialized, named list. The length of the contents vector determines the length of the list.     * @param contents - an array of {@link REXP}s to use as contents of this list     * @param names - an array of {@link String}s to use as names */    public RList(REXP[] contents, String[] names) {    this(contents);    if (names!=null && names.length>0) {        this.names=new Vector(names.length);        int i = 0;        while (i < names.length) this.names.add(names[i++]);        while (this.names.size()<size()) this.names.add(null);    }    }    /** constructs an initialized, named list. The size of the contents collection determines the length of the list.     * @param contents - a {@link Collection} of {@link REXP}s to use as contents of this list     * @param names - an array of {@link String}s to use as names */    public RList(Collection contents, String[] names) {    this(contents);    if (names!=null && names.length>0) {        this.names=new Vector(names.length);        int i = 0;        while (i < names.length) this.names.add(names[i++]);        while (this.names.size()<size()) this.names.add(null);    }    }    /** constructs an initialized, named list. The size of the contents collection determines the length of the list.     * @param contents - a {@link Collection} of {@link REXP}s to use as contents of this list     * @param names - an {@link Collection} of {@link String}s to use as names */    public RList(Collection contents, Collection names) {    this(contents);    if (names!=null && names.size()>0) {        this.names=new Vector(names);        while (this.names.size()<size()) this.names.add(null);    }    }    /** checks whether this list is named or unnamed     * @return <code>true</code> if this list is named, <code>false</code> otherwise */    public boolean isNamed() {    return names!=null;    }    /** get xpression given a key    @param v key    @return value which corresponds to the given key or            <code>null</code> if the list is unnamed or key not found */    public REXP at(String v) {    if (names==null) return null;    int i = names.indexOf(v);    if (i < 0) return null;    return (REXP)elementAt(i);    }    /** get element at the specified position    @param i index    @return value at the index or <code>null</code> if the index is out of bounds */    public REXP at(int i) {    return (i>=0 && i<size())?(REXP)elementAt(i):null;    }    /** return the key (name) at a given index     @param i index     @return ket at the index - can be <code>null</code> is the list is unnamed or the index is out of range */    public String keyAt(int i) {    return (names==null || i<0 || i>=names.size())?null:(String)names.get(i);    }    /** set key at the given index. Using this method automatically makes the list a named one even if the key is <code>null</code>. Out of range operations are undefined (currently no-ops)     @param i index     @param value key name */    public void setKeyAt(int i, String value) {        if (i < 0) return;        if (names==null)            names = new Vector();        if (names.size() < size()) names.setSize(size());        if (i < size()) names.set(i, value);    }    /** returns all keys of the list     * @return array containing all keys or <code>null</code> if list unnamed */    public String[] keys() {    if (names==null) return null;    int i = 0;    String k[] = new String[names.size()];    while (i < k.length) { k[i] = keyAt(i); i++; };    return k;    }
阅读全文
0 0
原创粉丝点击