2 |
26 Feb 07 |
jari |
1 |
package org.tigr.microarray.mev.r; |
2 |
26 Feb 07 |
jari |
2 |
|
2 |
26 Feb 07 |
jari |
3 |
import java.util.*; |
2 |
26 Feb 07 |
jari |
4 |
|
2 |
26 Feb 07 |
jari |
/** implementation of R-lists<br> |
2 |
26 Feb 07 |
jari |
This is rather preliminary and may change in future since it's not really proper. |
2 |
26 Feb 07 |
jari |
The point is that the parser tries to interpret lists to be of the form entry=value, |
2 |
26 Feb 07 |
jari |
where entry is stored in the "head" part, and value is stored in the "body" part. |
2 |
26 Feb 07 |
jari |
Then using {@link #at(String)} it is possible to fetch "body" for a specific "head". |
2 |
26 Feb 07 |
jari |
The terminology used is partly from hash fields - "keys" are the elements in "head" |
2 |
26 Feb 07 |
jari |
and values are in "body" (see {@link #keys}). |
2 |
26 Feb 07 |
jari |
<p> |
2 |
26 Feb 07 |
jari |
On the other hand, R uses lists to store complex internal structures, which are not |
2 |
26 Feb 07 |
jari |
parsed according to the structure - in that case "head" and "body" have to be evaluated |
2 |
26 Feb 07 |
jari |
separately according to their meaning in that context. |
2 |
26 Feb 07 |
jari |
16 |
|
2 |
26 Feb 07 |
jari |
@version $Id$ |
2 |
26 Feb 07 |
jari |
18 |
*/ |
2 |
26 Feb 07 |
jari |
19 |
public class RList extends Object { |
2 |
26 Feb 07 |
jari |
/** xpressions containing head and body. |
2 |
26 Feb 07 |
jari |
The terminology is a bit misleading - head corresponds to CAR, body to CDR and finally tag is TAG. */ |
2 |
26 Feb 07 |
jari |
22 |
public REXP head, body, tag; |
2 |
26 Feb 07 |
jari |
/** usual assumption is that both head and body are xpressions containing vectors. |
2 |
26 Feb 07 |
jari |
In such case the actual content objects (Vectors) are cached for key/value access. */ |
2 |
26 Feb 07 |
jari |
25 |
Vector h,b; |
2 |
26 Feb 07 |
jari |
26 |
|
2 |
26 Feb 07 |
jari |
/** constructs an empty list */ |
2 |
26 Feb 07 |
jari |
28 |
public RList() { head=body=tag=null; } |
2 |
26 Feb 07 |
jari |
29 |
|
2 |
26 Feb 07 |
jari |
/** constructs an initialized list |
2 |
26 Feb 07 |
jari |
@param h head xpression |
2 |
26 Feb 07 |
jari |
@param b body xpression */ |
2 |
26 Feb 07 |
jari |
33 |
public RList(REXP h, REXP b) { head=h; body=b; tag=null; } |
2 |
26 Feb 07 |
jari |
34 |
|
2 |
26 Feb 07 |
jari |
/** get head xpression (CAR) |
2 |
26 Feb 07 |
jari |
@return head xpression */ |
2 |
26 Feb 07 |
jari |
37 |
public REXP getHead() { return head; } |
2 |
26 Feb 07 |
jari |
38 |
|
2 |
26 Feb 07 |
jari |
/** get body xpression (CDR) |
2 |
26 Feb 07 |
jari |
@return body xpression */ |
2 |
26 Feb 07 |
jari |
41 |
public REXP getBody() { return body; } |
2 |
26 Feb 07 |
jari |
42 |
|
2 |
26 Feb 07 |
jari |
/** get tag xpression |
2 |
26 Feb 07 |
jari |
@return tag xpression */ |
2 |
26 Feb 07 |
jari |
45 |
public REXP getTag() { return tag; } |
2 |
26 Feb 07 |
jari |
46 |
|
2 |
26 Feb 07 |
jari |
/** internal function that updates cached vectors |
2 |
26 Feb 07 |
jari |
@return <code>true</code> if both expressions are vectors and of the same length */ |
2 |
26 Feb 07 |
jari |
49 |
boolean updateVec() { |
2 |
26 Feb 07 |
jari |
50 |
if (head==null||body==null|| |
2 |
26 Feb 07 |
jari |
51 |
head.Xt!=REXP.XT_VECTOR||body.Xt!=REXP.XT_VECTOR) |
2 |
26 Feb 07 |
jari |
52 |
return false; |
2 |
26 Feb 07 |
jari |
53 |
h=(Vector)head.cont; |
2 |
26 Feb 07 |
jari |
54 |
b=(Vector)body.cont; |
2 |
26 Feb 07 |
jari |
55 |
return (h.size()==b.size()); |
2 |
26 Feb 07 |
jari |
56 |
} |
2 |
26 Feb 07 |
jari |
57 |
|
2 |
26 Feb 07 |
jari |
/** get xpression given a key |
2 |
26 Feb 07 |
jari |
@param v key |
2 |
26 Feb 07 |
jari |
@return xpression which corresponds to the given key or |
2 |
26 Feb 07 |
jari |
<code>null</code> if list is not standartized or key not found */ |
2 |
26 Feb 07 |
jari |
62 |
public REXP at(String v) { |
2 |
26 Feb 07 |
jari |
63 |
if (!updateVec()) return null; |
2 |
26 Feb 07 |
jari |
64 |
for (int i=0;i<h.size();i++) { |
2 |
26 Feb 07 |
jari |
65 |
REXP r=(REXP)h.elementAt(i); |
2 |
26 Feb 07 |
jari |
66 |
if (r!=null && r.Xt==REXP.XT_STR && ((String)r.cont).compareTo(v)==0) |
2 |
26 Feb 07 |
jari |
67 |
return (REXP)b.elementAt(i); |
2 |
26 Feb 07 |
jari |
68 |
} |
2 |
26 Feb 07 |
jari |
69 |
return null; |
2 |
26 Feb 07 |
jari |
70 |
} |
2 |
26 Feb 07 |
jari |
71 |
|
2 |
26 Feb 07 |
jari |
/** get element at the specified position |
2 |
26 Feb 07 |
jari |
@param i index |
2 |
26 Feb 07 |
jari |
@return xpression at the index or <code>null</code> if list is not standartized or |
2 |
26 Feb 07 |
jari |
if index out of bounds */ |
2 |
26 Feb 07 |
jari |
76 |
public REXP at(int i) { |
2 |
26 Feb 07 |
jari |
77 |
if (!updateVec()) return null; |
2 |
26 Feb 07 |
jari |
78 |
return (i>=0 && i<b.size())?(REXP)b.elementAt(i):null; |
2 |
26 Feb 07 |
jari |
79 |
} |
2 |
26 Feb 07 |
jari |
80 |
|
2 |
26 Feb 07 |
jari |
/** returns all keys of the list |
2 |
26 Feb 07 |
jari |
@return array containing all keys or <code>null</code> if list is not standartized */ |
2 |
26 Feb 07 |
jari |
83 |
public String[] keys() { |
2 |
26 Feb 07 |
jari |
84 |
if (!updateVec()) return null; |
2 |
26 Feb 07 |
jari |
85 |
String[] k=new String[h.size()]; |
2 |
26 Feb 07 |
jari |
86 |
for(int i=0;i<h.size();i++) { |
2 |
26 Feb 07 |
jari |
87 |
REXP r=(REXP)h.elementAt(i); |
2 |
26 Feb 07 |
jari |
88 |
k[i]=(r==null||r.Xt!=REXP.XT_STR)?null:(String)r.cont; |
2 |
26 Feb 07 |
jari |
89 |
}; |
2 |
26 Feb 07 |
jari |
90 |
return k; |
2 |
26 Feb 07 |
jari |
91 |
} |
2 |
26 Feb 07 |
jari |
92 |
} |