forked from s-u/REngine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RFactor.java
224 lines (197 loc) · 5.85 KB
/
RFactor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
package org.rosuda.REngine;
// REngine
// Copyright (C) 2007 Simon Urbanek
// --- for licensing information see LICENSE file in the original distribution ---
import java.util.*;
/** representation of a factor variable. In R there is no actual object
type called "factor", instead it is coded as an int vector with a list
attribute. The parser code of REXP converts such constructs directly into
the RFactor objects and defines an own XT_FACTOR type
@version $Id$
*/
public class RFactor {
int ids[];
String levels[];
int index_base;
/** create a new, empty factor var */
public RFactor() { ids=new int[0]; levels=new String[0]; }
/** create a new factor variable, based on the supplied arrays.
@param i array of IDs (inde_base..v.length+index_base-1)
@param v values - cotegory names
@param copy copy above vaules or just retain them
@param index_base index of the first level element (1 for R factors, cannot be negtive)
*/
public RFactor(int[] i, String[] v, boolean copy, int index_base) {
if (i==null) i = new int[0];
if (v==null) v = new String[0];
if (copy) {
ids=new int[i.length]; System.arraycopy(i,0,ids,0,i.length);
levels=new String[v.length]; System.arraycopy(v,0,levels,0,v.length);
} else {
ids=i; levels=v;
}
this.index_base = index_base;
}
/** create a new factor variable by factorizing a given string array. The levels will be created in the orer of appearance.
@param c contents
@param index_base base of the level index */
public RFactor(String c[], int index_base) {
this.index_base = index_base;
if (c == null) c = new String[0];
Vector lv = new Vector();
ids = new int[c.length];
int i = 0;
while (i < c.length) {
int ix = (c[i]==null)?-1:lv.indexOf(c[i]);
if (ix<0 && c[i]!=null) {
ix = lv.size();
lv.add(c[i]);
}
ids[i] = (ix<0)?REXPInteger.NA:(ix+index_base);
i++;
}
levels = new String[lv.size()];
i = 0;
while (i < levels.length) {
levels[i] = (String) lv.elementAt(i);
i++;
}
}
/** same as <code>RFactor(c, 1)</code> */
public RFactor(String c[]) {
this(c, 1);
}
/** same as <code>RFactor(i,v, true, 1)</code> */
public RFactor(int[] i, String[] v) {
this(i, v, true, 1);
}
/** returns the level of a given case
@param i case number
@return name. may throw exception if out of range */
public String at(int i) {
int li = ids[i] - index_base;
return (li<0||li>levels.length)?null:levels[li];
}
/** returns <code>true</code> if the data contain the given level index */
public boolean contains(int li) {
int i = 0;
while (i < ids.length) {
if (ids[i] == li) return true;
i++;
}
return false;
}
/** return <code>true</code> if the factor contains the given level (it is NOT the same as levelIndex==-1!) */
public boolean contains(String name) {
int li = levelIndex(name);
if (li<0) return false;
int i = 0;
while (i < ids.length) {
if (ids[i] == li) return true;
i++;
}
return false;
}
/** count the number of occurences of a given level index */
public int count(int levelIndex) {
int i = 0;
int ct = 0;
while (i < ids.length) {
if (ids[i] == levelIndex) ct++;
i++;
}
return ct;
}
/** count the number of occurences of a given level name */
public int count(String name) {
return count(levelIndex(name));
}
/** return an array with level counts. */
public int[] counts() {
int[] c = new int[levels.length];
int i = 0;
while (i < ids.length) {
final int li = ids[i] - index_base;
if (li>=0 && li<levels.length)
c[li]++;
i++;
}
return c;
}
/** return the index of a given level name or -1 if it doesn't exist */
public int levelIndex(String name) {
if (name==null) return -1;
int i = 0;
while (i < levels.length) {
if (levels[i]!=null && levels[i].equals(name)) return i + index_base;
i++;
}
return -1;
}
/** return the list of levels (0-based, use {@link #indexBase} correction if you want to access it by level index) */
public String[] levels() {
return levels;
}
/** return the contents as integer indices (with the index base of this factor) */
public int[] asIntegers() {
return ids;
}
/** return the contents as integer indices with a given index base */
public int[] asIntegers(int desired_index_base) {
if (desired_index_base == index_base) return ids;
int[] ix = new int[ids.length];
int j = 0; while (j < ids.length) { ix[j] = ids[j] - index_base + desired_index_base; j++; }
return ix;
}
/** return the level name for a given level index */
public String levelAtIndex(int li) {
li -= index_base;
return (li<0||li>levels.length)?null:levels[li];
}
/** return the level index for a given case */
public int indexAt(int i) {
return ids[i];
}
/** return the factor as an array of strings */
public String[] asStrings() {
String[] s = new String[ids.length];
int i = 0;
while (i < ids.length) {
s[i] = at(i);
i++;
}
return s;
}
/** return the base of the levels index */
public int indexBase() {
return index_base;
}
/** returns the number of cases */
public int size() { return ids.length; }
public String toString() {
return super.toString()+"["+ids.length+","+levels.length+",#"+index_base+"]";
}
/** displayable representation of the factor variable
public String toString() {
//return "{"+((val==null)?"<null>;":("levels="+val.size()+";"))+((id==null)?"<null>":("cases="+id.size()))+"}";
StringBuffer sb=new StringBuffer("{levels=(");
if (val==null)
sb.append("null");
else
for (int i=0;i<val.size();i++) {
sb.append((i>0)?",\"":"\"");
sb.append((String)val.elementAt(i));
sb.append("\"");
};
sb.append("),ids=(");
if (id==null)
sb.append("null");
else
for (int i=0;i<id.size();i++) {
if (i>0) sb.append(",");
sb.append((Integer)id.elementAt(i));
};
sb.append(")}");
return sb.toString();
} */
}